Forum: Compiler & IDEs Array mit [0]?


von Tobias M. (obi)


Lesenswert?

Hi!
Ich bin µC- Anfänger (AVR) und mich beschäftigt eine Frage:
Ich habe mit etwas rumprobieren und testen jetzt endlich einen 
funktionsfähigen Code hinbekommen (aus Codeschnipseln von verschiedenen 
Quellen) und probiere jetzt zu verstehen, wie das ganze so funktioniert 
(ist für mich die beste Lernmethode um Code zu verstehen, finde ich).
Okay,hier mal ein paar Auszüge:
1
//Definition von Variablen
2
float    Temp_celsius;   // konvertierte Temperatur in °C
3
char     temp_ascii[0];  // ASCII vom Temperatur-Wert
4
uint16_t Temperature;    // Temperatur vom Sensor
5
6
// ...
7
// Auslesen des Temperatur-Sensors
8
// ...
9
10
//Verrechnung und Ausgabe auf LCD
11
Temp_celsius = ((float)Temperature / 2047 * 200) - 50;
12
dtostrf(Temp_celsius, 5, 1,temp_ascii);
13
lcd_string("Temperatur:", 0, 0);
14
lcd_string(temp_ascii, 1, 0);
15
16
// lcd_string ist eine eigene Funktion, hier ist die Definition:
17
// void lcd_string(char *data, unsigned char x, unsigned char y)

Ich habe zum Testen die Array- Größe von temp_ascii immer weiter 
Richtung 0 verkleinert, um zu sehen, was passiert. Dabei ist 
herausbekommen, dass das Programm immernoch mit [0] funktioniert, aber 
nicht mit nur
1
char temp_ascii;
Ich glaube ich werde die Themen Arrays und Zeiger nie verstehen aber 
vielleicht wagt mal jemand von euch den Versuch, mir das Thema näher zu 
bringen und/oder mich Aufzuschlauen, warum der Code mit [0] immer noch 
funktioniert. (Habe auch schon Tutorials durchgearbeitet aber die Themen 
irgendwie noch nicht verstanden)

Danke schonmal und Gruß
Tobias

von the_mo (Gast)


Lesenswert?

Huhu Tobias,

irgendein_tolles_array[0] <- 0 ist der Index wenn mich nicht alles 
täuscht(C noob).
Dh. das gibt nur an welcher eintrag im array ausgewählt ist.
Ein Array kannste dir so vorstellen:
array -> wert 0
         wert 1
         wert 2
         etc...

d.h. du hast nur den wert im ersten Eintrag des Arrays geschrieben. 
Dieser verhält sich wie eine Variable.
Wie du jetzt genau die Stringlängebegrenzt, keine Ahnung. Ich hoffe das 
Hilft dir!

schönen abend

Mo

von LM13700 (Gast)


Lesenswert?

Egal wie gross das Array ist: Wenn Du einfach nur 'temp_ascii' 
schreibst, macht der C-Compiler daraus die Adresse (=Zeiger) Deines 
Arrays. Das Ganze funktioniert deswegen, weil der Speicher für die 
Ausgabe zwar nicht reicht aber dennoch existiert. Bei einer Arraygröße 
von 0 könnten praktisch die Variablen 'temp_ascii' und 'Temperature' an 
der gleichen Adresse im Speicher zu liegen kommen. Daher würde der Wert 
von 'Temperature' zerstört. Wie das konkret aussieht, hängt aber vom 
verwendeten Compiler ab.

Wenn Du kein Array, sondern nur einen 'char' erzeugst, übergibt C 
wirklich den Wert, der in der Variable gespeichert ist. Letztlich 
bekommst Du beim Übersetzen einen Fehler. Wenn Du aber mit Hilfe des 
Adressoperators absichtlich die Adresse der Variable übergibst (also 
&temp_ascii), kannst Du Deine Experimente wieder fortsetzen :-)

von Hc Z. (mizch)


Lesenswert?

@the_mo: Das hilft nicht,denn es stimmt nicht.

Die Null befindet sich in der Variablendefintion, ist also die 
Arraygröße und kein Index.  Es funktioniert, weil der Compiler beim 
Beschreiben eines Arrays die Einhaltung der Arraygrenzen nicht 
überprüft.  Der Inhalt überschreibt dann andere Variablen, die dahinter 
kommen, oder (mit Glück) landet er im unbenutzten Teil des Rams.  Es ist 
also Zufall, wenn das Programm trotzdem läuft und daraus lässt sich 
nichts ableiten (außer dass man Glück hatte).

