Pointer



  • Hey,

    ich lerne gerade ein wenig C und bin nun beim Kapitel Pointer.

    Da werden allerdings einige Fragen nicht beantwortet.

    1. Pointer oder Gobale Variable? Was ist sinnvoller? (Unterschiede?)
    2. Lieber Adresse einer Variablen an eine Funktion übergeben oder direkt die Variable was ist besser? (Funktionsparameter können also entweder nen Pointer oder ne Variable sein)
    3. Array - Pointer - Unterschied?

    Danke schon Mal.

    P.s: Bitte für "Dummies" erklären 😃



  • ITrun90 schrieb:

    1. Pointer oder Gobale Variable? Was ist sinnvoller? (Unterschiede?)

    Blau oder eckig - was ist schoener?

    ITrun90 schrieb:

    2. Lieber Adresse einer Variablen an eine Funktion übergeben oder direkt die Variable was ist besser? (Funktionsparameter können also entweder nen Pointer oder ne Variable sein)

    und was ist ein pointer? Genau: eine variable. Soll eine funktion einen parameter veraendern koennen -> ptr. Ist ein parameter unverhaeltnismaessig gross zu einem ptr -> ptr. Soll das ziel unveraendert bleiben -> const ptr.

    ITrun90 schrieb:

    3. Array - Pointer - Unterschied?

    Ein ptr. Ist ein ptr, ein array ist ein array, wird aber ggf. als ptr interpretiert.

    Hast du keine beispiele, aus denen sich fragen ergeben?



  • Lustig. 😉

    Aber so fängt man eben an.

    Die Pointer in C kannst du gar nicht umgehen, auf jeder Funktion liegt ein Pointer und auf jedem Array. Das ist aber nicht dein Problem, du mußt dich nicht drum kümmern.

    Lern erstmal C und mach dir keinen Kopf.

    Laß die Pointer raus.

    Man kann in C programmieren ohne Pointer, und wenn man das kann, dann kann man darangehen, diese seltsamen Datentypen zu verstehen. Bevor man sich aber nicht auskennt, macht es keinen Sinn.

    Laß die globalen Variablen weg und programmiere mit arrays.

    Kannst natürlich machen, was du willst, aber das wäre so mein Tipp für den Einstieg.

    LG Alex



  • Du meine Güte, das ist womöglich der surrealste Beitrag, den ich je gelesen habe.



  • Das mit dem weglassen wird nicht funktionieren.

    Denn spätestens wenn in einer Funktion die Größe des Arrays gebraucht wird, geht das schief.



  • alex2010 schrieb:

    Lustig. 😉

    Aber so fängt man eben an.

    Ja, und über den Anfang bist du selbst noch nicht hinaus gekommen.

    alex2010 schrieb:

    Die Pointer in C kannst du gar nicht umgehen,
    ...
    Laß die Pointer raus.

    Du hast keine Ahnung, wovon du redest und lässt andere Leute an dieser deiner Ahnunglosigkeit teilhaben.



  • seldon schrieb:

    Du meine Güte, das ist womöglich der surrealste Beitrag, den ich je gelesen habe.

    Warum?



  • Wutz schrieb:

    alex2010 schrieb:

    Lustig. 😉

    Aber so fängt man eben an.

    Ja, und über den Anfang bist du selbst noch nicht hinaus gekommen.

    alex2010 schrieb:

    Die Pointer in C kannst du gar nicht umgehen,
    ...
    Laß die Pointer raus.

    Du hast keine Ahnung, wovon du redest und lässt andere Leute an dieser deiner Ahnunglosigkeit teilhaben.

    Das ist keine gute Art von Kommunikation.

    Dem anderen zu unterstellen, daß er keine Ahnung hat.

    Du irrst dich, definitiv. Aber was soll´s!

    Es ist für den Anfang besser, mit indizierten Arrays zu arbeiten. Ist meine Meinung.

    LG Alex



  • 1. globale Variablen sind meistens schlecht, bei Anfängern immer
    2. wenn du den Wert der Variablen in der Funktion ändern willst, musst du einen Zeiger übergeben, ansonsten kannst du einen Zeiger verwenden um Stack zu sparen (z.B. bei großvolumigen structs, nicht bei Arrays);
    Variablen direkt zu übergeben hat den "Vorteil", dass die Syntax einfacher ist und du "gefahrlos" darauf arbeiten kannst, da du hierbei immer auf einer Kopie arbeitest
    3. Arrays zerfallen außer bei 4 Ausnahmen (die ich dir hier nicht erkläre, selbst lernen!) in einen Zeiger auf das erste Arrayelement und sie sind im Gegensatz zu Zeigern ein unmodifiable lvalue.



  • Wutz schrieb:

    1. globale Variablen sind meistens schlecht, bei Anfängern immer
    2. wenn du den Wert der Variablen in der Funktion ändern willst, musst du einen Zeiger übergeben, ansonsten kannst du einen Zeiger verwenden um Stack zu sparen (z.B. bei großvolumigen structs, nicht bei Arrays);
    Variablen direkt zu übergeben hat den "Vorteil", dass die Syntax einfacher ist und du "gefahrlos" darauf arbeiten kannst, da du hierbei immer auf einer Kopie arbeitest
    3. Arrays zerfallen außer bei 4 Ausnahmen (die ich dir hier nicht erkläre, selbst lernen!) in einen Zeiger auf das erste Arrayelement und sie sind im Gegensatz zu Zeigern ein unmodifiable lvalue.

    1. Pauschale Aussagen sind meistens schlecht. Allerdings, mit den globalen Variablen, nun gut ...

    2. Sagen wir es mal deutlich:

    Call by value oder Call by reference

    Es werden da nicht notwendigerweise Zeiger übergeben, sondern Adressen, sieht man bei der Standardfunktion fwrite(&buffer ....

    3. Arrays haben zwar einen programminternen Zeiger, aber es muß den Programmierer nicht kümmern.

    Also, na ja .... ob das wirklich sinnstiftend ist, was du schreibst??? 😉



  • @alex: Na, was soll denn das bedeuten, "auf jeder Funktion liegt ein Pointer und auf jedem Array"? Nach der Beschreibung könnte man wirklich glauben, dass Zeiger seltsam seien. Und Arrays als Ersatz für globale Variablen zu empfehlen, ist auch ziemlich skurril.

    Also, Zeiger (Zeiger == Pointer) mal ganz einfach: Ein Zeiger zeigt auf eine Stelle im Speicher. Man kann ihn hinzeigen lassen, wo man lustig ist, sei es auf Funktionen, Arrays, andere Variablen - wenn es im Speicher liegt, kann ein Zeiger darauf zeigen. Technisch verbirgt sich dahinter in aller Regel eine Zahl, praktisch wie eine Hausnummer.

    Der Zeigertyp bestimmt Teile der Semantik: ist der Zeiger ein int*, so wird der Speicher, auf den er zeigt, als int interpretiert, ist es ein double* entsprechend als double (es ist daher empfehlenswert, einen int* auch auf ints zeigen zu lassen). Das zeigt sich neben der Dereferenzierung (*ptr) vor allem in der Pointerarithmetik - wenn p ein Zeiger ist, zeigt p + 1 auf die Speicherstelle ein Element hinter p, und dabei ist natürlich wichtig, wie groß ein Element ist. So funktioniert dann auch die Array-Syntax: p[i] == *(p + i).

    Und das ist auch schon alles.

    Was bei Anfängern häufig zu Verwirrung führt (und bei dir augenscheinlich zu Verwirrung geführt hat), wenn Arrays vorher nicht richtig erklärt wurden, ist der Umstand, dass Arrays implizit in Zeiger umwandelbar sind. Ich kann schreiben

    int array[] = { 1, 2, 3, 4, 5 };
    int *ptr = array;
    

    Hier ist array kein Zeiger und ptr kein Array. Es wird auch für array kein Zeiger in den Speicher gelegt - ein Array ist ein Speicherbereich, in dem mehrere Elemente gleichen Typs direkt hintereinander liegen. Aber: bei der Zuweisung zerfällt array zu einem Zeiger auf sein erstes Element, und dieser wird ptr dann zugewiesen. Ich versuch das mal in einem Diagramm darzustellen:

    +----+---
    +-- 0 --| 12 | ptr
    |       +----+---
    |   4   |    |
    |       +----+
    |   8   |    |
    |       +----+---
    +- 12 ->|  1 | a
            +----+
       16   |  2 | r
            +----+ 
       20   |  3 | r
            +----+
       24   |  4 | a
            +----+
       28   |  5 | y
            +----+---
       32   |    |
            +----+
    

    Die eigentlichen Gegenwerte der Speicheradressen sind in der Realität natürlich ganz anders. Auch bei zweidimensionalen Arrays werden keine Zeiger herangezogen, die Unterarrays liegen stumpf in Arrayform hintereinander im Speicher. Deswegen kann man sie auch nicht in Zeiger auf Zeiger stopfen.



  • [quote="seldon"]@alex: Na, was soll denn das bedeuten, "auf jeder Funktion liegt ein Pointer und auf jedem Array"? Nach der Beschreibung könnte man wirklich glauben, dass Zeiger seltsam seien. Und Arrays als Ersatz für globale Variablen zu empfehlen, ist auch ziemlich skurril.

    Lieber Seldon,

    es ist nett, daß du hier Aufklärungsarbeit betreibst, aber mich mußt du nicht aufklären und was die META-Ebene der Anfrage eines Programmierer-Neulings betrifft:

    Ich wollte andeuten, daß, auch wenn man keinen Pointer selbst deklariert, der Compiler zur Laufzeit die Arrays sowieso mit Pointern verwaltet.

    Die man aber nicht sieht und auch nicht selbst deklariert. Auf jedem Array liegt ein programminterner Pointer zur Laufzeit, das war die Aussage.

    Und meine Meinung ist, daß ein Anfänger besser zurechtkommt mit i[n] als wenn er sich gleich an selbst deklarierte Pointer heranwagt.

    Das ist meine Meinung, ob die richtig ist, sei dahingestellt.

    LG Alex



  • alex2010 schrieb:

    Ich wollte andeuten, daß, auch wenn man keinen Pointer selbst deklariert, der Compiler zur Laufzeit die Arrays sowieso mit Pointern verwaltet.

    Die man aber nicht sieht und auch nicht selbst deklariert. Auf jedem Array liegt ein programminterner Pointer zur Laufzeit, das war die Aussage.

    Das ist nicht der Fall. Der Compiler macht zur Laufzeit überhaupt nichts mehr, da ist er schon lange nicht mehr da. Der Code, den er zur Compilezeit erstellt hat, behandelt Arrays auch nicht als Zeiger, das habe ich dir gerade zu erklären versucht. Wenn ich ein Array deklariere, liegt dadurch nirgends ein Zeiger!



  • alex2010 schrieb:

    2. Sagen wir es mal deutlich:

    Call by value oder Call by reference

    Letzteres gibt es in C nicht. Hier gibt es nur Call-by-Value. Wenn der übergebene Wert ein Zeiger ist, lässt sich durch Dereferenzieren natürlich eine Änderung des entsprechenden Speichers erzielen. Der Zeiger selbst wird aber als Wert übergeben und kann innerhalb der aufgerufenen Funktion auch problemlos verunstaltet werden, ohne dass der Aufrufer das mitbekommt.


Log in to reply