Zeigerfragen



  • Hi!

    Danke! Aber bei Char arrays (Zeichenketten) wird glaub ich meistens immer mit Zeigern gearbeitet!

    Laut Buch steht bei Call by Value werden die Werte nicht verändert; oder können verändert werden. Bei Zeigern schon. Könnte viell jemand mir bitte ein Bsp geben damit man den Unterschied genau erkennt? Wäre super!

    Ich hoffe eines Tages kapier ich das mit den Zeigern :(.

    In Dankbarkeit

    TomiF



  • TomiF schrieb:

    Hi!

    Danke! Aber bei Char arrays (Zeichenketten) wird glaub ich meistens immer mit Zeigern gearbeitet!

    Ja, aber sie sind nicht die einzige Anwendung für Zeiger 😉

    Laut Buch steht bei Call by Value werden die Werte nicht verändert; oder können verändert werden. Bei Zeigern schon. Könnte viell jemand mir ein Bsp geben damit man den Unterschied genau erkennt? Wäre super!

    Call-by-Value bedeutet, daß die Änderungen keinen Einfluß zum Aufrufer haben, bei Call-by-Reference kannst du die Argumente direkt ändern:

    void cbv(int i)
    {
      i=5;
      printf("%d\n",i);
    }
    
    void cbr(int* pi)
    {
      *pi=5;
      printf("%d\n",*pi);
    }
    
    int main()
    {
      int i=10;
      printf("vorher: %d\n",i);//ganz klar: 10
      cbv(i);
      printf("nach cbv: %d\n",i);//immer noch 10 - trotz der Zuweisung
      cbr(&i);
      printf("nach cbr: %d\n",i);//nun auf einmal 5
    }
    


  • Hi!

    Danke für deine Hilfe!

    void write_to_server (int fd, char *msg) 
    {
    write(fd,msg,strlen(msg));
    }
    

    Aufruf in main write_to_server(sock,"Bla\n");

    Ich hätte int fd auch mit int *fd deklarieren können. Gäbe es da einen Unterschied? Wahrsch. hätte ich dann beim Aufruf

    write_to_server(&sock,"Bla\n"); schreiben müßen

    In Dankbarkeit

    TomiF



  • Tim schrieb:

    In C gibt es kein "call by reference".

    mag sein, dass dein C-compiler keine pointer unterstützt. meiner schon, und damit kennt er auch 'call by reference'.
    🙂



  • TomiF schrieb:

    Hi!

    Danke für deine Hilfe!

    void write_to_server (int fd, char *msg) 
    {
    write(fd,msg,strlen(msg));
    }
    

    Aufruf in main write_to_server(sock,"Bla\n");

    Ich hätte int fd auch mit int *fd deklarieren können. Gäbe es da einen Unterschied?

    Ja, du hättest einen Zeiger übergeben müssen - technisch brauchst du an der Stelle keinen Zeiger, also lohnt sich der Aufwand nicht.

    @Undertaker: C Parameterübergabe ist grundsätzlich "call by value" - daß man mit Zeigern dann doch call-by-reference Verhalten nachbilden kann, steht auf einem anderen Blatt.



  • Undertaker schrieb:

    Tim schrieb:

    In C gibt es kein "call by reference".

    mag sein, dass dein C-compiler keine pointer unterstützt. meiner schon, und damit kennt er auch 'call by reference'.
    🙂

    Wir hatten das schonmal. Wir werden das hier nicht nochmal diskutieren.



  • Tim schrieb:

    Undertaker schrieb:

    Tim schrieb:

    In C gibt es kein "call by reference".

    mag sein, dass dein C-compiler keine pointer unterstützt. meiner schon, und damit kennt er auch 'call by reference'.
    🙂

    Wir hatten das schonmal. Wir werden das hier nicht nochmal diskutieren.

    darüber gibt es auch nix zu diskutieren, denn:

    ISO/IEC 9899:1999 schrieb:

    Apointer type may be derived from a function type, an object type, or an incomplete
    type, called the referenced type. A pointer type describes an object whose value
    provides a reference to an entity of the referenced type. A pointer type derived from
    the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a
    pointer type from a referenced type is called ‘‘pointer type derivation’’.

    🙂



  • Also könnte man zusammenfassend sagen "Wenn ich einer Funktion Werte geändert werden (auch dann bei return) braucht man Zeiger.



  • TomiF schrieb:

    Also könnte man zusammenfassend sagen "Wenn ich einer Funktion Werte geändert werden (auch dann bei return) braucht man Zeiger.

    Im Prinzip ja. Zeiger sind nur Hilfmittel, um an eine Variable über ihre Adresse und nicht über ihren Namen zuzugreifen. Somit ist es möglich, ein "Call-by-Reference" nachzubilden, denn in C gibt es keine (C++)-Referenzen.

    void foo(int p)
    {
      p = 9;
    }
    
    void bar(void)
    {
      int x = 1;
      foo(x);
      /* x == 1 bleibt unverändert */
    }
    

    Hier ein kleines Bsp: Jede Variable hat ihre Adresse im Speicher (hier dummy Werte)
    x @ 0x4
    p @ 0x8

    Beim Aufruf von 'void bar(void)' wird x auf 1 gesetzt, d.h. in memory[0x4] wird eine 1 geschrieben.
    Beim 'foo(x);' Aufruf, gibt es eine Kopie des Wertes von memory[0x4] in memory[0x8]. 'void foo(int p)' schreibt in p eine 9, also memory[0x8] = 9. Wenn 'void foo(int p)' beendet, dann sprint das Programm zurück, x bleibt unverändert, weil die Funktion foo nur die Kopie geändert hat.

    void foo(int *p)
    {
      *p = 9;
    }
    
    void bar(void)
    {
      int x = 1;
      foo(&x);
      /* x == 9, da foo über die Adresse von x den Wert ändert */
    }
    

    Hier ist es im Prinzip genaudasselbe. Der Unterschied ist, dass der Wert von der Variable p nicht 1 ist sondern 0x4, nämlich die Adresse von x. Mit '*p = 9;' sagt du, dass der Wert 9 nicht in p (bzw. @ 0x8) sondern dort geschrieben werden muss, worauf p zeigt und das ist 0x4. Also schreibt die Funktion den Wert 9 auf die Adresse 0x4 und ändert somit den Wert von x.

    Warum man in C meistens mit Zeigern arbeitet, wenn man Strings behandelt, liegt an der Natur der Strings in C. Strings bzw. Zeichenketten sind, wie ihre Namen darauf hinwiest, eine Folge (Kette) von Zeichen, die mit dem Zeichen '\0' endet. Da man per Byte nur ein Zeichen speichern kann, braucht man ein Array, wo man alle Zeichen (und das \0 Zeichen) Byte für Byte abspeichert. Mit einem Zeiger kannst du auf das erste Element des Arrays von Zeichen zeigen und somit auf die ganze Zeichenkette. Deswegen benutzt man auch Zeiger, wenn man Strings behandelt.



  • Danke ich glaub so langsam verstehe ich es!



  • supertux schrieb:

    Im Prinzip ja. Zeiger sind nur Hilfmittel, um an eine Variable über ihre Adresse und nicht über ihren Namen zuzugreifen. Somit ist es möglich, ein "Call-by-Reference" nachzubilden, denn in C gibt es keine (C++)-Referenzen.

    das ist richtig, wobei ich nicht von 'nachbilden' sprechen würde. unterschiedliche programmiersprachen bieten nun mal unterschiedliche mittel zum referenzieren an.
    🙂



  • Wieso habe ich das Gefühl, dass du wieder mal ne lange sinnlose Diskussion starten willst? Ich meine, die Diskussion über Call-by-Ref. vs. Call-by-Value in C haben wir etliche Male geführt, und die, die immer an Call-by-Ref glauben, werden die Argumente der anderen nie akzeptieren und das wirst du vielleicht auch nie.

    Es erinnert mich ein wenig an die elend lange Diskussion über "kann man OOP mit C schreiben?". Tatsache ist, C bietet dir Zeiger an, mit denen du die C++/Java Call-By-Reference nachbauen kannst, aber es ist keineswegs eine C++/Java Call-By-Reference, da Zeiger keine Referenzen sind. Dass am Ende dasselbe passiert, ist an der Stelle egal, denn ich finde, es ist wichtiger zu verstehen, was da eigentlich passiert und wieso man ein bestimmtes Effekt bekommt, dann versteht man auch, was andere Sprachen machen. Ein Zeiger ist keine Referenz, denn du kannst den Inhalt des Zeigers ändern und somit irgendwo anders zeigen.



  • supertux schrieb:

    Wieso habe ich das Gefühl, dass du wieder mal ne lange sinnlose Diskussion starten willst? Ich meine, die Diskussion über Call-by-Ref. vs. Call-by-Value in C haben wir etliche Male geführt, und die, die immer an Call-by-Ref glauben, werden die Argumente der anderen nie akzeptieren und das wirst du vielleicht auch nie.

    kann sein, dass ich alt werde, aber ich kann mich nur an eine erinnern, die von einem 'möchtegern-moderator' knallhart abgewürgt wurde. der hat mich für blöd erklärt, weil ich behauptete, dass C 'call by ref' kennt und den thread einfach geschlossen.
    ich will keine erneute, krampfhafte diskussion zu dem thema heraufbeschwören. jeder, der wissen will, was 'call by reference' (allgemein und insbesondere in C) bedeutet, muss einfach nur etwas googlen.
    🙂



  • höflich bleiben - danke


Anmelden zum Antworten