Eine Arraygröße von 0 ist übrigens eine gcc-spezifische Erweiterung, die 
nur für ein paar Extrafälle sinnvoll ist.  Aber das war sicher hier 
nicht gefragt.

von Christoph (Gast)


Lesenswert?

dtostrf() möchte als letztes Argument einen Pointer haben, deswegen 
mault der Compiler wenn Du einfach einen char übergibst. Bei einem 
char-Array wird quasi automatisch ein Pointer auf das erste 
Array-Element übergeben wenn man nur den Array-Namen ohne Index 
hinschreibt.

Im übrigen wird der Code nicht wirklich funktionieren, auch wenn er 
vielleicht ohne Fehler kompiliert: Dadurch das dein Puffer jetzt zu 
klein ist produziert der Aufruf von dtostrf() einen Buffer Overflow. 
Sieh dir am besten mal in der Library Reference an was dtostrf() genau 
macht, dann sollte klar werden warum.

von Ungast (Gast)


Lesenswert?

Nur so nebenbei:
> Temperature / 2047
ist vermutlich falsch,
müsste Temperature / 2048
sein, sofern das eine A/D-Umrechnung und kein Kalibrierungsfaktor ist.
Dein ADC hat vermutlich 11 Bit Auflösung, und nicht nur 10,99.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>> Temperature / 2047
> ist vermutlich falsch, müsste Temperature / 2048 sein
Das ist ein gern gemachter Fehler, der sogar von etlichen Herstellern in 
AppNotes begangen wird. Und auch hier im Forum ein Dauerbrenner. Such 
mal nach +1023 +1024 +wandler
Beitrag "Float-Berechnung auf 8051 mit SDCC"
Beitrag "Umrechnen von analog to digital"

von Karl H. (kbuchegg)


Lesenswert?

Tobias M. schrieb:

> Ich habe mit etwas rumprobieren und testen jetzt endlich einen
> funktionsfähigen Code hinbekommen (aus Codeschnipseln von verschiedenen
> Quellen) und probiere jetzt zu verstehen, wie das ganze so funktioniert
> (ist für mich die beste Lernmethode um Code zu verstehen, finde ich).

Wenn du über einen gewissen Grundstock an Wissen verfügst, ist es gar 
nicht so schlecht anderer Leute Code zu studieren und bei Fragen seine 
Literatursammlung zu konsultieren.
Bis du aber diesen Grundstock hast, ist es die schlechtest mögliche 
Methode. Du wirst immer auf Halbwissen sitzenbleiben (wenn überhaupt) 
und die Grundlagen der Sprache nicht in einer systematischen Art und 
Weise erlernen, sondern chaotisch und dann auch nur halb.

Und zu guter letzt hast du das Problen, dass man programmieren nur 
lernt, wenn man möglichst viele Programme selber schreibt. Es gibt viele 
kleine Fallen in den Schreibweisen und in die MUSS man hineinfallen, 
damit man sie sich merkt. Klaust da immer nur Code von anderen, dann 
schreibst du nicht selber und machst daher auch nicht diese Fehler.

> Ich habe zum Testen die Array- Größe von temp_ascii immer weiter
> Richtung 0 verkleinert, um zu sehen, was passiert. Dabei ist
> herausbekommen, dass das Programm immernoch mit [0] funktioniert,

Ohne Fehler zu compilieren beduetet nicht dass das Programm auch 
funktioniert. Den Compiler interessiert nur, ob deine Grammatik stimmt. 
Ob die Logik stimmt, das ist dein Bier.

   "Er verschrottete den Apfel mit der Kamera."

ist ein deutscher Satz, der den deutschen Sprachregeln genügt. Obowhl er 
grammatikalisch richtig ist, ist es dennoch ein sinnloser Satz.

> bringen und/oder mich Aufzuschlauen, warum der Code mit [0] immer noch
> funktioniert.

Er funktioniert nicht.
Er scheint nur zu funktionieren.

von Tobias M. (obi)


Lesenswert?

Hallo liebe Programmierfreunde ;-)
Vielen Dank für eure Antworten!

@ Christoph:
>Im übrigen wird der Code nicht wirklich funktionieren, auch wenn er
>vielleicht ohne Fehler kompiliert

