struktur "format argument is not a pointer"
-
Hallo,
ich habe folgenden Code vor mir, er ist nicht ansatzweise fertig, aber ich kann mir die Warnung im Titel nicht erklären...Der Code:
#include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct punkte Punkte; struct punkte { double x1; double y1; double x2; double y2; }; void cb() { int c=0; while((c=getchar()) != EOF || c != '\n') ; } void eingabe(Punkte *abc) { printf("\nx1 = "); scanf("%lf",abc->x1); cb(); return; } int main(void) { Punkte pts; printf("Berechnung von Punkten\n"); eingabe(&pts); return 0; }
ich will 4 Punkte in eine Struktur pts über die Funktion eingabe() einlesen...Dafür übergebe ich der Funnktion die Adresse der Struktur, speicher sie in *abc. wieso funktioniert das ganze wenn ich &abc->x1 schreibe, aber nicht wenn ich abc->x1 sag?! Ich habe doch einen Pointer übergeben und müsste somit den Adressoperator weglassen können...(ich schreibe ja auch -> )
Vielen Dank im Voraus, vielleicht bin ich grad auch einfach nur zu müde
-
struct Punkte {..};
Der Typ heißt "struct Punkte" - nicht "Punkte".
Du kannst ein Typedef benutzen, wenn es dir gefällt:
typedef struct Punkte Punkte;Heißt praktisch erstelle einen Neuen Typ namens Punkte aus dem Typ "struct Punkte".
-
ich habe in zeile 5:
typedef struct punkte Punkte;
sprich Punkte ist mein "Synonym". In Zeile 23 und 35 habe ich auch Punkte geschrieben (großer Buchstabe). Oder überseh ich da grad was?!
-
chmbw schrieb:
Dafür übergebe ich der Funnktion die Adresse der Struktur, speicher sie in *abc. wieso funktioniert das ganze wenn ich &abc->x1 schreibe, aber nicht wenn ich abc->x1 sag?! Ich habe doch einen Pointer übergeben und müsste somit den Adressoperator weglassen können...(ich schreibe ja auch -> )
abc ist ein Zeiger auf die Punkte-Struktur, hat also den Typ "Zeiger auf Punkte".
abc->x1 ist der (uninitialisierte) Wert von x1 in der Struktur (du musst "->" und nicht "." verwenden, eben weil abc ein Zeiger ist), hat also den Typ double.
&abc->x1 ist die Adresse von diesem x1, also Typ "Zeiger auf double". Die musst du an scanf übergeben. Der Adressoperator bezieht sich auf das ganze abc->x1 und nicht nur auf abc, weil (sozusagen) das -> eine höhere Operatorpräzedenz hat als & (postfix höher als unary).
-
hmm, ok, weil mein Problem war jetzt, wenn ich z.B. folgendes habe (nur eben zur veranschaulichung reingehackt):
void eingabe(*int ptr_a) { printf("eingabe bitte"); scanf("%i",ptr_a); return; } int main(void) { int a; eingabe(&a); return 0; }
sprich die Adresse von a an eingabe übergebe und dort mit scanf was einlese, dann lasse ich den Adressoperator weg weil ich ja einem pointer was zuweise.
namespace invader schrieb:
&abc->x1 ist die Adresse von diesem x1, also Typ "Zeiger auf double". Die musst du an scanf übergeben. Der Adressoperator bezieht sich auf das ganze abc->x1 und nicht nur auf abc, weil (sozusagen) das -> eine höhere Operatorpräzedenz hat als & (postfix höher als unary).
deshalb hab ich gedacht, da ich ja wieder einem Zeiger was zuweise, ich den Adressoperator weglassen müsste...
Viele Grüße
chmbw
-
Der -> Operator enthält ja eine Dereferenzierung, abc->x1 könntest du auch schreiben als (*abc).x1
Und die * und & Operatoren heben sich gegenseitig auf, z.B. ist &&*&a das selbe wie a. Dein Adressoperator in main wird also durch die Dereferenzierung aufgefressen, du brauchst deshalb für den scanf-Aufruf noch einen.
(Genaugenommen ist, da x1 das erste Element in der Struktur ist, abc und &abc->x1 ohnehin dasselbe; beides ist einfach ein Zeiger auf den Anfang des Strukturobjektes, nur mit anderem Typ. Du könntest also auch einfach abc an scanf übergeben, du musst es dazu nur auf den richtigen Typ casten, also
scanf("%lf", (double*)abc);
)
-
ahh, vielen vielen Dank, genau das war die Information die ich gebraucht habe :):):)