Announcement

Collapse
No announcement yet.

Frage zu Pointern und Referenzen in C und C++

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Frage zu Pointern und Referenzen in C und C++

    Hallo zusammen

    Ich habe ein paar Fragen dazu, wann ich Pointer und Referenzen in C und C++ verwende. Ich fange gerade erst an, mich etwas tiefgreifender mit dem Ganzen zu beschäftigen.

    Also erstmal zu C, da gibts ja nur Pointer.

    Ich verstehe, dass ich Pointer verwende, wenn ich die Speicheradresse brauche und nicht den Wert an der Adresse. Man braucht sie bei malloc und pass by reference. Aber hier mal ein paar konkrete Beispiele, die ich nicht 100% verstehe:

    A) Was ist der Unterschied zwischen

    Code:
    char[] name = "Hans"
    und
    Code:
    char* name = "Hans"
    ?

    B) Was ist bei structs der Unterschied zwischen:
    Code:
    struct Books
    {
       int   book_id;
    };
    
    struct Books Book1; 
    
    Book1.book_id = 1;
    und
    Code:
    struct Books
    {
       int   book_id;
    };
    
    struct Book *eins = malloc(sizeof(struct Book));
    
    eins->book_id = 1;
    Welchen Sinn hat es, einen Pointer zu verwenden, um auf das struct zuzugreifen?

    C) Das hier ist aus dem Quellcode der TCP-Implementierung von Linux
    Code:
    int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
     148{
     149        struct inet_sock *inet = inet_sk(sk);
     150        struct tcp_sock *tp = tcp_sk(sk);
     151        struct sockaddr_in *usin = (struct sockaddr_in *)uaddr;
     152        struct rtable *rt;
     153        __be32 daddr, nexthop;
     154        int tmp;
     155        int err;
     156
     157        if (addr_len < sizeof(struct sockaddr_in))
     158                return -EINVAL;
    Hier ist der Parameter addr_len kein Pointer, weil er nur dazu verwendet wird, einen Wertvergleich durchzuführen. Alle anderen sind Pointer, weil sie entweder an weitere Funktionen gereicht werden, die pointer verlangen oder weil sie by reference übergeben werden sollen, richtig?

    D) In LinkedLists sind die Knoten wie next, temp etc. Pointer, weil sie auch den Wert null annehmen können, oder?



    Dann zu Referenzen und Pointer in C++

    Bei diesem SO-Post http://stackoverflow.com/questions/2...nter-or-valuea steht als Kommentar:
    References are not necessary, they are syntactic sugar that makes it easier to use data without copying it without exposing you to raw pointers and their potential for abuse. You should use references any time you don't need to use pointers but need to change the data. You should use const references any time you only need the value but want to avoid creating a copy (as with pass-by-value)
    Also mal an diesem Beispiel: http://www.cplusplus.com/articles/LACRko23/, der Konnstruktor einer Node-Klasse

    Code:
    Node(const T& item, Node<T>* ptrnext = NULL);
    ptrnext ist ein Pointer, weil es den Wert null annehmen kann. item ist eine const reference, weil man hier nur den wert braucht, aber keine Kopie der Daten anfertigen will. Richtig?

    Wann benutzt man denn dann überhaupt noch pass by value in C++? Ich kann ja auch bei Primitiven eine const reference übergebenl oder?

    Und verstehe ich richtig, dass man in C++ dann Objekte prinzipiell als Referenzen anlegen soll und nur dann als Pointer, wenn unbedingt nötig? Also besser A) als B):
    Code:
    A) Objekt instanz;
    B) Objekt *instanz = new Objekt();
    Wäre sehr dankbar für ein paar erhellende Worte

  • #2
    Generell halte ich mal fest: jede Variable in C hat immer 2 Werte. Die Adresse der Speicherstelle der Variable und den Inhalt.

    A, das ist absolut dasselbe. Beides sind Pointer die auf den ersten Buchstaben des Char Arrays zeigen (der Buchstabe 'H')

    B, Im ersten Beispiel ohne Pointer steht in der ersten Speicherzelle des Strukts direkt der Integer Wert. Haette das struct noch mehrere Felder, dann wuerden die einfach hintereinander im Speicher stehen.
    Beim zweiten Beispiel wird Speicher der Groesse Books angelegt. Das ganze gibt dann einen Zeiger auf die erste Speicherzelle des Structs zurueck. In der Variable Books steht dann die Adresse der ersten Speicherzelle des Book Structs. Deswegen musst Du dann auch zum Zugriff (*eins) schreiben.

    C, Im Prinzip wird immer wenn Du eine Variable an eine Funktion uebergibst der Wert der Variable kopiert. Bei den ersten beiden Variablen wird die Adresse der ersten Speicherzelle kopiert und Du musst auch eine Adresse uebergeben, bei der letzten Variable wird der Inhalt der Speicherzelle kopiert (addr_len). Moechtest Du innerhalb einer Funktion den Wert in einer Speicherzelle veraendern solltest Du diesen Mechanismus benutzen. Im Prinzip stimmt das was Du geschrieben hast, das sind aber mehr die Auswirkungen als die Ursachen warum man das tut.

    D, Deine Aussagen wuerde ich nicht ganz unterschreiben. Listen sind von Grund auf dynamisch. Das heisst Du weisst beim Kompilieren noch nicht wieviele Elemente in der Liste sein koennen. Um zur Laufzeit Elemente hinzufuegen oder wegehmen zu koennen brauchst Du Pointer bzw. malloc. Natuerlich kannst Du damit auch erkennen ob es noch mehr Elemente in der Liste gibt oder ob Du am Ende der Liste bist (next == null).

    Zu Referenzen vs Pointer kann ich nicht ganz so viel sagen. Die C++ Feinheiten kenne ich nicht sooo gut. Variante B, scheint mir aber doch die uebliche zu sein in Plain C++, vor allem weil man bei B immer einen parameterlosen Konstruktor braucht, was ich fuer schwer realisierbar halte.

    Comment


    • #3
      Halllo!

      Vielen Dank für die Antworten!

      Was ist denn bei B) der Vorteil des einen gegenüber dem anderen?

      Zu C) okay, dann sind das hauptsächlich deswegen Pointer, weil malloc eben einen Pointer zurückgibt?

      Zu D) du meinst, bei Variante A braucht man immer einen parameterlosen Konstruktor? Soweit ich das weiß, ist das nicht so. Im Beispiel oben wird zwar der parameterlose Standardkonstuktor aufgerufen, aber ich kann ja auch sowas schreiben:

      Ref neu = Ref("param");

      Comment


      • #4
        Zu B: Ich wuerde nicht sagen dass irgendwas davon einen vor oder Nachteil hat. In der ersten Variante hast Du nur keinen Pointer. Falls Du das struct als per reference uebergeben moechtest muesstest Du Dir noch einen Pointer erzeugen:

        Code:
        struct Book * Book1Pointer = &Book1;
        Zu C: Ja genau. malloc kann auch nur Pointer zurueckgeben, da erst zur Laufzeit entschieden wird wie gross der Inhalt ist.

        Zu D: Wie gesagt ich bin in C++ nicht sehr fit und ich bin mir da auch nicht sicher. Das war nur ein Gedanke der mir durch den Kopf ging der das vielleicht erklaeren koennte. Wenn Du das aber so schreiben kannst wie Du das gesagt hast, dann wird sich das wohl wie B, verhalten. Das waere aber auch nur meine naive Annahme ohne wissenschaftliches Fundament

        Comment


        • #5
          Super, vielen Dank für die Antworten!!

          Comment

          Working...
          X