Wartezeit ... sleep()
-
Danke euch beiden!
Wenn ich das mit den Funktionsdeklarationen richtig verstanden habe, sollte es dann so aussehen: ?data.h
/* 'Global' Datas */ #define st 100 #define mt 150 #define lt 200 struct rectangle { char UDsides; char LRsides; int width; int height; } ; void keyb(void); void nl(int);
help.c
#include <stdio.h> #include <stdlib.h> #include "data.h" void keyb(void) { int c; while ((c = getchar()) != EOF && c != '\n'); } /*************************************************************/ void nl(int anzahl) { switch (anzahl) { case 1 : puts("\n"); break; case 2 : puts("\n\n"); break; case 3 : puts("\n\n\n"); break; case 4 : puts("\n\n\n\n"); break; default : puts("\n\n\n\n\n"); break; } }
und in Main.c
#include <stdio.h> #include <stdlib.h> #include "data.h" int main(int argc, char *argv[]) { struct rectangle rec1; bla bla bla
Evtl. eins noch:
- in paint sollte der Parameter mit const deklariert bzw. nicht als Zeiger deklariert werden
Das versteh ich nicht wirklich.
-
beginner88888 schrieb:
Evtl. eins noch:
- in paint sollte der Parameter mit const deklariert bzw. nicht als Zeiger deklariert werden
Das versteh ich nicht wirklich.
void paint( struct rectangle *sptr)
Lassen wir mal alles Ablenkende weg:
void foo1(int* parameter);
vs.
void foo2(const int* parameter);
vs.
void foo3(int * const parameter);
vs.
void foo4(const int* const parameter);
vs.
void bar1(int parameter);
vs.
void bar2(const int parameter);
Welche der folgenden Aufrufe sind erlaubt, welche nicht? Warum? Was schlussfolgerst du?
int i=3; const int j=4; #define k 5 foo1(&i); foo1(&j); foo1(&k); foo2(&i); foo2(&j); foo2(&k); foo3(&i); foo3(&j); foo3(&k); foo4(&i); foo4(&j); foo4(&k); bar1(i); bar1(j); bar1(k); bar2(i); bar2(j); bar2(k);
-
Wow, das ist jetzt heftig.
Ich versuchs mal:bar1(i) müsste gehen, da bar1 einfach nur nen int will.
bar1 mit j oder k .... könnte vielleicht gehen, sollte aber nicht so sein da Konstanten übergeben werden.bar2 wäre dann umgedreht, geht nur mit j und k da konstant.
foo1 : parameter ist ein Zeiger auf Int. Bin unschlüßig . i geht auf jeden Fall, j und k nicht da ich Konstanten nicht ändern kann , also auch nicht by refernece übergeben darf / kann...
foo2: parameter ist ein Zeiger auf Konstanten Int. j und k gehen. i ... vielleicht ? müsste ich probieren. sollte aber nicht so sein.
foo3: jetzt wird´s schon beim verstehen interessant...
Ist Parameter eine Konstante die auf einen Int zeigt? Dann würde ich wider sagen j und k geht.foo4 : ich hab keine Ahnung. Versuche das Rückwerts zu lesen und zu interpretieren... da kommt aber nix bei mir raus.
schätze wieder "setzen sechs"
-
In paint verwendest du das Argument nur lesend; genau diese Tatsache kannst du den Compiler prüfen lassen, wenn du ihm genau diesen Hinweis gibst:
paint( const struct bla *z ); oder paint( const struct bla w );
Wenn du jetzt nämlich auf die Idee kommst, das Argument innerhalb von paint zu verändern (z.B. durch Zuweisungen), gibts vom Compiler was auf die Finger (nicht immer, aber viele Compiler warnen hier).
error: assignment of member '...' in read-only object
Du forcierst also, dass der Compiler dir deine Fehler anzeigt; was gibt es besseres?
Nebenbei bemerkt, kann ein Compiler mit solchen Zusatzinfos auch besser/einfacher optimieren.
-
Wutz schrieb:
- Eingabepuffer nicht aufgeräumt
wie kann ich in c den eingabepuffer aufräumen?
-
@ Wutz : Ok, danke . Das leuchtet ein . Das include mit meinen Datein passt jetzt?
@puff0r : Die Frage wird erst beantwortet wenn du SeppJ's Aufgabe löst :-)))
-
beginner88888 schrieb:
Wow, das ist jetzt heftig.
Ich versuchs mal:bar1(i) müsste gehen, da bar1 einfach nur nen int will.
Ja, das war noch einfach.
bar1 mit j oder k .... könnte vielleicht gehen, sollte aber nicht so sein da Konstanten übergeben werden.
Nein. Da hast du nicht verstanden, was Funktionsparameter und/oder Konstanten sind. Funktionsparameter sind Kopien der Argumente. Eine Konstante kann natürlich auch mit der Kopie eines variablen Wertes initialisiert werden und umgekehrt. Dies hier ist doch auch kein Problem:
int i = 2; const int j = i; int k = j;
bar2 wäre dann umgedreht, geht nur mit j und k da konstant.
Nein, siehe oben. Das ganze const direkt auf den Funktionsparametern ist völlig irrelevant. Das hat bloß Einfluss darauf, ob man den Wert innerhalb der Funktion ändern kann oder nicht. Das ist aber ein internes Details der Funktion, dass den Aufrufer nicht interessieren braucht, daher ist der übliche Stil, hier nichts const zu machen.
foo1 : parameter ist ein Zeiger auf Int. Bin unschlüßig . i geht auf jeden Fall, j und k nicht da ich Konstanten nicht ändern kann , also auch nicht by refernece übergeben darf / kann...
Korrekt. Über den int-Zeiger könntest du den Wert ändern, auf den der Zeiger zeigt. Daher muss dieser Wert änderbar sein. Daher kann man aus einem Zeiger auf eine Konstante keinen Zeiger auf eine Variable machen, umgekehrt aber schon. Denn sonst könnte man Konstanten ändern. Eine Variable nicht zu ändern ist aber natürlich kein Problem.
foo2: parameter ist ein Zeiger auf Konstanten Int. j und k gehen. i ... vielleicht ? müsste ich probieren. sollte aber nicht so sein.
Siehe oben. Natürlich ist es erlaubt, einen Zeiger auf eine Variable als einen Zeiger auf eine Konstante aufzufassen. Das heißt ja nur, dass man den Wert der Variablen nicht über diesen Zeiger ändern kann.
foo3: jetzt wird´s schon beim verstehen interessant...
Ist Parameter eine Konstante die auf einen Int zeigt?Ja, der Zeiger ist hier die Konstante. Regel: Von rechts nach links lesen (geht besser auf Englisch, aber auf Deutsch passt es auch halbwegs).
int * const p;
: Deklariere p als konstanten Zeiger auf int.
const int * p;
: Deklariere p als Zeiger auf einen int, der const ist.
int const * p;
: Deklariere p als Zeiger auf einen konstanten int.
Ja, das heißt, die letzten beiden sind das gleiche.
Siehe auch
http://cdecl.ridiculousfish.com/Dann würde ich wider sagen j und k geht.
Wieder falsch. Die Antwort ist nicht einmal konsistent zu den falschen Antworten zu foo1 und foo2. Du hast doch schon erkannt, dass das const sich auf den Zeiger bezieht (so wie bei bar2), das ändert doch nichts da dran, wo drauf er zeigen darf.
foo4 : ich hab keine Ahnung. Versuche das Rückwerts zu lesen und zu interpretieren... da kommt aber nix bei mir raus.
Schätze wieder "setzen sechs"
Ich fürchte, ja.
@puff0r : Die Frage wird erst beantwortet wenn du SeppJ's Aufgabe löst :-)))
Für Leute, die ihr C-Wissen testen wollen, hätte ich noch folgende (nicht sehr schwere, aber interessante) Zusatzaufgabe: Wieso geht folgendes nicht?
void foo(const int **bar); int main() { int **p; foo(p); // WTF? Wieso darf ich keinen non-const an const übergeben? }
(Mögen manche Compiler schlucken, sollten aber wenigstens warnen. Spätestens ein strengerer C++-Compiler würde einen Fehler daraus machen.)
-
void foo3(int * const parameter); void foo4(const int* const parameter);
int i=3; const int j=4; #define k 5 foo1(&i); foo1(&j); foo1(&k); foo2(&i); foo2(&j); foo2(&k); foo3(&i); foo3(&j); foo3(&k); foo4(&i); foo4(&j); foo4(&k); bar1(i); bar1(j); bar1(k); bar2(i); bar2(j); bar2(k);
hmm...
bar1 : ich kann i j und k übergeben. Es wird nur festgelegt das ein Int "kommt"
bar2 : ich kann i j und k übergeben. Ich kann keinen dieser Werte in der Funktion änder , zb.: parameter+=3 geht nicht da "read only"
foo1: ich kann i ohne Probleme übergeben. j gibt ne compiler warnung, da ich j verändern könnte obwohl es eine const ist . (Funktioniert aber).
Ich kann k nicht übergeben da es keine richtige Adresse hat. (Weiß jetzt nicht wie ich das beschreiben soll);foo2: parameter ist ein zeiger auf nen konstanten int(?). ich kann i und j übergeben. k geht nicht. ich kann i und j nicht ändern in der funktion
foo3: parameter ist ein konstanter zeiger auf einen Int. ich kann i und j übergeben , k wieder nicht, ich kann i und j aber nicht ändern. bei j motzt der compiler weil der typ nicht passt.
foo4: parameter ist ein konstanter zeiger auf einen konstanten int.
ich kann i und j übergeben. k ist raus. ich kann i und j nicht ändern.Ich hab keinen plan mehr ob´s jetzt besser oder schlechter geworden ist.
Mir raucht der Schädel.// http://cdecl.ridiculousfish.com/ komm ich nicht wirklich klar. glaub ich mach da was falsch? bei ner eingabe von z.B. void foo(int *p) kommt nur Syntax Error... Egal
-
Wesentlich besser. Nur bei foo3 ist noch ein Fehler, ich bin mir nicht einmal sicher, ob es nicht bloß ein Schreibfehler ist:
foo3: parameter ist ein konstanter zeiger auf einen Int. ich kann i und j übergeben , k wieder nicht, ich kann i und j aber nicht ändern. bei j motzt der compiler weil der typ nicht passt.
Der Zeiger selbst ist konstant, du kannst ihn nicht auf etwas anderes zeigen lassen. Aber das wo drauf er zeigt (i, j) ist nicht konstant und kann über den Zeiger geändert werden.
// http://cdecl.ridiculousfish.com/ komm ich nicht wirklich klar. glaub ich mach da was falsch? bei ner eingabe von z.B. void foo(int *p) kommt nur Syntax Error... Egal
Das ist nur für Variablen, keine kompletten Funktionen. Zum Beispiel:
http://cdecl.ridiculousfish.com/?q=const+int+*+const+p
oder
http://cdecl.ridiculousfish.com/?q=declare+p+as+constant+pointer+to+constant+int
(Den ersten Link musst du von Hand Copy&Pasten, da die Forensoftware nicht mit Sternchen in Links zurecht kommt)
-
zu foo3 : ja, so meinte ich das. Der Zeiger ist konstant. Ich kann i und j ändern, bei j motzt mein compiler dann weil das "ziel" const ist. Es geht aber.
Einigen wir uns auf ne 4- durch nacharbeit , und nochmal nachsitzen bei den Const Kaiteln
Danke nochmal. Hat heute wieder einiges gebracht.
http://cdecl.ridiculousfish.com ...jetzt auch gecheckt, ist gar nicht schlecht wenn man weis wie´s funktioniert.
-
Die "Aufgabe" von SeppJ wäre noch offen
C: void foo(const int **bar); int main() { int **p; foo(p); // WTF? Wieso darf ich keinen non-const an const übergeben? }
ich bin eigentlich raus, mit "Doppelzeiger" hab ich mich noch nicht befasst.
Allerdings stelle ich jetzt mal ne "These" auf, basierend auf Sachen die ich ihier im Forum schon mal kurz gelesen habe.
Werden mit ** nicht auch "zweidimensionale oder mehrdimensionale" Arrays übergeben? (Wenn nein, sind die nächsten Zeilen sowieso Schrott)
... Kann es sein das dann ein Const übergeben werden muss wegen der "Größe"?
Man möge mich bitte nicht steinigen
-
Du kannst mit Doppelzeigern zweidimensionale Strukturen übergeben, aber nicht das, was man normalerweise unter einem 2D-Array versteht. Da bekommt man nämlich tatsächlich Probleme mit den Größenangaben. Das hat aber nichts mit dem const zu tun.
Ich nehme mal an, für die anderen ist die Aufgabe zu einfach, daher schreibt niemand eine Lösung. Ich mache es dir mal vor:
const char konstante[] = "abc"; void foo(const char** parameter) { *parameter = // Das wo drauf parameter zeigt ist nicht const, das dürfen wir ändern konstante; // Und so können wir das, wo drauf parameter zeigt auf die Konstante abc zeigen lassen. // Das ist vollkommen ok, wir geben einem const char* (das, wo drauf parameter zeigt) einen neuen Wert. } int main() { char *non_const_char_pointer; char **bar = &non_const_char_pointer; foo(bar); // Angenommen, wir dürften dies so machen // Dann wird das, wo drauf bar zeigt, also non_const_char_pointer, // von foo verändert. // Das heißt, non_const_char_pointer zeigt nun auf die Konstanten "abc" // Der Pointer ist aber von einem Typ, der Veränderung der Objekte erlaubt: non_const_char_pointer[0] = 'x'; // Autsch, nun haben wir eine Konstante geändert! }
-
puff0r schrieb:
Wutz schrieb:
- Eingabepuffer nicht aufgeräumt
wie kann ich in c den eingabepuffer aufräumen?
beginner88888 schrieb:
@puff0r : Die Frage wird erst beantwortet wenn du SeppJ's Aufgabe löst :-)))
du kannst ruhig sagen wenn du das nicht weißt, ist doch nicht schlimm!
sonst jemand ne idee, wie ich den puffer aufräumen tu?
-
du kannst ruhig sagen wenn du das nicht weißt, ist doch nicht schlimm!
Genau das wollte ich mit
@puff0r : Die Frage wird erst beantwortet wenn du SeppJ's Aufgabe löst :-)))
sagen
Du kannst mit Doppelzeigern zweidimensionale Strukturen übergeben, aber nicht das, was man normalerweise unter einem 2D-Array versteht. Da bekommt man nämlich tatsächlich Probleme mit den Größenangaben. Das hat aber nichts mit dem const zu tun.
Ich nehme mal an, für die anderen ist die Aufgabe zu einfach, daher schreibt niemand eine Lösung. Ich mache es dir mal vor:
const char konstante[] = "abc"; void foo(const char** parameter) { *parameter = // Das wo drauf parameter zeigt ist nicht const, das dürfen wir ändern konstante; // Und so können wir das, wo drauf parameter zeigt auf die Konstante abc zeigen lassen. // Das ist vollkommen ok, wir geben einem const char* (das, wo drauf parameter zeigt) einen neuen Wert. } int main() { char *non_const_char_pointer; char **bar = &non_const_char_pointer; foo(bar); // Angenommen, wir dürften dies so machen // Dann wird das, wo drauf bar zeigt, also non_const_char_pointer, // von foo verändert. // Das heißt, non_const_char_pointer zeigt nun auf die Konstanten "abc" // Der Pointer ist aber von einem Typ, der Veränderung der Objekte erlaubt: non_const_char_pointer[0] = 'x'; // Autsch, nun haben wir eine Konstante geändert! }
Kann leider nicht sagen "Alles Klar", da ich wie gesagt mit Doppelzeiger noch nix am Hut habe, das Prinzip habe aber verstanden. Danke.