Wartezeit ... sleep()
-
Ok. Danke derweilen.
-
beginner88888 schrieb:
Das müsste dann Portabel UND Standardkonform sein?
Das ist weder portabel noch (nach dem C Standard) Standardkonform.
Aber es ist Windowsstandard und klappt unter jedem Rechner auf dem Windows läuft.
-
da fällt mir jetzt noch was ein, was ich für meine kleine "Grafik" brauchen könnte...
ich kann ja mit
printf("%10c", '#');
das # um 10 Stellen einrücken.
Kann man das 10 irgendwie durch eine Variable ersetzen? Damit könnte ich in einer Schleife vor und rückwerts "laufen" wenn ich die 10 verändern könnt....
-
Ja, das geht:
#include<stdio.h> int main() { int i; for (i = 0; i < 10; ++i) printf("%*c\n", i, '#'); }
Siehe Referenzen zu printf. printf (und auch scanf) kann allerlei tolle Dinge, von denen (leider) kaum jemand weiß.
-
Siehe Referenzen zu printf. printf (und auch scanf) kann allerlei tolle Dinge, von denen (leider) kaum jemand weiß.
...Das kannst du laut sagen. Ich hab ne grottenschlechte Referenz , da hab ich nix gefunden, aber ich war mir fast sicher das das geht.
Jetzt kann ich ein Quadrat zeichnen :-)) For Schleife und Printf . Hammer
-
ps... Meine Referenz ist soeben in den Müll gewandert
-
beginner88888 schrieb:
ps... Meine Referenz ist soeben in den Müll gewandert
Was war es denn? Allgemein hätte ich einer gedruckten Referenz sowieso nicht so wirklich getraut. Hier sind zwei gute Sammlungen:
http://www.cplusplus.com/reference/clibrary/
http://en.cppreference.com/w/c
Wobei die erste eigentlich eine C++-Referenz ist, die Referenz zum C-Teil der C++-Standardbibliothek ist aber bewusst möglichst kompatibel zu C gehalten. Aber auf die Namen der Header und eventuelle Hinweise aufpassen! Dafür ist sie viel ausführlicher als die zweite Referenz.
-
Danke. Meine gedruckte war von Markt und Technik, C und C++.
Mit der hatte ich bis jetzt nur sehr bescheidene Erfolge wenn ich etwas gesucht habe.
-
Also nachdem ich alles von gestern mit dem bisher "gelernten" bisschen zusammengepackt habe, will ich hier mal mein "Endergebnis" präsentieren.
Ich bitte über die 2 verwendeten system(tu was) hinweg zu sehen, das war nur noch ein kleines gimmick.
Bin auf die Kritik gespannt.
(Die Idee war es das Rechtek-zeichnen in die Teile "Daten init" , "Daten holen" und "Zeichnen" zu zerlegen. Und da sich alles auf das gleiche "Rechteck" bezieht habe ich mich entschlossen die Daten via Call by Referenze durchzureichen... Naja, das ist rausgekommen
)
Datei data.h
/* 'Global' Datas */ #define st 100 #define mt 150 #define lt 200 struct rectangle { char UDsides; char LRsides; int width; int height; } ;
Datei Help.h
#include <stdio.h> #include <stdlib.h> /*Help Functions*/ void keyb(); void nl(); void keyb() { 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; } }
"Init" :
#include <stdio.h> #include <stdlib.h> #include "data.h" void init(struct rectangle *sptr) { puts("*********start init.........") ; (sptr ->UDsides) = '0'; (sptr ->LRsides) = '0'; (sptr ->width) =0; (sptr ->height) =0; sleep(1000); nl(2); printf("%20s", "ooooooooo"); nl(2); printf(".........done************\n"); }
Getdata:
#include <stdio.h> #include <stdlib.h> #include "data.h" void getdata(struct rectangle *sptr) { puts("Enter the 'Signs' for the Upp & Down Line: "); (sptr->UDsides)= getchar(); keyb(); puts("Now enter the 'Signs' for the Left & Right Side: "); (sptr->LRsides) = getchar(); puts("Ok.. So now the width of the Rectangle: "); scanf("%d", &(sptr->width) ); puts("...Last... Enter the Height of the Rectanlge:"); scanf("%d", &(sptr->height) ); ((sptr->width) == (sptr->height) ) ? puts("you inserted 4 a Square :-)") : puts("Ok"); }
Paint :
#include <stdio.h> #include <stdlib.h> #include "data.h" void paint( struct rectangle *sptr) { int breite, hoehe; int index[5]={0}; char UD, LR; breite = (sptr->width); hoehe = (sptr->height); UD = (sptr->UDsides); LR = (sptr->LRsides); puts("So, here is your Rectangle: \n"); system("cls"); system("color 2"); for(index[1]=0; index[1] < breite; index[1]++) { printf("%c", UD); sleep(mt); if ( index[1]==(breite-1) ) { puts(""); for (index[2]=0; index[2] < (hoehe-1); index[2]++) { sleep(st); printf("%c%*c\n", LR, (breite-1), LR); } } } for (index[3]=breite; index[3] > 0; index[3]--) { sleep(lt); printf("%*c\r", index[3], UD); index[3]==1 ? printf("\n") : printf(""); } nl(2); puts("so.... this was your Rectangle"); }
und MAIN :
#include <stdio.h> #include <stdlib.h> #include "data.h" #include "help.h" int main(int argc, char *argv[]) { struct rectangle rec1; puts("Welcome . Let's draw a rectangle!!!"); init(&rec1); getdata(&rec1); paint(&rec1); system("PAUSE"); return 0; }
Irgendwie hab ich auch noch nicht so den Klammer-Style gefunden... Der braucht schon vieeel Platz.
So bin gespannt ....
-
- unsinnige Einrückungen/Klammerungen
- unsinniges system()
- unportables sleep
- Funktionsdefinitionen gehören nicht in eine .h
- for-Laufvariablen als int-Array sind masochistisch
- "void keyb();" Funktionsprototypen mit leerer Parameterliste sind unsinnig und bedeuten Fehlerverschleierung
- "(sptr->UDsides)" - unsinnige Klammerung
- #defines sollten signifikante Namen und in Großbuchstaben enthalten
- für die struct würde ich ein typedef spendieren
- in paint sollte der Parameter mit const deklariert bzw. nicht als Zeiger deklariert werden
- scanf-Rückgabewerte nicht ausgewertet
- Eingabepuffer nicht aufgeräumt
- ...Der main()-Aufbau ist soweit OK.
-
Hallo Wutz,
erstmal danke das du dir meinen "Müllhaufen" angesehen hast.Vielleicht können wir auf ein paar Sachen noch näher eingehen.
- unsinnige Einrückungen/Klammerungen
- unsinniges system()
- unportables sleep-Mit dem "Style" hab ich generell noch probleme, weiß noch nicht so wirklich wie ich am übersichtlichsten einrücke oder auch nicht.. Auch die Art wie ich meine Klammern setze...
-system war nur zum Bildschirm löschen und Farbe wechseln, das es etwa frischer auf der Konsole aussieht, das man das nicht verwenden soll weiß ich.
- eine Alternative zu sleep habe ich nicht gefunden. (da sich sleep bei einbinden der windows.h nicht viel anders verhält habe ich darauf verzichtet).Funktionsdefinitionen gehören nicht in eine .h
Wie sollte ich das dann machen, das ich mein keyb() und nl() (zugegeben , nicht dieee Wahnsinnsfunktionen) überall benutzen kann?
- for-Laufvariablen als int-Array sind masochistisch
Ich weiß, hab ich extra gemacht, wollte noch ein bisschen "Array" mit reinbringen. Mache ich normal nicht. (Tolle Ausrede :-)) )
- "void keyb();" Funktionsprototypen mit leerer Parameterliste sind unsinnig und bedeuten Fehlerverschleierung
ähh..??? Wie dann? also die Parameterliste ist hald mal leer, weils keine Parameter gibt. ?
"(sptr->UDsides)" - unsinnige Klammerung
Für mich nicht. Das macht es für mich auf anhieb leichter zu lesen.
Ich hab mir das auch in anderen Sprachen angewohnt, zb. wenn irgendetwas berechnet wir wie bei :(index[2]=0; index[2] < (hoehe-1); index[2]++)
die "Rechnung" , also (hoehe-1) immer in Klammern zu setzen.
Ist für mich persönlich so ok.- für die struct würde ich ein typedef spendieren
- in paint sollte der Parameter mit const deklariert bzw. nicht als Zeiger deklariert werdenstruct oder typedef... ok, kann man machen.
=> Warum die Parameter in paint mit const , bzw. NICHT als Zeiger??- scanf-Rückgabewerte nicht ausgewertet
- Eingabepuffer nicht aufgeräumtscanf ... war mir zuviel arbeit... Wollte schnell mein programm vom "Aufbau" präsentieren. Ich fange ja auch keine Fehleingaben oder dergleichen ab.
=> Eingabepuffer nicht aufgeräumt?? hä??Der main()-Aufbau ist soweit OK.
einen Punkt erreicht
Somit stehts 12 : 1 würde sagen "setzen 6"
Naja lieber harte Kritik als so "weiterwurschteln"...
-
beginner88888 schrieb:
- unsinnige Einrückungen/Klammerungen
-Mit dem "Style" hab ich generell noch probleme, weiß noch nicht so wirklich wie ich am übersichtlichsten einrücke oder auch nicht.. Auch die Art wie ich meine Klammern setze...
Im Prinzip ist es egal wie du es machst. Hauptsache du machst es durchgängig.
(Darüber werden Kriege geführt, da nur der jeweils eigene Stil der einzig Wahre ist.)
Schau mal bei http://de.wikipedia.org/wiki/Einr%C3%BCckungsstil Vielleicht ist einer für dich dabei.beginner88888 schrieb:
Funktionsdefinitionen gehören nicht in eine .h
Wie sollte ich das dann machen, das ich mein keyb() und nl() (zugegeben , nicht dieee Wahnsinnsfunktionen) überall benutzen kann?
Wie machst du es denn bei paint() und init() und getdata()?
Die Funktionsdefinition gehört in eine .c.
Die Funktionsdeklaration in eine .hbeginner88888 schrieb:
- "void keyb();" Funktionsprototypen mit leerer Parameterliste sind unsinnig und bedeuten Fehlerverschleierung
ähh..??? Wie dann? also die Parameterliste ist hald mal leer, weils keine Parameter gibt. ?
Dann kommt void in die Paramterliste.
void keyb(void);
-
void keyb();
deklariert eine Funktion ohne Rückgabewert und mit einer beliebigen unbekannten aber festen Anzahl Parameter (variable Parameterlisten passen hier also nicht),
d.h.void keyb();
passt für eine Vielzahl von Definitionen
void keyb(){} void keyb(int){} void keyb(int,int){} void keyb(int,int,int){} ...
und ist deswegen Unsinn. Werfe das Buch, das dir sowas zeigt weg, inkl. das "Wissen", das du dir daraus angeeignet hast.
-
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.)