Forum: Mikrocontroller und Digitale Elektronik Frage zu Zeigern


von Ain A. (ain)


Lesenswert?

Wenn ich die globalen Zeiger verwende
ist alles prima. Will ich allerdings die übergebenen Zeiger verwenden 
funktioniert nichts.
(es soll mehrere grad arrays geben)


1
unsigned char grad_array1[TEILER];
2
unsigned char grad_array2[TEILER];
3
unsigned char  *z_aktuelles_grad_array,*z_buffer_grad_array;
4
5
6
...
7
8
main()
9
{
10
...
11
   z_aktuelles_grad_array = &grad_array1[0];
12
   z_buffer_grad_array = &grad_array2[0];
13
...
14
   striche_in_array_schreiben(striche1,z_aktuelles_grad_array,z_buffer_grad_array);
15
...
16
}
17
18
void striche_in_array_schreiben(struct strich striche[],unsigned char *aktuelles_grad_array,unsigned char *buffer_array)
19
{
20
   unsigned char  *z_temp;
21
22
...//schreibt was ins buffer_array rein
23
24
  
25
   z_temp = z_aktuelles_grad_array;
26
   z_aktuelles_grad_array = z_buffer_grad_array;
27
   z_buffer_grad_array = z_temp;
28
   
29
// z_temp = aktuelles_grad_array;    //Auskommentiertes geht nicht! Warum?
30
// aktuelles_grad_array = buffer_array;
31
// buffer_array = z_temp;
32
}

von Floh (Gast)


Lesenswert?

Wenn du den Zeiger nach der Funktion verändert haben willst, musst du 
den Zeiger nicht als Kopie, sondern als Referenz übergeben.

Als Beispiel:
1
void aenderezeiger(char* &zeiger)
2
{
3
  zeiger++;
4
}
5
6
int main()
7
{
8
  char text[] = "abc";
9
  char *s = &text[0];
10
  aenderezeiger(s);
11
  // s steht jetzt auf text[1]
12
}
Wenn du keine Referenz (&) hast, wird ja eine lokale Kopie des Zeigers s 
angelegt (zeiger), dessen Änderungen sich nicht auf das Original 
auswirken.

Hoffe das passt so alles :-)

von Karl H. (kbuchegg)


Lesenswert?

Na ja, das funktioniert schon. ABer nicht so wie du dir das vorstellst

Dein Problem dürfte das hier sein
1
int main()
2
{
3
  int i = 5;
4
5
  foo( i );
6
  printf( "%d\n", i );
7
}
8
9
void foo( int j )
10
{
11
  j = 8;
12
}

und die Frage dazu lautet: warum hat i nach dem Funktionsaufruf immer 
noch den WErt 5, ich habe ihm doch in der Funktion einen neuen Wert 
zugewiesen.

Die Antwort darauf (die sich auch in jedem C-Lehrbuch findet) lautet: 
Weil bei der Parameterübergabe eine Kopie gemacht des Arguments gemacht 
wird. Die Funktion bekommt keinen Zugang zu i, sondern nur eine Kopie 
des Wertes von i. Und diesen Wert überschreibt sie lokal in der Funktion 
mit 8. Das ändert aber i nicht!

Will man einer Funktion die Möglichkeit geben, dann muss man der 
Funktion die Adresse der zu ändernden Variablen zur Verfügung stellen.

1
int main()
2
{
3
  int i = 5;
4
5
  foo( &i );
6
  printf( "%d\n", i );
7
}
8
9
void foo( int* j )
10
{
11
  *j = 8;
12
}

Jetzt hat die Funktion die Möglichkeit i zu ändern.

Bei dir ist jetzt die Sache die, das du nicht einfach einen int Wert 
hast, sondern einen Pointer
1
int main()
2
{
3
  char * wert = "Hallo";
4
5
  foo( wert );
6
  printf( "%s\n", wert );
7
}
8
9
void foo( char * j )
10
{
11
  j = "Welt";
12
}

Was passiert? Genau wie im ersten Beispiel bekommt die Funktion eine 
Kopie des momentanten Inhalts von wert. Dieser ist: die Startadresse des 
Strings.
DIese Startadresse wird in j abgelegt und innerhalb der Funktion 
manipuliert.

Aber: Das ändert nicht die Variable "Wert"

Das Schema sieht doch so aus
1
int main()
2
{
3
  T i = ...;
4
5
  foo( i );
6
}
7
8
void foo( T j )
9
{
10
  j = ...;
11
}

Im ersten Beispiel war T der Datentyp "int". Im dritten Beispiel war T 
der Datentyp "char *". Aber ansonsten sind die beiden Beispiele völlig 
gleichwertig. Es gibt keinen konzeptionellen Unterschied.

Das 2.te Beispiel hat gezeit, wie es richtig geht.
Das allgemeine Schema dazu lautet
1
int main()
2
{
3
  T i = ...;
4
5
  foo( & i );
6
}
7
8
void foo( T * j )
9
{
10
  * j = ...;
11
}

Setze anstelle von T einfach "int" ein und du landest beim 2.ten 
Beispiel.
Beim Aufruf steht ein & (als ein "Adress of" Operator), in der Argument 
Liste wird ein Pointer gemacht und Zugriffe erfolgen über den 
Dereferenzierungsoperator *.

Und jetzt wendest du dieses Schema auf die Situation an, dass T ein char 
Pointer ist. Also alle T durch "char *" austauschen.
Du landest bei
1
int main()
2
{
3
  char * wert = "Hallo";
4
5
  foo( &wert );
6
  printf( "%s\n", wert );
7
}
8
9
void foo( char * * j )
10
{
11
  *j = "Welt";
12
}

Und jetzt lautet die Ausgabe des Programmes tatsächlich "Welt", genauso 
und aus genau dem gleichen Grund, warum die Ausgabe in der int Version 
eine 8 war. foo hat über den Pointer Zugriff auf die Pointer-Variable 
wert und lässt sie auf den String "Welt" zeigen.

Willkommen in der 2-Stern Programmierung.

von Karl H. (kbuchegg)


Lesenswert?

Floh schrieb:

> Hoffe das passt so alles :-)

In C++: ja.
In C: nein. Da gibt es keine Referenzen.

von Ain A. (ain)


Lesenswert?

Vielen Dank. Der Post von kbuchegg kommt zu meinen Unterlagen.
Hier die Anwendung: http://www.youtube.com/watch?v=Ma3AscgeFlQ

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.