array ausdruecke in pointer umschreiben



  • hall erstmal, hab da ne aufgabe die ich gerne bisschen diskutieren wuerde.

    definition:         rewrite:
    
        a.      int x[6] -->             x[3] = x[2];
        b.      char *argv[] -->         cout << argv[2];
        c.      int x[] -->             &x[10] - &x[3];
        d.      char *argv[] -->        argv[0]++;
        e.      char *argv[] -->        argv++[0];
        f.      char *argv[] -->       ++argv[0];
        g.      char **argv -->         ++argv[0][2];
    

    es soll so kmopakt wie moeglich sein, keine unnoetigen klammern oder pointer.

    a.      int x[6] -->             x[3] = x[2];
    *(x+3) = *(x+2)
    

    der name des arrays ist ja die erste speicheradresse. da ich das vierte bzw. dritte element des array haben moechte muss ich zu erster speicheradresse jeweils drei bzw. zwei(integer) addieren.

    b.      char *argv[]  -->        cout << argv[2];
    cout << *(argv+sizeof(char)*2)
    

    hier bin ich mir nicht sicher. ich habe ja hier ein array names argv welches pointer vom typ char enthaelt oder? aber ich hab keine ahnung von der dimension. aber da ich durch sizeof(char) genau weiß wie viel speciherplatz ein char benoetigt kann ich einfach die groeße mal zwei weitergehn.
    wuerde es auch reichen einfach *(argv+2) zu machen?

    c.      int x[] -->             &x[10] - &x[3];
    (x + 10) - (x + 3);
    

    da ich hier die speicheradressen der elemente benoetige kann ich einfach zur startadresse weiterzaehlen und bekomme diese.

    d.      char *argv[] -->        argv[0]++;
    

    hmm hier habe ich wieder ein array mit pointer zu diversen chars;
    ich will das erste element des array inkrementieren.
    also

    (*argv)++;
    
    e.      char *argv[] -->        argv++[0];
    

    hier verstehe ich die frage nicht ganz, was bedeutet argv++[0]?

    f.      char *argv[];       ++argv[0];
    

    ich denke wie d. nur postfix.
    also

    ++(*argv);
    
    g.      char **argv -->        ++argv[0][2];
    

    hier wirds spannend 😃
    ein zwei dimensionales array.
    ich moechte in der ersten zweile das dritte element erhoehen.
    soweit verstehe ich es nur wie spreche ich das an?
    mit argv habe ich die erste adresse, da ich in der ersten zeile bleibe muesste ich doch theoretisch wie vorhin einfach um 2 weitergehen (je nachdem mit +2 oder +sizeof(char) *2)
    -->

    ++(*(argv+2))
    

    falls es richtig ist, wie spreche ich zb das element der dritten zeile an, also

    ++argv[2][2];
    

    ich dachte ich komme in die zweite zeile indem ich zu dem ersten elemetn die anzahl an elementen der zweiten dimension addirer. bp array: arr[3][4]
    indem ich arr + 5 mach (+4 waeren die elemente der ersten zeile, +5 das erste in der naechsten)
    aber ich habe hie ja keine dimension, also wie geht das dann?

    sorry ich weiß ist ein langer post geworden bin aber jedem helfer dankbar 🙂
    (falls wer einen link hat welcher das problem mehrdimensionale arrays mit pointern beschreibt wuerde mir das sehr helfen!)



  • Du musst nur folgende Regel anwenden:

    Array[Index] == *(Array+Index)
    

    Benutze bitte in Zukunft CPP-Tags, dann werden sich auch sicher mehr Leute deinen Thread anschauen.
    Zu Zeigern gibt es hier einen Artikel.



  • done 🙂
    danke fuer die erste rueckmeldung.
    ich lese mir mal den artikel durch, danke fuer den link!
    werde mich sicher noch melden 😉



  • AbsoluterBeginner schrieb:

    ok die konkreten fragen:
    a sollte passen.

    b.      char *argv[]  -->        cout << argv[2];
    cout << *(argv+sizeof(char)*2)
    

    dh es wuerde hier reichen

    cout << *(argv+2)
    

    zu machen da der compiler check dass es ein char ist und somit selbst die groeße weiß wie viele bytes er weiter gehen soll oder?

    c.      int x[] -->             &x[10] - &x[3];
    (x + 10) - (x + 3);
    

    da ich hier die speicheradressen der elemente benoetige kann ich einfach zur startadresse weiterzaehlen und bekomme diese.

    is flasch oder, ich muss ja noch ein & davor geben, also:

    &(x + 10) - &(x + 3);
    
    d.      char *argv[] -->        argv[0]++;
    
    (*argv)++;
    

    sollte passen..

    e.      char *argv[] -->        argv++[0];
    

    immer noch offen:
    hier verstehe ich die frage nicht ganz, was bedeutet argv++[0]?

    f.      char *argv[];       ++argv[0];
    

    ich denke wie d. nur postfix.
    also

    ++(*argv);
    

    sollte auch passen....

    g.      char **argv -->        ++argv[0][2];
    

    also wenn ich es nach dem pointer thread richtig verstanden habe:
    ein pointer (zeile) zeigt auf einen anderen pointer der die elemente pro zeile anspricht.
    argv hat die adresse des ersten elementes in der ersten zeile, weiter weiß ich trotzdem nich und verweiße auf meine vorherige frage:

    ich moechte in der ersten zweile das dritte element erhoehen.
    soweit verstehe ich es nur wie spreche ich das an?
    mit argv habe ich die erste adresse, da ich in der ersten zeile bleibe muesste ich doch theoretisch wie vorhin einfach um 2 weitergehen

    ++(*(argv+2))
    

    falls es richtig ist, wie spreche ich zb das element der dritten zeile an, also

    ++argv[2][2];
    

    ich dachte ich komme in die zweite zeile indem ich zu dem ersten elemetn die anzahl an elementen der zweiten dimension addirer. bp array: arr[3][4]
    indem ich arr + 5 mach (+4 waeren die elemente der ersten zeile, +5 das erste in der naechsten)
    aber ich habe hier ja keine dimension, also wie geht das dann?

    vielen dank schon mal.
    ein thread ueber mehr dimensionale array waere nett, der vorherige bringt mich nicht weiter 😞



  • zu c.
    (x+10)-(x+3) ist schon richtig. Du bildest ja die Differenz der Adressen des zehnten und dritten Elements ( x[10] <=> *(x+10) => &x[10] <=> (x+10) ). &(x+10) ist sowieso Unsinn, da man die Adresse von einem Zwischenergebnis nicht bilden kann ( (x+10) wird ja nirgendwo gespeichert).

    zu e.
    Das Ergebnis des Ausdrucks ist der Wert des ersten Arrayelements, da argv++ den alten Zeigerwert von argv zurückgibt. argv selbst zeigt danach auf das zweite Arrayelement. Die Lösung sieht fast wie bei d. aus 🙂 ACHTUNG: Das ganze ist nur gültig, wenn argv ein Funktionsparameter ist.

    zu g.
    Eigentlich musst Du nur die Indirektionsstufen nacheinander auflösen. Behandle die innere Indirektion zuerst, dann substituiere das Ergebnis. Bei der äusseren Dimension tust Du so, als ob es ein Eindimensionales Array wäre und schleppst das, was innen steht, einfach mit.

    Betrachten wir also ++argv[0][2] . Die innere Indirektion ist argv[0] , also (*argv) (siehe a.). Wir haben jetzt ++(*argv)[2] . Nun erklären wir: z entspricht (*argv) , haben also ++z[2] . Jetzt machst Du das, was Du bei f. schon gemacht hast und ersetzt danach z wieder durch (*argv) .

    Der Rest stimmt, wenn ich nichts übersehen habe.



  • AbsoluterBeginner schrieb:

    ein thread ueber mehr dimensionale array waere nett, der vorherige bringt mich nicht weiter 😞

    Das hilft ev. auch weiter, wenn du mal das ganze noch übergeben willst:

    3D

    2D



  • LordJaxom schrieb:

    zu c.
    (x+10)-(x+3) ist schon richtig. Du bildest ja die Differenz der Adressen des zehnten und dritten Elements ( x[10] <=> *(x+10) => &x[10] <=> (x+10) ). &(x+10) ist sowieso Unsinn, da man die Adresse von einem Zwischenergebnis nicht bilden kann ( (x+10) wird ja nirgendwo gespeichert).

    hmm ich denke eher da

    x+10
    

    ja schon eine adresse ist kann ich nicht

    &(x+10)
    

    machen oder? denn was ist die adresse der adresse 😃

    zu e.
    Das Ergebnis des Ausdrucks ist der Wert des ersten Arrayelements, da argv++ den alten Zeigerwert von argv zurückgibt. argv selbst zeigt danach auf das zweite Arrayelement. Die Lösung sieht fast wie bei d. aus 🙂 ACHTUNG: Das ganze ist nur gültig, wenn argv ein Funktionsparameter ist.

    hae?!
    dh ich spreche den char pointer dann an wie ein array?!
    ich habe ja

    argv[0]
    

    auszugeben (da das postix erst spaeter wirkt) dass waere dann mit

    *argv
    

    getan - richtig?!

    zu g.
    Betrachten wir also ++argv[0][2] . Die innere Indirektion ist argv[0] , also (*argv) (siehe a.). Wir haben jetzt ++(*argv)[2] . Nun erklären wir: z entspricht (*argv) , haben also ++z[2] . Jetzt machst Du das, was Du bei f. schon gemacht hast und ersetzt danach z wieder durch (*argv) .

    also stimmt

    ++(*((argv)+2))
    

    oder?

    meine gedanken:
    mit argv bekomme ich die speicher adresse des elementes [0][0],da ich in dieser zeile das dritte element moecht noch +2 addieren und ich habe die adresse dieses elements.
    durch den * bekomme ich den wert des elements und inkreentiere es.
    die klammern um argv mache ich darum da ich ja mit argv+2 die uebernaechste zeile des arrays ansprechen wuerde oder nicht? da ich das nicht will druecke ich somit aus, bleib in der zeile argv und gehe zwei "schritte" (ints) weiter

    danke...



  • Bei argv hast du nichts mit Zeilen und Spalten und was weiß ich, da es kein mehrdimensionales Array ist das sequentiell im Speicher steht. Denn es ist ein stumpfes Array von char*. Das heißt im Speicher hast du nur sequentiell die Adressen der jeweiligen char-Arrays der Parameterwerte stehen.

    Mit argv+2 bekommst du die Adresse an der die Adresse des ersten Buchstaben des dritten Parameters liegt.
    Mit (argv+2) bekommst du die Adresse des ersten Buchstaben des dritten Parameters.
    Mit ++(
    (argv+2)) veränderst du diese Adresse, so daß sie von da an auf den zweiten Buchstaben des dritten Parameters zeigt.



  • Fellhuhn schrieb:

    Mit argv+2 bekommst du die Adresse an der die Adresse des ersten Buchstaben des dritten Parameters liegt.

    nur um sicher zu gehen ob ich "Adresse an der die Adresse des" richtig verstehe:
    argv = erste adresse im speicher, +2 komme ich zum dritten array.
    also adresse des ersten buchstabens vom dritten wert.

    Mit *(argv+2) bekommst du die Adresse des ersten Buchstaben des dritten Parameters.

    😕 waere ja dann wie oben wenn ich nur eine adresse bekommen.
    ich dachte durch * gehe ich eine ebene hoeher, also dachte ich wuerde hier den ersten buchstaben des dritten arrays bekommen - nicht?

    Mit ++(*(argv+2)) veränderst du diese Adresse, so daß sie von da an auf den zweiten Buchstaben des dritten Parameters zeigt.

    also auch hier wuerde ich das char des dritten arrays an der ersten stelle um eines erhoehen (1 wert weiter in der ascii tabelle)

    wo ist mein denkfehler?!



  • AbsoluterBeginner schrieb:

    nur um sicher zu gehen ob ich "Adresse an der die Adresse des" richtig verstehe:
    argv = erste adresse im speicher, +2 komme ich zum dritten array.
    also adresse des ersten buchstabens vom dritten wert.

    Mit +2 hast du dann die Adresse an der die Adresse des dritten Parameters steht (char Array).

    😕 waere ja dann wie oben wenn ich nur eine adresse bekommen.
    ich dachte durch * gehe ich eine ebene hoeher, also dachte ich wuerde hier den ersten buchstaben des dritten arrays bekommen - nicht?

    Durch den *-Operator auf einen Zeiger bekommst du das, was an der Adresse auf die verwiesen wird steht. Also wenn argv+2 die Adresse der Adresse des dritten Parameters ist, dann ist *(argv+2) dann nur noch die Adresse des dritten Parameters.

    also auch hier wuerde ich das char des dritten arrays an der ersten stelle um eines erhoehen (1 wert weiter in der ascii tabelle)

    wo ist mein denkfehler?!

    Das du noch nicht bei den Chars bist. Weil eben (argv+2) dir nur einen Zeiger auf das erste Element des Char-Arrays gibt aber nicht den Char selbst. Wolltest du den Char verändern, müsstest du den Zeiger selbst auch noch einmal dereferenzieren: ++((*(argv+2))



  • ok, eine dimension vergessen 😃
    nochmal zum konkreten beispiel:

    char **argv; --> ++argv[0][2];
    

    ich moechte den dritten buchstaben des ersten arrays erhoehen.
    argv zeigt auf einen weiteren zeiger der mir die adresse des ersten arrays gibt.
    also ich muss

    *argv
    

    habe ich die adresse des ersten arrays, von dort aus muss ich um zwei weitergehen -->

    ((*argv)+2)
    

    da ich aber nicht die adresse haben moechte (sondern den char selbst) noch ein * davor -->

    *((*argv)+2)
    

    ist der char welcher im ersten array an dritter position steht.
    da ich diesen inkrementieren moechte noch ein ++ davor -->

    ++(*((*argv)+2))
    

    endergebnis.

    vielen dank, waere super wenn es jetzt richtig waere 😃



  • Genau. Wobei du bedenken musst das der erste (bzw. "nullte") Parameter immer der Programmname an sich ist.



  • danke 😉


Log in to reply