Zeiger auf ein Struct-Array-Element übergeben

Gast #2916831
Lesenswert?

Guten Abend zusammen.

Ich habe mal eine kleine Frage bezüglich "Zeiger auf ein 
Struct-Array-Element".
1
typedef struct {
2
  char nachricht[max_nachrichtenlaenge];
3
  uint8_t empfaenger_nr[max_teilnehmer];
4
  } MELDUNG;
5

6
MELDUNG a[5];
7
MELDUNG b[5];
8
MELDUNG c[5];

anschließend übergebe ich ein struct vom Typ MELDUNG an eine Funktion 
(diese ist auf das Nötigste reduziert).
1
int create(MELDUNG* event){
2
  uint8_t i = 0;
3
  uint8_t zeile = 0;
4
  uint8_t empfaenger_id;
5
  
6
  while (strcmp(*event[i].nachricht,"") != 0){
7
    strcpy(sendeliste[zeile].nachricht, *event[i].nachricht); //Funktioniert
8
    empfaenger_id = *event[i].empfaenger_nr[i]; //Funktioniert nicht -> invalid type of unaray '*'(have 'int')
9
    i++;
10
  }
11

12
return 1;
13
}

Wieso kann ich nicht auf das Element im empfaenger_nr Array zugreifen? 
empfaenger_id habe ich auch schon als typ int probiert. Ebenfalls 
erfolglos.

Bin für jeden Tip dankbar.

Gruß
Jannik
Gast #2916850
Lesenswert?

Danke.
Ich habe einen Verdacht, jedoch verstehe ich es noch nicht ganz.
D.h. also ich mache auch *event[i], event[i]? Der Compiler akzeptiert 
das.

Aber wieso funktioniert es bei *event[i].nachricht ? Kann mir das 
nochmal wer näher erläutern?
Gast #2916883
Lesenswert?

Bist Du Dir sicher, dass das funktioniert und keine Warnung gibt?
1
strcpy(sendeliste[zeile].nachricht, *event[i].nachricht); //Funktioniert

strcpy möchte ja einen Zeiger, und event[i].nachricht zeigt auf das 
erste Element im Array. Wenn Du es noch derefenzierst, ist es kein 
Zeiger mehr.
Persönliche Seite #2917110
Lesenswert?

Andreas W. schrieb:

> weil die Array Variable "nachricht" ein  Pointer ist.

Nein.  Ein Array ist ein Array und ein Pointer ist ein Pointer.

Nur weil sie in der Verwendung teilweise ähnlich sind, sind Arrays noch 
lange keine Pointer — ausser bei Funktionsparametern, wo es tatsächlich 
das "Array decays to Pointer" gibt.

Bei Zeigern, int und double gilt ja auch: Nur weil man sie subtrahieren 
kann, vergleichen kann oder einen int draufaddieren kann, sind Zeiger, 
int und double noch lange nicht das selbe.
#2918467
Lesenswert?

Andreas W. schrieb:

> Der Name eines Arrays kann als Pointer auf sein erstes Element benutzt
> werden.

Besser. Viel besser.

Das Problem mit deiner Aussage ist, dass die Kenner zwar wissen was du 
meinst, aber Anfänger ganz gerne die Aussage missverstehen.

So, so. Der Arrayname ist ein Pointer. Warum geht dann das nicht

FileA.C
1
int Werte[20];

FileB.C
1
extern int *Werte;
2

3
void foo()
4
{
5
  Werte[5] = 26;
6
}

wo doch ein Array ein Pointer ist?
Gast #2919057
Lesenswert?

Johann L. schrieb:
> Nur weil sie in der Verwendung teilweise ähnlich sind, sind Arrays noch
> lange keine Pointer — ausser bei Funktionsparametern, wo es tatsächlich
> das "Array decays to Pointer" gibt.

Eigentlich gibt es das nicht nur dort, sondern fast überall. Auch z.B. 
der Dereferenzierungs-Operator kann ja auf Arrays angewendet werden. 
Selbst die Index-Operation x[n] ist auch nur definiert als äquivalent zu 
*(x+n).
Aber leider ist eben trotzdem nur fast überall, und die Unterscheidung 
ist sehr wichtig.

Karl Heinz Buchegger schrieb:
> So, so. Der Arrayname ist ein Pointer. Warum geht dann das nicht

Naja, der Klassiker ist doch eher sowas wie:
1
void funktion(char arr[])
2
{
3
    for (size_t i = 0; i < sizeof arr; i++)
4
    {
5
        putchar(arr[i]);
6
    }
7
}

mit einer Frage wie: "Warum werden hier nur die ersten vier Zeichen 
ausgegeben?"
#2919062
Lesenswert?

Rolf Magnus schrieb:

> Naja, der Klassiker ist doch eher sowas wie:

:-)
Diese Syntax kannte ich damals noch nicht, als ich für mich die 
Unterscheidung Array-Pointer entdeckte und mir einen Reim darauf machen 
musste. Das globale Array/Pointer Beispiel hat mir dann die Augen 
geöffnet, als ich dann endlich verstanden hatte, was ich im K&R 
misverstanden habe.

Drum bringe ich es ganz gerne.
Moderator #2919098
Lesenswert?

Wenn man mit dem Extern/Pointer/Array-Beispiel von Karl Heinz auf die
Nase gefallen ist, lernt man dann meistens auch, warum alles Gobale in
Header-Files deklariert gehört und diese insbesondere auch dort
inkludiert werden sollten, wo die Definitionen der entsprechenden
Variablen bzw. Funktionen stehen. Dann wird man vom Compiler nämlich
durch ein "error: conflicting types" auf den Fehler hingewiesen.

Neben den Extern-Deklarationen und dem Sizeof-Operator ist die
Unterscheidung zwischen Array und Pointer bei der Behandlung von Arrays
von Arrays (im Volksmund auch mehrdimensionale Arrays genannt) von
Bedeutung. Da stößt man dann plötzlich auf so seltsame Dinge wie Pointer
auf Arrays. Auch zu diesem Aspekt gab es hier im Forum schon genügend
Verwirrung.
Gast #2919136
Lesenswert?

Yalu X. schrieb:
> Neben den Extern-Deklarationen und dem Sizeof-Operator ist die
> Unterscheidung zwischen Array und Pointer bei der Behandlung von Arrays
> von Arrays (im Volksmund auch mehrdimensionale Arrays genannt) von
> Bedeutung. Da stößt man dann plötzlich auf so seltsame Dinge wie Pointer
> auf Arrays. Auch zu diesem Aspekt gab es hier im Forum schon genügend
> Verwirrung.

Man muß halt erkennen, daß aus einem Array bei den meisten Operationen 
ein Pointer auf das erste Element gemacht werden kann. Bei einem Array 
aus Arrays ist das erste Element eben ein Array. Es wird nicht rekursiv 
durchgegangen und aus dem Array aus Arrays ein Pointer auf das Erste 
Element eines Arrays aus Pointern. Spaßig wird das, wenn man versucht, 
mehrdimensionale Arrays an Funktionen zu übergeben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren