einfaches c-Programm , Verständnisschwierigkeiten



  • Hallo, Danke D.A!

    Jetzt sind mir nur noch wenige Sachen unklar.

    1. Warum heißt der Datentyp "vector_t" ? Ich dachte er wird am Beginn als "vector" definiert, und anschließend wird eine Variable vector_t vom Typ vector angelegt.
      Doch da in späteren Funktionen immer vector_t steht wird die Struktur wohl so bezeichnet... was ist dann aber das "vector" in der ersten Zeile nach "typedef struct" ?

    2. Die von D.A angesprochene Zeile: A.e=( double*)malloc(A.nsizeof(double));
      Was mach hier das "(double
      )" am Beginn ? Der Speicher wird ja mit malloc zugewiesen oder? Und... A ist ja schon vom Typ vector_t oder, und dort ist A.e vom Typ double! Warum muss dann nochmals die Größe von double ausgelesen werden? Würde das nicht einfach mit A.e+=A.n* gehen oder so, vielleicht in einer for schleife???

    3. Wie werden hier (Eingabe der Elemente des Vectors) bei scanf die einzelnen Elemente voneinander getrennt?
      Es funktioniert nämlich sowohl mit Leerzeichen, als auch mit Zeilenumbruch?



  • @1: Der Typ heißt entweder 'struct vector' oder (aufgrund des typedef's) 'vector_t' (in C++ könntest du ihn auch als 'vector' ansprechen, aber du redest ja von C).

    @2: Das ist ein Cast, der den von malloc() gelieferten void* (Zeiger auf beliebige Daten) uminterpretiert in einen double* (Zeiger auf ein (Array von) double). Und A.e ist rein zufällig ein double*.
    (für einen vernünftigen C-Compiler ist dieser Cast übrigens nicht erforderlich - und versteckt nur mögliche tiefersitzende Fehler)

    @3: scanf() liest so lange weiter, bis das nächste Zeichen nicht mehr zur Formatkennung passt (und fast immer gelten Whitespaces (Leerzeichen, Tab, Enter) als Ende der aktuellen Eingabe).



  • Danke CStoll,

    Nur 2) ist mir noch nicht ganz klar.
    Wo ist hier ein void Zeiger ? A ist vom Typ vector_t, A.n vom Typ int und A.e vom Typ double.
    Ich hätte das so geschrieben: A.e=malloc(A.n*sizeof(A.e*));
    da ich dachte A.e ist ja schon vom Typ double, warum ist das falsch?

    Also was macht das (double*)? Wo ist hier der void-Zeiger?



  • Der void-Zeiger ist der Rückgabetyp von malloc und steht im Standard. Wie schon erwähnt brauchst Du, wenn Du ANSI-C machst, den Cast nicht, da in C ein void-Zeiger (etwa: "zeigt auf IRGENDWAS") in jeden anderen Zeiger umgewandelt werden darf. Deshalb ist auch Dein Beispiel nicht falsch (wenn man von dem Sternchen vor der schließenden Klammer hinten absieht).



  • gerhard schrieb:

    Danke CStoll,

    Nur 2) ist mir noch nicht ganz klar.
    Wo ist hier ein void Zeiger ? A ist vom Typ vector_t, A.n vom Typ int und A.e vom Typ double.

    A.e ist nicht vom Typ 'double' (Gleitkommazahl), sondern 'double*' (Zeiger auf Gleitkommazahl), das ist ein kleiner, aber bedeutender Unterschied. Und malloc() liefert einen void* (Zeiger auf irgendwelche Daten) zurück.

    Ich hätte das so geschrieben: A.e=malloc(A.n*sizeof(A.e*));
    da ich dachte A.e ist ja schon vom Typ double, warum ist das falsch?

    Ja, eigentlich wäre das so auch richtig (abgesehen von dem überflüssigen Sternchen am Ende). C++ Compiler sind bei dem Thema leider (oder "Gott sei dank") etwas empfindlicher als C Compiler - aber das Problem sollte man eigentlich nicht mit einem Cast lösen, sondern mit dem richtigen Compiler 😉



  • Das heißt ein "schlechter" Compiler übergibt dem A, obwohl es vom Typ vector_t ist nicht, dass A.e ein Zeiger vom Typ double ist.? Warum wird das dann bei der Festlegung der Struktur überhaupt reingeschrieben "double *e;" ,wenn es ohnehin nicht übergeben wird? Oder verstehe ich das jetzt falsch?

    Und warum muss dann A.n eigentlich nicht auch auf int gecastet werden?



  • Ok, da habe ich mich wohl vertan.

    Aber A.e ist also vom Typ Zeiger auf double.
    Der Cast macht aber doch auch nichts anderes oder?
    A.e bleibt doch ein Zeiger oder, der cast sagt nur, dass es ein Zeiger auf den Typ double sein (werden) soll...

    Das heißt das ganz ist nur wegen dem malloc() notwendig oder?
    Das nimmt dem A.e irgendwie seinen Typ weg, oder wie?



  • A.e ist ein double*, aber malloc() liefert nunmal keine double* (weil jede Funktion einen eindeutig definierten Rückgabetyp besitzen muss und malloc() auch für andere Typen klappen soll), sondern einen void*.

    void* wiederum ist ein Zeiger auf beliebige Daten. Laut ANSI C ist es absolut legal, einem double* einen void* zuzuweisen (also A.e=malloc(A.n*sizeof(double)); , unter C++ ist diese Zuweisung im Sinne der Typsicherheit verboten wurden, weshalb man "hier"* den von malloc() gelieferten Zeiger in den richtigen Typ casten muß.

    * mit "hier" meine ich C++-Programme oder C-Programme, die durch einen C++ Compiler gejagt werden - aber im ersten Fall sollte man lieber new nehmen und im zweiten Fall einen echten C Compiler 😉



  • Vielen Dank, das hat mir wirklich sehr geholfen!

    Jetzt verstehe ich das Programm!



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum ANSI C verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten