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
floatTemp_celsius;// konvertierte Temperatur in °C
3
chartemp_ascii[0];// ASCII vom Temperatur-Wert
4
uint16_tTemperature;// 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:
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
chartemp_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
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
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 :-)
@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.
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.
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.
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.
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
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.
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.
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.