Hallo Forum, ich hoffe die Frage ist jetzt nicht zu banal aber ich bin langsam aber sicher am verzweifeln. Kurz zur Erklärung: Ich möchte mir ein Array mit 256 Werten anlegen und dann im Hauptprogramm einmal pro Schleifendurchlauf einen Wert ins Array schreiben und dann wenn das Array voll ist, dieses mit printf ausgeben. Ich dachte mit das folgendermaßen: int16_t fr[256]; //Mein Array char *pa; //Der zeiger auf mein Array(Index) pa = fr; //Den zeiger beim 1.Element des Arrays beginnen lassen int main(void) { *pa = aktuellerWert; *pa++; if (pa==256) printf("fr[i]=%i",fr); } Leider schlägt es schon bei der Deklaration des Arrays fehl.Folgende Fehlermeldungen kommen: main.c:35: warning: type defaults to `int' in declaration of `pa' main.c:35: error: conflicting types for 'pa' main.c:34: error: previous declaration of 'pa' was here main.c:35: warning: initialization makes integer from pointer without a cast main.c:35: warning: data definition has no type or storage class main.c:290: error: invalid type argument of `unary *' main.c:291: error: invalid type argument of `unary *' main.c:292: warning: int format, pointer arg (arg 2) main.c:338: error: invalid type argument of `unary *' main.c:339: error: invalid type argument of `unary *' main.c:340: warning: int format, pointer arg (arg 2) Leider kann ich mit diese Meldungen nicht viel anfangen. Laut C und C++ Kursen deklariere ich mein Array richtig aber wieso will das AVRstudio (gcc) dieses nicht annehmen? Was mache ich falsch?
Was als erstes gleich mal auffällt : int16_t fr[256]; //Du machst Ein Array mit 16 INT Werten char *pa; //Der Zeiger soll aber auf "char" zeigen pa = fr; //Jetzt willst Du einen "char" Pointer auf "int16" zeigen lassen. Deshalb jammert der Compiler int16_t fr[256]; //Mein Array int16_t *pa; //Der zeiger auf mein Array(Index) pa = fr; //Den zeiger beim 1.Element des Arrays beginnen sollte gehen. Gruss FrankW
Du deklarierst ein int16-Array, möchtest aber mit einem char-Zeiger darauf zugreifen. Desweiteren ist pa ein Zeiger und kein Index, daher kannst Du den nicht mit einem konstanten Wert wie 256 vergleichen. Ansonsten ist Dein Code nicht gerade sinnvoll in main() aufgehoben, so, wie Du das formuliert hast, wird das exakt einmal aufgerufen. Alternative:
1 | int16_t fr[256]; //Mein Array |
2 | char pa = 0; //Index |
3 | |
4 | |
5 | |
6 | void wert_in_array_packen(int16_t aktuellerwert) |
7 | {
|
8 | int i; |
9 | |
10 | fr[pa] = aktuellerWert; |
11 | pa++; |
12 | |
13 | if (pa == 256) |
14 | {
|
15 | for (i = 0; i < 256; i++) |
16 | printf("fr[i]=%i", fr[i]); |
17 | pa = 0; |
18 | }
|
19 | }
|
Erst mal der hier:
>(pa==256)
Wie soll das denn gehen?
der grösstmögliche Wert von pa ist 255.
Du müsstest also abfragen if (pa==0)
Dann willst einen char-Pointer auf ein Int-Array zeigen lassen.
Entweder benutzt du pa als Index von 0 bis 255 oder deklarierst ihn als
int-pointer.
Vielleicht solltest du mal einen Blick in das Buch von Dennis und Brian
werfen, und dir das Kapitel über Pointer und Felder angucken. Ab der
2.Auflage ist die deutsche Version auch nicht mehr so wirr
geschrieben...
Ja das ist mir auch gerade so aufgefallen aber das war es nicht. Auch wenn beide gleich definiert sind meckert er rum. Habe nun die Zeile: pa=fr; rausgenommen und siehe da, es funktioniert. Aber wieso stört ihn das? Und wie soll ich nun sonst den Pointer am Anfang des Arrays starten lassen? Um die Werte dem Array zuzuführen mache ich es nun so: *pa=WERTaktuell; *pa++; if (*pa==256) printf("fr[i]=%i",fr); Nun kommt diese Fehlermeldung: main.c:291: warning: int format, pointer arg (arg 2) Aber das Array und der Pointer sind doch nun Integer, also warum ist das falsch?
.... und den Rest verstehe ich auch nicht int main(void) { *pa = aktuellerWert; *pa++; // Meinst Du nicht eher pa++ statt *pa++ ? // Du willst doch den Pointer erhöhen, // nicht den Wert, auf den der Pointer zeigt if (pa==256) printf("fr[i]=%i",fr); // Dass pa jemals 256 wird ist sehr sehr sehr unwahrscheinlich :-) // pa ist ein Pointer, der irgenwo in den Speicher deines RAM's // Zeigt. Mit sicherheit wird Dein Array nicht bei Speicherplatz // 0 anfangen. // Also - z.B. parallel Zähler mitlaufen lassen und den abfragen. // Und wo das "i" fuer fr[i] herkommt, das können wir nur raten. }
Beschaffe dir ein C-Buch oder C-Tutorial und lese es durch. Dir fehlen die Grundlagen der Sprache. Denk daran: Du hast nur eine gewisse Anzahl Fragen frei und hier verplemperst du einige davon. Später, wenn du die wirklich kniffeligen Fragen hast, antwortet dir keiner mehr.
1 | if ( *pa == 256 ) |
2 | printf( "fr[i]=%i", fr[i] ); |
> // Und wo das "i" fuer fr[i] herkommt, das können wir nur raten.
Ups - sorry. Da ist ja nur ein Text.
> if (*pa==256) printf("fr[i]=%i",fr); > > Nun kommt diese Fehlermeldung: > > main.c:291: warning: int format, pointer arg (arg 2) > > Aber das Array und der Pointer sind doch nun Integer, also warum > ist das falsch? Weder das Array noch der Pointer sind Integer. Das Array ist ein Array von Integer. Und der Pointer ist ein Pointer auf Integer. Im printf gibst du aber mit dem %i (warum eigentlich %i, tuts %d nicht auch?) an, dass die einen Integer übergibst. fr ist aber kein Integer, fr ist ein komplettes Array von Integern und das ist nun mal was anderes. Wie man ein Array ausgeben kann, hat Rufus weiter oben schon gezeigt.
> aber ich bin langsam aber sicher am verzweifeln
Das musst du nicht. Kauf dir ein Buch.
Der Klassiker von Kernighan & Ritchie ist immer noch eines
der Standardlehrbücher über C.
Eine Programmiersprache ohne ausreichende Unterlagen lernen
zu wollen ist so wie wenn ich ohne entsprechende Unterlagen
und Schulung den Leitstand eines Kernkraftwerkes übernehmen
sollte. Erst recht dann, wenn ich neben der neuen Programmier-
sprache auch noch gleichzeitig das Programmieren an sich lernen
muss.
Warum muss es unbedingt ein Pointer sein? So wie es aussieht, kennst Du Dich mit denen noch nicht so gut aus. Nimm einen Index-Zähler, das ist für den Anfang einfacher zu durchschauen:
1 | int16_t fr[256]; //Mein Array |
2 | uint16_t index = 0; |
3 | |
4 | int main(void) |
5 | {
|
6 | while(1){ |
7 | |
8 | fr[index] = aktuellerWert; |
9 | index++; |
10 | if (index == 256){ |
11 | index = 0; // Nullsetzen fürs nächste Mal! |
12 | for(n=0; n<256; n++){ // alle 256 Werte ausgeben: |
13 | printf("fr[i]=%i\n",fr[n]); // immer nur 1 Wert aus dem |
14 | Array
|
15 | }
|
16 | }
|
17 | |
18 | } // end of while(1) |
19 | } // end of main |
Wenn Du es mit Index kannst, dann versuche es mit Pointern! Gruß, Stefan
Tja ich weiß gar nicht wo ich anfangen soll. Also ich weiß selbst das mir die C-Grundlagen fehlen, aber ich versuche ja auch gerade diese mir anzueignen. Im Moment bin ich halt dabei Arrays und Pointer zu üben. Ich habe zwar kein C-Buch aber dafür nutze ich sämtliche Online Kurse die ich gefunden habe um zu üben. Das mit dem pa==256 war ein Schussligkeitsfehler...den hätte ich später bestimmt auch selbst noch gefunden aber danke für den Hinweis. >>Ansonsten ist Dein Code nicht gerade sinnvoll in main() aufgehoben, so, wie Du das formuliert hast, wird das exakt einmal aufgerufen. Ja das ist mir auch klar, das war nur so als Beispiel angedacht wie ich das dann halt in der for-Schleife for(;;) machen wollte. Sollte nicht einfach so in der main stehen, sondern halt im for(;;){}. Eins habt ihr mir aber noch nicht erklärt: >>Habe nun die Zeile: pa=fr; rausgenommen und siehe da, es funktioniert. Aber wieso stört ihn das? Und wie soll ich nun sonst den Pointer am Anfang des Arrays starten lassen? Kann mir das noch einer erklären? Ich danke auf jeden Fall allen die mir gerade geholfen haben...ein Sorry an alle, die das lesen des Beitrages genervt hat aber ich schrieb ja am Anfang, dass es warhscheinlich ein sehr banales Thema ist.
> Ich habe zwar kein C-Buch aber dafür nutze ich > sämtliche Online Kurse die ich gefunden habe um zu üben. Vergiss die Online Kurse. Die Online Kurse kommen selten über 20 Seiten hinaus. Selbst das lausigste C-Buch hat aber über 100 Seiten. Und jetzt frag dich mal warum. > Eins habt ihr mir aber noch nicht erklärt: > >>Habe nun die Zeile: > pa=fr; > rausgenommen und siehe da, es funktioniert. Aber wieso stört ihn > das? Doch das wurde schon erklärt: fr ist ein Array von int ! pa hast du aber als Pointer auf char definiert. Das heist also wenn du einen gültigen Pointer Wert in pa stehen hast, dann führt dich dieser Pointer Wert bei der Dereferenzierung zu einem char. Daher kann die Zuweisung nicht gehen, denn wie gesagt, fr ist ja ein Array von int: char != int
Noch was:
> siehe da, es funktioniert
Der Compiler akzeptiert es. Das heist aber noch lange nicht
das es funktioniert. Der Compiler überprüft nur, ob dein
Programm den Schreibregeln (der sog. Syntax) der Programmier-
sprache entspricht. Ob dein Programm logisch richtig ist,
kümmert ihn einen Pfurz.
Das ist so, wie wenn ich sage, dass in der deutschen Sprache
für einen Satz gilt:
Subjekt Verb Objekt
Das heist der Satz:
Die Feuerwehr löscht den Brand
ist ein gültiger deutscher Satz. Aber
Die Feuerwehr weht das Kino
ist auch ein deutscher Satz. Er entspricht genauso obiger Regel.
Nur macht er halt keinen Sinn.
Weil's noch keiner geschrieben hat (glaub' ich), int16_t fr[256]; char *pa; pa = fr; Das steht vor deinem main() und damit außerhalb jeglicher Funktion. Dort sind aber nur Deklarationen und Definitionen zugelassen, keine Zuweisungen. Was (mit Warnungen, wegen der Typinkompatibilität) geht ist: int16_t fr[256]; char *pa = fr; Damit ändert sich die Zuweisung in eine Intialisierung.
Aha und wie sagt man stattdessen, dass der Pointer auf das 1. Element des Arrays zeigt und nicht irgendwo in den Speicher? Auf jeden Fall ist die Sache mit dem Index für mich erstmal sehr interessant. Das habe ich auch sofort verstanden, denn so dachte ich mir das auch mit dem Pointer. Naja ich werde mir jetzt mal nen C-Buch besorgen gehen. Was ist denn Sinnvoller? Das empfohlene von Kernighan & Ritchie für C oder eines für C++?
Ups gleichzeitig abgesendet! Danke Jörg, genau das wollte ich auch noch wissen.
C und C++ sind verschiedene Sprachen. Du willst C lernen, ergo ... > Aha und wie sagt man stattdessen, dass der Pointer auf das 1. > Element des Arrays zeigt und nicht irgendwo in den Speicher? Das tust du automatisch bei der Zuweisung der Adresse. Wenn ein Array ohne einen Indexausdruck verwendet wird, dann ist das in den meisten Fällen gleichbedeutend mit der Adresse des ersten Arrayelementes im Speicher: int fr[100]; int* pa = &fr; Hier ist pa ein Zeiger auf int. fr ist ein Array von int. Also passt das auch zusammen.
C++-Bücher setzen in der Regel C-Kenntnisse vorraus. Falls Du es immer noch nicht verstanden haben solltest: pa ist ein Pointer auf eine Variable von type char. Dein Array ist aber ein int-Feld. Das verträgt sich nicht. so solltes es funktionieren: int *pa; int fr[256]; pa = fr; jetzt kann man die einzelnen Feldeinträge mit pa++ "adressieren" und mit *pa ausgeben.
Da hat bei mir der Tippfehlerteufel zugeschlagen: > int fr[100]; > int* pa = &fr; muss heissen: int fr[100]; int* pa = fr; oder aber, weil gleichbedeutend: int fr[100]; int* pa = & fr[0];
> C++-Bücher setzen in der Regel C-Kenntnisse vorraus.
Um solche Bücher sollte man aber in der Regel einen Bogen machen.
>>int fr[100]; >>int* pa = fr; >>oder aber, weil gleichbedeutend: >>int fr[100]; >>int* pa = & fr[0]; Tja auf die Idee, dem Pointer gleich bei der Initialiserung die Adresse zuzuweisen bin ich noch nicht gekommen. Das war ja das Problem was Jörg schon erklärt hat. Mit den Büchern bin ich jetzt allerdings etwas verwirrt. Wenn ich den GCC nutze programiere ich doch in C++ oder? Welches sollte ich mir denn nun aneigenen?
Der gcc ist ein 'Kombi-Compiler'. Der kann C und C++ kompilieren (*). Das hat historische Ursachen, da sich C++ aus C entwickelt hat. Wird der gcc im C++ Modus benutzt, dann heist er meist g++ Das heist: Ob du C oder C++ kompilierst hängt davon ab, welche Parameter beim Aufruf mitgegeben werden. Aber meistens ist es auf einem µC C. (*) so war das mal. Mittlerweile hat sich das weiterentwickelt. Unter gcc versteht man heutzutage eigentlich einen Compiler, der durch Austausch von Modulen im Compiler eine ganze Reihe von Sprachen übersetzen kann.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.