einfaches c-Programm , Verständnisschwierigkeiten
-
ist mein Post noch wo zu finden?
-
Keiner deiner beiden Threads wurde gelöscht. Lediglich der im C-Forum wurde geschlossen. Vielleicht einfach mal eine Seite zurückblättern?
-
stimmt...
kann mir vielleicht noch jeman helfen das zu verstehen. Diese Zeile verstehe ich nicht:
double abssum(vector_t *x)wird hier x ein Zeiger auf vector_t, nur das von allen Einträgen der Absolutbetrag genommen wird? was soll das doulbe, und warum ein Zeiger?
-
gerhard schrieb:
stimmt...
kann mir vielleicht noch jeman helfen das zu verstehen. Diese Zeile verstehe ich nicht:
double abssum(vector_t *x)wird hier x ein Zeiger auf vector_t, nur das von allen Einträgen der Absolutbetrag genommen wird? was soll das doulbe, und warum ein Zeiger?
Funktionen haben i.d.R. einen Rückgabewert, wenn nicht, dann steht da void vor.
Die Funktion abssum gibt einen double Wert zurück.
Der Übergabeparamater ist ein Zeiger auf vector_t.
Zeiger als Parameter in Funktionen werden übergeben, wenn das Objekt auf den dieser Zeiger zeigt, geändert werden soll, oder wenn man vermeiden möchte, das die übergebenen Parameter kopiert werden( Zeitgewinn ).Würde also in der Klammer (vector_t x) anstelle von (vector_t *x) stehen,
dann würde jedesmal die komplette Struktur die übergeben wird, kopiert und in die Variable x geschrieben werden. Das macht das System nämlich intern, automatisch.
Da aber die Variable x ein Zeiger ist, wird nur ein einziger Wert übergeben, nämlich die Adresse der Struktur.In der Funktion vector_ein wird dynamisch Speicherplatz für ein double array erzeugt, welches in der Struktur A vom Typ vector_t ist.
In der for-Schleife dieser Funktion wird dieser Speicherplatz mit den eingegebenen Werten belegt, dann wird die Struktur A zurückgegeben.Die Funktion abssum berechnet die Summe aller dieser eingegebenen double Werte.
Im Programm fehlt noch die Freigabe des mit malloc reservierten Arbeitsspeichers.
MfGD.A.
-
Hallo, Danke D.A!
Jetzt sind mir nur noch wenige Sachen unklar.
-
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" ? -
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??? -
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.