argv, Zeigerarrays und andere Widrigkeiten ;o)



  • Original erstellt von <fff>:
    Also ist Zeiger auf Zeiger eigentlich schwachsinn oder?

    nee. ist nur anderes speicherlayout.

    int** mach2darray(int sx,int sy)
    {
      int i;
      int** oberarray=malloc(sx*sizeof(int*));
      for(i=0;i<sx;++i)
       oberarray[i]=malloc(sy*sizeof(int));
      return oberarray;
    }
    

    vorteil von das hier ist, daß der ganze speicher nicht an einem stück sein muß, was bei dos manchmal schwer war. und daß der benutzer dieses 2d-arrays nix über dessen dimensionen wissen muß. die beiden dereferenzierungen bei zweimaligem [] machen das schon.

    int (*mach2darraymitsyist4(int sx))[4]
    {
      int (*array)[4]=malloc(sx*sizeof(int[4]));
      return array;
    }
    

    vorteil von das hier ist, daß nicht zwei dereferenzierunge nötig sind, sondern ein [] mit adresberechnung gemacht wird. und ein wenig speicherplatzsparender ist es, weil kein oberarray gebaurcht wird. und natürlich nur ein malloc-aufruf. nachteil ist, daß nur eine dimension frei wählbar ist. alle anderen müssen fest sein.



  • Wielange hast Du den gebraucht, um das mit den "Zeiger auf Zeiger" zu verstehen?



  • Original erstellt von <fff>:
    Wielange hast Du den gebraucht, um das mit den "Zeiger auf Zeiger" zu verstehen?

    jahre.



  • Das ist häftig.

    Auf jeden Fall danke, für deine Hilfe. 🙂



  • Original erstellt von fff**
    Naja also wenn du mit alten Windows-Versionene arbeitest, sind 2Byte schon richtig**

    Nix altes Windows, sondern neues Linux 😉
    Aber ist schon klar, das mit den 16Bit. 32Bits sind natürlich 4 Bytes...

    Original erstellt von volkard**
    jahre.**

    Ich sehe mich auch in ein paar Jahren noch dahängen und darüber grübeln, ob es nun ein Zeigerarray oder sonst was anderes ist *kotz*. Mal im Ernst: ich habe noch keine Anleitung gesehen, in der das einfach verständlich erklärt wird. Aber es kann bestimmt nicht deshalb einfach erklärt werden, weil es nicht einfach ist - ganz einfach 😉

    Ok, ich resümiere mal für mich: Zeigerarrays, deren Elemente wieder auf Arrays zeigen, sind natürlich keine 2-dim-Arrays, da 2-dim-Arrays als Elemente wiederum Arrays enthalten und ihr Speicherplatz hintereinander reserviert ist. Die Arrays, auf die die Elemente eines Zeigerarrays zeigen, können hingegen dynamisch verändert werden, das ganze Array von Zeigern kann natürlich auch dynamisch verändert werden, wenn man eine Dimensionierung unterlässt und malloc zunächst auf das Zeigerarray und dann noch auf jedes Array, auf welches ein Zeiger des Zeigerarrays zeigt, ausführt.
    Aber: Zeigerarrays, deren Elemente auf Zeiger zeigen UND 2-dim-Arrays können auf dieselbe Art und Weise angesprochen werden, oder?

    Letzter Hint hierzu nochmal: wieso darf ich argv++ ausführen, wenn doch argv ein konstanter Zeiger ist? Bashar hatte eine kleine Lösung angegeben, doch damit kann ich wenig anfangen: "Weil Array an Funktionen als Zeiger übergeben werden."
    Kann mir das jemand nochmal kurz erklären?



  • Kennst Du schon das Tutorial auf www.pronix.de ?

    Da wird das und noch viel mehr, verständlich und leicht erklärt 🙂

    Nix altes Windows, sondern neues Linux

    dito 🙂



  • Kenne es schon, aber da habe ich in Bezug auf die kleine argv-Frage keine Antwort gefunden 😞



  • Original erstellt von RTC:
    Letzter Hint hierzu nochmal: wieso darf ich argv++ ausführen, wenn doch argv ein konstanter Zeiger ist? Bashar hatte eine kleine Lösung angegeben, doch damit kann ich wenig anfangen: "Weil Array an Funktionen als Zeiger übergeben werden."
    Kann mir das jemand nochmal kurz erklären?

    also sowas:

    int main(int argc,char** argv)
    {
        ++argv;
        return 0;
    }
    

    tja, also argv ist hier nicht konstant. ist ne lokale variable, die auf den ersten argument-string zeigt. so nen übergebenen zeiger kannste ändern. macht man manchmal auch ganz gerne, wie hier:

    int strlen(char* str)
    {
      int result=0;
      while(*str)
      {
        ++result;
        ++str;
      }
      return result;
    }
    

    gemeiner wirds hierbei:

    int main(int argc,char *argv[])
    {
        ++argv;
        return 0;
    }
    

    das darf natürlich nicht klappen. außer, bashar hat nen guten grund.

    erstmal seine these prüfen, daß da heimlich nu ein zeiger übergeben wird.

    void test(double x[])
    {
        cout<<sizeof(x)<<endl;
    }
    int main()
    {
        double a[10];
        cout<<sizeof(a)<<endl;
        test(a);
        return 0;
    }
    

    ausgabe:

    80 
    4
    

    aha. durch irgend eine compilermagie wurde in der tat dafür gesorgt, daß x innerhalb der funktion nur ein zeiger ist. hat vermutlich den grund, daß es viel zu lange dauern würde, alle 80 bytes zu kopieren bei jedem funktionsaufruf.
    wenn ich jetzt ganz fest an die compilermagie glaube, ganz fest daran, daß da in wirklichkeit statt void test(double x[]) nur ein void test(double *x) steht, dann klappt ++x.



  • Original erstellt von volkard:
    **also sowas:

    int main(int argc,char** argv)
    {
        ++argv;
        return 0;
    }
    

    tja, also argv ist hier nicht konstant.
    [...]
    gemeiner wirds hierbei:

    int main(int argc,char *argv[])
    {
        ++argv;
        return 0;
    }
    

    das darf natürlich nicht klappen. außer, bashar hat nen guten grund.**

    Bin zwar nicht bashar, aber ich antworte trotzdem mal 🙄
    Beide Beispiele sind äquivalent.
    "A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation." (ISO/IEC 9899:1999, 6.7.5.3-7)
    int main(int argc,char argv[])
    wird also so ausgewertet, als würde da
    int main(int argc,char
    * argv)
    stehen.



  • Ok danke!
    Das hat mir erstmal weiter geholfen.
    Thx a lot...
    😃


Anmelden zum Antworten