Doch, der Code funktioniert so, wie er soll. Habe das Programm auf den 
AVR übertragen und es wird die richtige Temperatur auf dem Display 
angezeigt. Sie ändert sich auch, wenn man den Sensor z.B. anfasst. Aber 
ich werde mir die Funktion auch nochmal ansehen.

@ Ungast:
>> Temperature / 2047
>ist vermutlich falsch,müsste Temperature / 2048 sein

Die Formel habe ich aus dem Datenblatt vom Hersteller, ich werde mir 
aber auch nochmal die Verweise von Lothar ansehen.

@ Karl Heinz:
Ich verfüge über einen gewissen Grundstock, da wir in der Firma auch mal 
etwas C programmiert haben und ich habe schon so manches Tutorial 
überlesen.
Ich versuche mich immer wieder vor neue Aufgaben zu stellen und diese 
dann im Programm zu lösen. Teils mit eigenem Wissen, der andere Teil 
sind dann Codeschnipsel.

>Er funktioniert nicht.
>Er scheint nur zu funktionieren.

Wie meinst du das? Wie ich vorher schon geschrieben habe funktioniert 
der Code und die Temperatur wird richtig angezeigt.

@All:
Wenn ich das jetzt richtig verstanden habe:
es muss
1
char     temp_ascii[6];
heißen??

Danke und Gruß
Tobias

von Stefan E. (sternst)


Lesenswert?

Tobias M. schrieb:

>>Er funktioniert nicht.
>>Er scheint nur zu funktionieren.
>
> Wie meinst du das? Wie ich vorher schon geschrieben habe funktioniert
> der Code und die Temperatur wird richtig angezeigt.

Das "Funktionieren" ist dann aber eher Zufall, und nicht das zwingende 
Resultat der Programmierung. Nur um es noch mal ganz klar zu sagen: wenn 
du ein Array a[0] definierst, und dann in das Array etwas schreibst, 
dann schreibst du auf jeden Fall irgendwo hin, wo du eigentlich nicht 
hinschreiben darfst. Natürlich kann man Glück haben (wie in deinem 
Fall), und man erwischt nichts "lebenswichtiges". Es ist z.B. möglich, 
dass das Array die letzte Variable im Speicher ist, dann gehen die 
illegalen Zugriffe einfach in den unbenutzten Bereich hinter den 
Variablen. Das ist eines der möglichen Szenarios, warum das fehlerhafte 
Programm zu funktionieren scheint.

von Karl H. (kbuchegg)


Lesenswert?

Tobias M. schrieb:

>>Er funktioniert nicht.
>>Er scheint nur zu funktionieren.
>
> Wie meinst du das? Wie ich vorher schon geschrieben habe funktioniert
> der Code und die Temperatur wird richtig angezeigt.

Ab und zu liest man auch in der Zeitung, dass Menschen einen Sturz aus 
dem 5. Stock überlebt haben.
'Funktioniert' deshalb das Springen aus dem 5. Stock? Würdest du das zb. 
Feuerwehrmännern empfehlen?

Du hattest Glück. Oder besser ausgedrückt: Du hattest das Pech, dass 
dein Programm zu funktionieren schien und du mit deiner Harakiriaktion 
nichts Lebenswichtiges erwischt hast. Wenn du Glück gehabt hättest, wäre 
das Programm abgeschmiert und du hättest gewusst, dass es noch 
mindestens einen Fehler gibt. So aber wähnst du dich in trügerischer 
Sicherheit die keine ist.

von Karl H. (kbuchegg)


Lesenswert?

Tobias M. schrieb:

> Ich verfüge über einen gewissen Grundstock, da wir in der Firma auch mal
> etwas C programmiert haben und ich habe schon so manches Tutorial
> überlesen.

Lesen alleine ist zuwenig.
Das ist wie Fahradfahren. Du kannst darüber lesen soviel du willst (und 
das ist im Falle von Programmieren auch wichtig, dass man das tut). Aber 
lernen wirst du es erst, wenn du es machst, sprich wenn du die Tutorien 
durcharbeitest.

> Ich versuche mich immer wieder vor neue Aufgaben zu stellen und diese
> dann im Programm zu lösen. Teils mit eigenem Wissen, der andere Teil
> sind dann Codeschnipsel.

Das ist ok.
Aber das eine hat keine Berechtigung ohne das andere.
Lesen ist zuwenig. Anderen Code studieren ist zuwenig. Erst die 
Kombination machts.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.