Erstes Programm: "Laufzeit"fehler und Projektidee
-
regInfo000? schrieb:
.exe-Dateien sind natürlich dafür da, durch einen Doppelklick vom Anwender geöffnet zu werden, und das ohne vorherige Installation.
Ihr scheint das Wort "einfach" noch nicht zu verstehen.
Wie DirkB schon beschrieben hat, kommt das sehr auf das Programm an. Wenn es nur durchläuft, eine Ausgabe produziert und dann terminiert, wirst Du die Ausgabe nie zu sehen bekommen.
Aber wenn Du schon alles so gut weißt, wie das hier klingt ... wieso stellst Du dann überhaupt noch irgendwelche Fragen?
-
So, ich weiß selbstverständlich, wie man die Konsole benutzt, denn ich kompiliere ja C-Programmtext darüber.
Später ist es nervig, ein Programm immer über cmd.exe aufrufen zu müssen, bzw., wenn es nach der Eingabe sofort wieder schließt.
Jetzt habe ich ein paar weitere Fragen und so etwas hier geschrieben:
/* * Kommentar */ #include <limits.h> #include <stdio.h> #include <stdlib.h> typedef unsigned char char255; /* 0..255 */ int swap(int *hahaha, int *b); int main(void) { int a, b; printf("!!Hello World!!\n"); printf("Bitte a und b (Ganzzahl) eingeben: "); scanf("%i %i", &a, &b); printf("a=%i, b=%i\n", a, b); printf("a + b = %i\n", a + b); printf("a - b = %i\n", a - b); printf("a * b = %i\n", a * b); printf("a / (b | 1) = %i\n", a / (b | 1)); printf("a % (b | 1) = %i\n", a % (b | 1)); printf("b << 1 = %i\n", b << 1); printf("b >> 1 = %i\n", b >> 1); swap(&a, &b); printf("a=%i, b=%i\n", a, b); printf("a + b = %i\n", a + b); printf("a - b = %i\n", a - b); printf("a * b = %i\n", a * b); printf("a / (b | 1) = %i\n", a / (b | 1)); printf("a % (b | 1) = %i\n", a % (b | 1)); printf("b << 1 = %i\n", b << 1); printf("b >> 1 = %i\n", b >> 1); printf("b | 1 << sizeof(1) * 8 - 1 = %i\n", b | 1 << sizeof(1) * 8 - 1); getchar(); getchar(); return EXIT_SUCCESS; } int swap(int *a, int *b) { *a ^= *b ^= *a; return 1; }
C:\Users\MyName\Desktop>%gcc% HelloWorld.c HelloWorld.c: In function 'main': HelloWorld.c:40:2: warning: suggest parentheses around '-' inside '<<' [-Wparent heses] printf("b | 1 << sizeof(1) * 8 - 1 = %i\n", b | 1 << sizeof(1) * 8 - 1); ^ C:\Users\MyName\Desktop>HelloWorld.exe !!Hello World!! Bitte a und b (Ganzzahl) eingeben: 123 234 a=123, b=234 a + b = 357 a - b = -111 a * b = 28782 a / (b | 1) = 0 a % (b | 1) = 123 b << 1 = 468 b >> 1 = 117 a=234, b=145 a + b = 379 a - b = 89 a * b = 33930 a / (b | 1) = 1 a % (b | 1) = 89 b << 1 = 290 b >> 1 = 72 b | 1 << sizeof(1) * 8 - 1 = -2147483503 C:\Users\MyName\Desktop>
Er warnt, in Zeile 40 zu wenige runde Klammern gesetzt zu haben. Die Rangfolge der Operatoren habe ich einfach mal hierher entnommen: http://www.imb-jena.de/~gmueller/kurse/c_c++/c_operat.html , dort steht, dass der nicht geklammerte Ausdruck meiner Intention entspricht.
-
Wie sollte geklammert werden?
-
sizeof(1) , sizeof(b) oder sizeof(int) verwenden? (1 | 1 << sizeof(1) * 8 - 1 entspricht bei mir -(2^31)+1, das ist also korrekt.)
-
int swap(int *hahaha, int *b); funktioniert nicht richtig. Ich habe mir nur a b a gemerkt, was ist an dem swap abgesehen des returns falsch?
-
Kennt ihr eine Seite, auf der "typedef struct" gut erklärt wird?
( 5) Kennt jemand eine [url=Nichtproportionale Schriftarten (Dickten-/Festbreitschrift)]http://de.wikipedia.org/wiki/Liste_von_Schriftarten#Nichtproportionale_Schriftarten_.28Dickten-.2FFestbreitschrift.29[/url], die nicht so viel Platz wie "Courier New" benötigt? )
-
-
Wenn du nu nicht den Kernighan willst:
http://openbook.galileocomputing.de/c_von_a_bis_z/Setze Klammern immer, auch wenn die Assoziativität deiner "Intention" entspricht. Ist besser lesbar und eindeutig. Wie das geht, weißt du doch sicher noch aus dem Mathe-Unterricht aus der 6. Klasse?
(Ich hoffe ja, du willst nicht beruflich programmieren...)
-
regInfo000? schrieb:
int swap(int *a, int *b) { *a ^= *b ^= *a; return 1; }
- int swap(int *hahaha, int *b); funktioniert nicht richtig. Ich habe mir nur a b a gemerkt, was ist an dem swap abgesehen des returns falsch?
Es fehlt noch eine weitere Zuweisung an *b.
Abgesehen führt diese Schreibweise zu undefiniertem Verhalten (es sei denn, es wird ein C++11-Compiler eingesetzt).
Dieses swap ist destruktiv, wenn ein Objekt mit sich selbst geswapped wird, ausserdem ist es (mit modernen Prozessorarchitekturen, es sei denn der Compiler ist sehr schlau) weniger effizient als normales 3-Wege-swap.Korrekt wäre
int swap(int *a, int *b) { *b ^= *a; *a ^= *b; *b ^= *a; return 1; }
-
fibeline schrieb:
(Ich hoffe ja, du willst nicht beruflich programmieren...)
Doch, das möchte ich später mal machen.
Ich hab' jetzt mal eine Personalverwaltung wie folgt geschrieben:
/* * Kommentar */ #include <limits.h> #include <stdio.h> #include <stdlib.h> enum Bereich { Management=30, Entwicklung=10, Produktion=1, Marketing=2, Vertrieb=1 }; typedef struct { char *name; char *vorname; unsigned int personalNummer; enum Bereich abteilung; float gehalt; } Angestellter; Angestellter angestellte[10] = { { "aab", "aaa", 111, Vertrieb, 1111 }, { "bbc", "bbb", 222, Marketing, 2222 }, { "ccd", "ccc", 333, Produktion, 3333 }, { "dde", "ddd", 444, Entwicklung, 4444 }, { "Pan", "Peter", 555, Management, 9999 } }; double durchschnitt(void) { int i = 0; double d = 0.0; for (; i < 10; i++) { d += angestellte[i].gehalt; } return d / 10.0; } void erhoeheGehalt(void) { int i = 0; for (; i < 10; i++) { Angestellter *a = &angestellte[i]; a->gehalt *= a->abteilung / 100.0 + 1.0; } } void drucke(Angestellter *ang) { printf("%-10s%-10s%10i%10d%15f\n", (*ang).vorname, (*ang).name, (*ang).personalNummer, (*ang).abteilung, (*ang).gehalt); } void druckeAlle(void) { int i = 0; for (; i < 10; i++) { drucke(&angestellte[i]); } } int main(void) { /* int a, b; */ druckeAlle(); printf("durchschnitt() = %f\n", durchschnitt()); erhoeheGehalt(); printf("durchschnitt() = %f\n", durchschnitt()); druckeAlle(); getchar(); return EXIT_SUCCESS; }
Wie schreibe ich das ganze Ding jetzt so um, das ich 10 Array-Elemente oder ein dynamisch/es (wachsendes) Array/Feld benutzen kann?
-
Wie scanf richtig benutzen?
-
4444.0F * (10 / 100.0 + 1.0) sollte 4888,4 ergeben, ergibt bei mir aber 4888,399902. Wie runde ich oder rechne genauer?
-
Wie bekomme ich so eine schöne enum-Ausgabe hin, d. h., das da steht "Marketing" usw. usf. etc. pp.?
Danke für eure Mitarbeit
-
-
regInfo000? schrieb:
Wie schreibe ich das ganze Ding jetzt so um, das ich 10 Array-Elemente
Sie erstmal zu, dass du die 5 vorhandenen richtig benutzt.
Im Augenblick rechnest du mit Phantomdaten aus den Inizes 5 bis 9regInfo000? schrieb:
oder ein dynamisch/es (wachsendes) Array/Feld benutzen kann?
mit Zeigern und malloc
regInfo000? schrieb:
- Wie scanf richtig benutzen?
Referenz lesen und bei Problemen fragen.
regInfo000? schrieb:
- 4444.0F * (10 / 100.0 + 1.0) sollte 4888,4 ergeben, ergibt bei mir aber 4888,399902. Wie runde ich oder rechne genauer?
double nehmen. Bei Geldbeträgen rechnest du besser mit Ganzzahlen in Cent.
regInfo000? schrieb:
- Wie bekomme ich so eine schöne enum-Ausgabe hin, d. h., das da steht "Marketing" usw. usf. etc. pp.?
Selber machen. (mit Array oder switch/case ...)
-
Gut, danke erst mal.
@DirkB: Warum meldest du dich denn hier nicht an (Registrierung), dann hast du doch sicherlich einige Vorteile, oder wurdest du in der vergangenheit mal "durch unfreundliches Verhalten vergrault/vertreiben"?
Um auf dieser Ebene zu bleiben, und weil ich das andere Thema bzgl. Strings gelesen habe,
wie kann ich ein/e String-Konstante/Literal verändern, oder wie lege ich veränderbare Zeichenketten in C an? Wie umgehe ich, dass String-Literale nicht während der gesamten Programmlaufzeit auf dem Stack, virtuellen Speicher, RAM/Festplatte o. Ä. liegen?
Danke auch an dieser Stelle
-
regInfo000? schrieb:
wie kann ich ein/e String-Konstante/Literal verändern,
Verändern und Konstante widersprechen sich.
regInfo000? schrieb:
oder wie lege ich veränderbare Zeichenketten in C an?
Array oder dynamischer Speicher (malloc)
Du kannst bei der Definition von einem Array auch gleich ein Wert/Inhalt zuweisen.regInfo000? schrieb:
Wie umgehe ich, dass String-Literale nicht während der gesamten Programmlaufzeit auf dem Stack, virtuellen Speicher, RAM/Festplatte o. Ä. liegen?
Gar nicht. Irgendwo muss die Information stehen.
-
Wie schreibe ich "dies ist ein Täxt" in ein char []? (Sobald ich " " verwende, wird intern doch eine programmlebenslängliche Konstante angelegt, oder?)
-
regInfo000? schrieb:
Wie schreibe ich "dies ist ein Täxt" in ein char []? (Sobald ich " " verwende, wird intern doch eine programmlebenslängliche Konstante angelegt, oder?)
char foo[] = "ab";
Ist das Gleiche wie:
char foo[] = { 'a', 'b', '\0'};
Da wird keine Konstante erstellt.
-
int bar(char *text) { char foo[10] = "ab"; //mach etwas mit foo }
Beim Auruf der Funktion wird dann "ab" in das Array kopiert. Es steht also irgendwo im Speicher.
Wie willst du das verhindern? Bzw. was stört dich daran?
-
Sind Arrays automatische Variablen? Angenommen, ich lese eine mehrere mb Datei ein, möchte nach char [] oder char * "konvertieren", aber nicht sämtlichen Virtuellen Speicher benutzen..
In Java ist das ganz einfach gewesen, Datei Zeile für Zeile lesen, "verarbeiten", Block/Gültigkeitsbereich/Scope verlassen oder Variable auf null setzen, und beim nächsten Durchlauf des GCs wird aufgeräumt..
Siehe hier: http://de.wikipedia.org/wiki/Variable_(Programmierung)#Sichtbarkeitsbereich_von_Variablen_.28Scope.29
- Sind Structs oder sind deren Variablen automatische Variablen?
-
Ja, Arrays sind automatische Variablen,
Automatische Variablen werden beim verlassen des Scopes, in dem sie definiert wurden, ungültig.Arrays kann man nach ihrer Definition nicht in der Größe ändern oder einen anderen Speicherplatz zuweisen. (sie wachsen nicht dynamisch - auch nicht statisch)
Darum gibt es auch keine GC.Bei dynamischen Speicher sieht da anders aus. Aber da bist du (als Programmierer) für die Anforderung und Freigabe zuständig. Darum gibt es auch keine GC.*
Ja, auch structs sind automatische Variablen (im Prinzip alles was einen Namen hat und Speicherplatz anbietet).
Speicher von malloc hat keinen Namen, Stringliterale auch nicht.
Ein Array hat einen Namen.*Mag sein das freie benachbarte Speicherblöcke wieder zusammengefasst werden.
-
Ok, ich hab' jetzt mal einen Binärbaum ohne löschen/Remove geschrieben, um malloc und struct kennenzulernen:
/* * Kommentar */ #include <limits.h> #include <stdio.h> #include <stdlib.h> typedef struct Node { char str[20]; struct Node *left; struct Node *right; } Node; Node *tree = NULL; void cop1(char str[], Node *nod) { int i; for (i = 0; str[i] != '\0' && i < 19; i++) nod->str[i] = str[i]; nod->str[i] = '\0'; nod->left = NULL; nod->right = NULL; } void add1(char str[], Node *nod) { if (nod->left == NULL || nod->right == NULL) { Node *newNod = (Node *) malloc(sizeof(Node)); cop1(str, newNod); if (nod->left == NULL) nod->left = newNod; if (nod->right == NULL) nod->right = newNod; return; } if (rand() % 2 == 0) add1(str, nod->left); else add1(str, nod->right); } void add(char str[]) { if (tree == NULL) { tree = (Node *) malloc(sizeof(Node)); cop1(str, tree); return; } add1(str, tree); } void printTree1(int ebe, Node *nod) { if (nod == NULL) return; printf("%-5i%s%p%p\n", ebe, nod->str, nod->left, nod->right); ebe++; printTree1(ebe, nod->left); printTree1(ebe, nod->right); } void printTree(void) { printTree1(1, tree); } int main(void) { int i; int array[10]; /* Deklaration */ int *pointer1, *pointer2; pointer1 = array; /* pointer1 auf Anfangsadresse von array */ pointer2 = array + 3; /* pointer2 auf 4.Element von array */ array[0] = 99; /* array[0] */ pointer1[1] = 88; /* array[1] */ *(pointer1+2) = 77; /* array[2] */ *pointer2 = 66; /* array[3] */ for (i = 0; i < 10; i++) printf("%5i\n", array[i]); add("eins"); add("Zwei"); add("drei"); add("Vier"); add("fuenf"); add("Sechs"); add("sieben"); add("Acht"); add("neun"); add("Sehr laaannngggeeer String/Zeichenkette!!"); printTree(); getchar(); return EXIT_SUCCESS; }
Der BinTree wird zufällig befüllt (damit entsteht auch keine Liste).
-
Warum muss ich typedef struct Node .... Node schreiben? Dieses Node ist doppelt. Aber ohne müsste ich immer (struct Node
schreiben, wieso?
-
Die Ausgabe (Wurzel-Links-Rechts / dfs) dreht total durch bei mir, was habe ich vergessen?
-
Ist string copy richtig, wenn ich in der Struct immer Zeichenketten mit genau 20 Zeichen (inklusive '\n') haben möchte?
-
Wieso kann ich
struct Node *left = NULL;
nicht schreiben? -
Wie kann ich relativ einfach eine Breitensuche hinbekommen?
Danke noch mal für Antworten
PS. Zeile 65 bis 74 habe ich einer anderen Quelle (c_von_a_bis_z) entnommen und gehört eig. nicht zum Programm. (Nicht verwirren lassen)
-
-
regInfo000? schrieb:
- Warum muss ich typedef struct Node .... Node schreiben? Dieses Node ist doppelt. Aber ohne müsste ich immer (struct Node
schreiben, wieso?
Das ist C-Syntax.
regInfo000? schrieb:
- Die Ausgabe (Wurzel-Links-Rechts / dfs) dreht total durch bei mir, was habe ich vergessen?
Du trägst bei add1 den neuen Node links und rechts ein.
regInfo000? schrieb:
- Ist string copy richtig, wenn ich in der Struct immer Zeichenketten mit genau 20 Zeichen (inklusive '\n') haben möchte?
string copy kenne ich nicht. Interresanter wäre auch das '\0'
regInfo000? schrieb:
- Wieso kann ich
struct Node *left = NULL;
nicht schreiben?
Weil du eine Wertzuweisung nur bei der Definition der Variablen machen kannst. Dazu gehört aber nicht typedef.
Du kannst bei der Definition die Werte übergeben:Node knoten = {"", NULL, NULL);
oder wenn es dynamisch werden soll, nimm calloc.
- Warum muss ich typedef struct Node .... Node schreiben? Dieses Node ist doppelt. Aber ohne müsste ich immer (struct Node
-
Allerdings Platz für ein 20-elemntiges Array wird in der Struct bzw. bei malloc angelegt.
if (nod->left == NULL) nod->left = newNod; else if (nod->right == NULL) nod->right = newNod; /*....*/ printf("%-5i%-19s%7p%7p%7p\n", ebe, nod->str, nod, nod->left, nod->right);
funktioniert.
Kann ich
if (nod->left == NULL || nod->right == NULL) {
umschreiben in
if (nod == NULL) {
und dann &nod "etwas neues" zuweisen?
Verwendet ihr auch den -> für (*variable).element ?
-
regInfo000? schrieb:
Allerdings Platz für ein 20-elemntiges Array wird in der Struct bzw. bei malloc angelegt.
Hat das jemand bestritten? In welchem Zusammenhang meinst du das?
regInfo000? schrieb:
Kann ich ... umschreiben in ... und dann &nod "etwas neues" zuweisen?
Du darfst dir mal selber überlegen was das bedeutet:
was ist
nod?
nod->left bzw. nod->right?
&nod?
NULL?regInfo000? schrieb:
Verwendet ihr auch den -> für (*variable).element ?
Sicher, dafür ist er da. Ist ja auch weniger Schreibarbeit (und auch lesbarer)
-
nod ist ein Zeiger auf ein/e Struct. D. h. der Wert von nod ist eine Adresse (16-bit, 32-bit, abhängig vom System und der Implementierung). An/Bei dieser Adresse liegt/liegen "die Werte von Struct".
Idee/Vermutung: (*nod) oder nod-> liefert mir den Inhalt von nod (Dereferenzierung). &nod liefert mir die Adresse der Adresse/des Zeigers nod... Damit kann ich zur Zeit nichts anfangen. void * malloc(....) will nur eine Variable oder Typ haben, für den Speicherplatz reserviert werden soll. Dass an/bei der Adresse des NULL-Werts der Struct Speicherplatz reserviert werden soll, kann ich wahrscheinlich nicht angeben. Olay, dann erübrigt sich meine Frage grad...
Einen Wert NULL kann ich also nicht einfach in eine Struct umwandeln. Welche Adresse malloc nach dem rEservieren zurückgibt ,ist unbekannt.
Prinzipiell ist das wie mit Objektreferenzen in Java - und eine Struct (<- wie nennt man die Dinger eigentlich=?) ist so etwas wie ein Objekt (ohne Funktionen/Methoden/Prozeduren, aber mit "Variablen" [<- und wie nennen sich die=?] für Daten)...
Zukünftig werde ich wieder meinen Kopf einschalten..
-
Hallo, ich habe es mal überarbeitet:
/* * Kommentar */ #include <limits.h> #include <stdio.h> #include <stdlib.h> #define STRING_SIZE 20 typedef struct Node { char str[STRING_SIZE]; struct Node *left; struct Node *right; } Node; Node *tree = NULL; void cop1(char str[], Node *nod) { int i; for (i = 0; str[i] != '\0' && i < STRING_SIZE - 1; i++) nod->str[i] = str[i]; for(; i < STRING_SIZE - 1; i++) /* optionally */ nod->str[i] = '*'; nod->str[i] = '\0'; nod->left = NULL; nod->right = NULL; } void add1(char str[], Node *nod, Node *newNod) { if (nod->left == NULL) if (nod->right == NULL) if (rand() % 2 == 0) nod->left = newNod; else nod->right = newNod; else nod->left = newNod; else if (nod->right == NULL) nod->right = newNod; else if (rand() % 2 == 0) add1(str, nod->left, newNod); else add1(str, nod->right, newNod); } void add(char str[]) { Node *newNod = (Node *) malloc(sizeof(Node)); cop1(str, newNod); if (tree == NULL) { tree = newNod; return; } add1(str, tree, newNod); } void printTree1(int ebe, Node *nod) { if (nod == NULL) return; printf("%-2i%-19s%7p%7p%7p\n", ebe, nod->str, nod, nod->left, nod->right); ebe++; printTree1(ebe, nod->left); printTree1(ebe, nod->right); } void printTree(void) { printTree1(1, tree); } int main(void) { int i; int array[10]; /* Deklaration */ int *pointer1, *pointer2; pointer1 = array; /* pointer1 auf Anfangsadresse von array */ pointer2 = array + 3; /* pointer2 auf 4.Element von array */ array[0] = 99; /* array[0] */ pointer1[1] = 88; /* array[1] */ *(pointer1+2) = 77; /* array[2] */ *pointer2 = 66; /* array[3] */ for (i = 0; i < 10; i++) printf("%5i\n", array[i]); for (i = 0; i < 13; i++) { add("eins"); add("Zwei"); add("drei"); add("Vier"); add("fuenf"); add("Sechs"); add("sieben"); add("Acht"); add("neun"); add("!!Sehr laaannngggeeer String/Zeichenkette!!"); } printTree(); getchar(); return EXIT_SUCCESS; }
Ausgabe bei mir:
[SPOILER]C:\Users\MyName\Desktop>%gcc% HelloWorld.c (gcc == gcc -ansi -pedantic -Wall -o HelloWorld.exe ) C:\Users\MyName\Desktop>HelloWorld.exe 99 88 77 66 1962414434 1962761156 4202240 2686824 4202334 4202240 1 eins*************** 5213e8 520f68 521410 2 drei*************** 520f68 520fe0 520fb8 3 Sechs************** 520fe0 521008 5210f8 4 sieben************* 521008 526388 5263b0 5 Sechs************** 526388 526450 5267c0 6 eins*************** 526450 6474a8 0 7 Acht*************** 6474a8 0 0 6 drei*************** 5267c0 5269f0 526928 7 sieben************* 5269f0 0 0 7 Zwei*************** 526928 0 0 5 sieben************* 5263b0 5264f0 526540 6 fuenf************** 5264f0 0 647688 7 !!Sehr laaannngggee 647688 0 0 6 sieben************* 526540 647250 647340 7 drei*************** 647250 0 0 7 neun*************** 647340 0 6476d8 8 Zwei*************** 6476d8 0 0 4 drei*************** 5210f8 5265e0 526608 5 eins*************** 5265e0 5266a8 526748 6 Sechs************** 5266a8 647570 647408 7 drei*************** 647570 0 0 7 Vier*************** 647408 0 0 6 !!Sehr laaannngggee 526748 526978 6475e8 7 Vier*************** 526978 0 6477c8 8 Acht*************** 6477c8 0 0 7 Sechs************** 6475e8 0 0 5 Zwei*************** 526608 647070 647020 6 eins*************** 647070 6470e8 647138 7 Vier*************** 6470e8 0 0 7 Sechs************** 647138 647318 0 8 Acht*************** 647318 0 0 6 neun*************** 647020 647750 0 7 fuenf************** 647750 0 0 3 fuenf************** 520fb8 5210d0 521030 4 Zwei*************** 5210d0 521148 521198 5 fuenf************** 521148 526680 526720 6 fuenf************** 526680 0 526e70 7 neun*************** 526e70 0 0 6 neun*************** 526720 647200 526fb0 7 eins*************** 647200 0 0 7 sieben************* 526fb0 0 0 5 sieben************* 521198 647368 526590 6 !!Sehr laaannngggee 647368 0 526ee8 7 Zwei*************** 526ee8 0 0 6 neun*************** 526590 0 647458 7 Sechs************** 647458 0 0 4 Acht*************** 521030 526400 526798 5 neun*************** 526400 5268b0 526860 6 neun*************** 5268b0 526950 647548 7 drei*************** 526950 526f38 0 8 Vier*************** 526f38 0 0 7 Zwei*************** 647548 647610 527000 8 sieben************* 647610 0 0 8 neun*************** 527000 0 0 6 sieben************* 526860 6473e0 6473b8 7 drei*************** 6473e0 0 647778 8 Sechs************** 647778 0 0 7 Zwei*************** 6473b8 0 526f60 8 fuenf************** 526f60 0 0 5 Zwei*************** 526798 647638 647480 6 Acht*************** 647638 6477a0 647660 7 sieben************* 6477a0 0 0 7 neun*************** 647660 0 0 6 sieben************* 647480 0 0 2 Zwei*************** 521410 520f90 521058 3 Vier*************** 520f90 521120 5210a8 4 Vier*************** 521120 526360 5262e8 5 fuenf************** 526360 647278 5269c8 6 Vier*************** 647278 647390 647700 7 eins*************** 647390 0 0 7 drei*************** 647700 0 0 6 Sechs************** 5269c8 647520 6472a0 7 eins*************** 647520 0 526e98 8 !!Sehr laaannngggee 526e98 0 0 7 fuenf************** 6472a0 0 0 5 Zwei*************** 5262e8 526478 526770 6 Zwei*************** 526478 526888 6475c0 7 Acht*************** 526888 0 0 7 fuenf************** 6475c0 0 0 6 eins*************** 526770 647048 0 7 !!Sehr laaannngggee 647048 0 0 4 eins*************** 5210a8 526270 5211c0 5 neun*************** 526270 5263d8 5265b8 6 Acht*************** 5263d8 526900 6472c8 7 eins*************** 526900 0 6474d0 8 neun*************** 6474d0 0 0 7 Sechs************** 6472c8 0 0 6 !!Sehr laaannngggee 5265b8 5266d0 6470c0 7 sieben************* 5266d0 0 647728 8 Vier*************** 647728 0 0 7 drei*************** 6470c0 0 0 5 Acht*************** 5211c0 526298 526518 6 !!Sehr laaannngggee 526298 6472f0 647110 7 sieben************* 6472f0 0 0 7 fuenf************** 647110 0 0 6 Sechs************** 526518 5266f8 647098 7 Acht*************** 5266f8 0 0 7 Zwei*************** 647098 647430 647228 8 fuenf************** 647430 0 0 8 Zwei*************** 647228 0 0 3 neun*************** 521058 521170 521080 4 Sechs************** 521170 526338 526428 5 Vier*************** 526338 5264a0 5269a0 6 drei*************** 5264a0 647598 526a18 7 Vier*************** 647598 0 0 7 Acht*************** 526a18 0 0 6 fuenf************** 5269a0 6471d8 6474f8 7 !!Sehr laaannngggee 6471d8 0 0 7 !!Sehr laaannngggee 6474f8 0 0 5 !!Sehr laaannngggee 526428 5267e8 526838 6 Vier*************** 5267e8 647160 527028 7 sieben************* 647160 0 0 7 !!Sehr laaannngggee 527028 0 0 6 Sechs************** 526838 0 0 4 !!Sehr laaannngggee 521080 5262c0 526310 5 eins*************** 5262c0 526568 526810 6 Acht*************** 526568 6476b0 0 7 eins*************** 6476b0 0 0 6 fuenf************** 526810 526f88 6471b0 7 Sechs************** 526f88 0 0 7 neun*************** 6471b0 0 0 5 drei*************** 526310 526630 5264c8 6 drei*************** 526630 526ec0 647188 7 eins*************** 526ec0 0 0 7 Acht*************** 647188 0 0 6 Vier*************** 5264c8 5268d8 526658 7 !!Sehr laaannngggee 5268d8 526fd8 0 8 Acht*************** 526fd8 0 0 7 Vier*************** 526658 526f10 0 8 drei*************** 526f10 0 0 C:\Users\MyName\Desktop>
[/SPOILER]
Fragen:
(0) Wer einen Baum mit Höhe > 9 bekommt (0-basiert oder wie auch immer), bei dem stimmt etwas mit dem Zufall nicht...- Arbeite ich so mit den Zeigern korrekt?
- Muss ich in Zeile 25 immer nod->str[i] = '\0'; schreiben, oder ist das 20ste Zeichen immer '\0'?
- Kann ich nicht einfach einen Zeiger auf "dies ist ein String" zuweisen?
- Lässt sich ab Zeile 30 das "if-else if-else"-Konstrukt vereinfachen?
- Ist es sinnvoll, schon in der Funktion add Speicherplatz zu allokieren/allozieren und einen Zeiger darauf bei jedem Aufruf von add1 mitzugeben? Schließlich wird dann jedes mal kopiert...
- Was könntet ihr anhand der obigen Ausgabe über mein System sagen?
-
sry for doppelpost...
/* * Kommentar */ #include <limits.h> #include <stdio.h> #include <stdlib.h> #define STRING_SIZE 20 typedef struct Node { char str[STRING_SIZE]; struct Node *left; struct Node *right; } Node; Node *tree = NULL; void cop1(char str[], Node *newNod) { int i; for (i = 0; str[i] != '\0' && i < STRING_SIZE - 1; i++) newNod->str[i] = str[i]; for(; i < STRING_SIZE - 1; i++) /* optionally */ newNod->str[i] = '*'; newNod->str[i] = '\0'; newNod->left = NULL; newNod->right = NULL; } int trueOrFalse(void) { return rand() % 2; } void add1(Node *nod, Node *newNod) { if (nod->left == NULL) if (nod->right == NULL) if (trueOrFalse()) nod->left = newNod; else nod->right = newNod; else nod->left = newNod; else if (nod->right == NULL) nod->right = newNod; else if (trueOrFalse()) add1(nod->left, newNod); else add1(nod->right, newNod); } void add(char str[]) { Node *newNod = (Node *) malloc(sizeof(Node)); cop1(str, newNod); if (tree == NULL) { tree = newNod; return; } add1(tree, newNod); } void printTree1(int *val, Node *nod) { if (nod == NULL) return; printf("%-4i%-19s%7p%7p%7p\n", ++(*val), nod->str, nod, nod->left, nod->right); printTree1(val, nod->left); printTree1(val, nod->right); } void printTree(void) { int val = 0; printTree1(&val, tree); } int compare(char *str1, char *str2) { int i; int len = sizeof(str1); int len2 = sizeof(str2); if (len2 < len) len = len2; for (i = 0; i < len; i++) if (str1[i] != str2[i]) return 0; return 1; } char * search1(char *str, int *i, char **ptrptr) { return "not yet implemented"; } char * search(char *str) { int i = 0; char *ptr = ""; char **ptrptr = &ptr; if (tree == NULL || compare(tree->str, str)) return ""; return search1(str, &i, ptrptr); } int main(void) { getchar(); return EXIT_SUCCESS; }
Ich möchte jetzt in Zeile 90 die Funktion search implementieren. Wenn die Wurzel des Baums gleich dem String str ist, soll "" zurückgegeben werden. Wenn der Baum so aufgebaut ist:
"a" / \ "b" "c" / \ / \ |"d" | |
und str=="d" ist, dann soll "LR" für Links und Rechts zurückgegeben werden. Usw.
Welche Parameter muss die Funktion search1 haben?
char **ptrptr dachte ich mir, damit an den String *ptrptr ein Zeichen mittels malloc angehängt werden kann...
Danke noch mal fürs Drüberschauen