www.mikrocontroller.net

Forum: Compiler & IDEs Array und pointer


Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: FrankW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
int16_t fr[256]; //Mein Array
char pa = 0;         //Index



void wert_in_array_packen(int16_t aktuellerwert)
{
  int i;

  fr[pa] = aktuellerWert;
  pa++;

  if (pa == 256) 
  {
    for (i = 0; i < 256; i++)
      printf("fr[i]=%i", fr[i]);
    pa = 0;
  }
}


Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
printf("fr[i]=%i",*fr);

Autor: FrankW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.... 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.

}

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
if ( *pa == 256 ) 
   printf( "fr[i]=%i", fr[i] );

Autor: FrankW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> // Und wo das "i" fuer fr[i] herkommt, das können wir nur raten.
Ups - sorry. Da ist ja nur ein Text.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
int16_t fr[256]; //Mein Array
uint16_t index = 0;

int main(void)
{
  while(1){

    fr[index] = aktuellerWert;
    index++;
    if (index == 256){
      index = 0;                    // Nullsetzen fürs nächste Mal!
      for(n=0; n<256; n++){         // alle 256 Werte ausgeben:
        printf("fr[i]=%i\n",fr[n]); // immer nur 1 Wert aus dem
Array
      }
    }

  } // end of while(1)
}   // end of main

Wenn Du es mit Index kannst, dann versuche es mit Pointern!

Gruß, Stefan

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups peinlich .. hat ja Rufus schon alles mal geschrieben ...

Gruß, Stefan

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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++?

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups gleichzeitig abgesendet!

Danke Jörg, genau das wollte ich auch noch wissen.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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];

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> C++-Bücher setzen in der Regel C-Kenntnisse vorraus.

Um solche Bücher sollte man aber in der Regel einen Bogen machen.

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>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?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok danke :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.