PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Einfache C Frage


AtTheEndofAugust
2008-06-10, 22:26:50
Wieso stürzt mein Compiler bei folgendem Quelltext ab?



#include <stdio.h>

void main()

{

int zahl;

printf ("Welche Zahl soll ueberprueft werden?\n");
scanf ("%d", zahl);

printf("Die Zahl ist %d", zahl);


}






Und könnt ihr mir ein gutes Forum für Probleme in C empfehlen?

bluey
2008-06-10, 22:30:32
void main()


int main()

sollte es sein.

Oberon
2008-06-10, 22:30:37
Wieso stürzt mein Compiler bei folgendem Quelltext ab?



#include <stdio.h>

void main()

{

int zahl;

printf ("Welche Zahl soll ueberprueft werden?\n");
scanf ("%d", zahl);

printf("Die Zahl ist %d", zahl);


}






Und könnt ihr mir ein gutes Forum für Probleme in C empfehlen?



Da fehlt was ;).

AtTheEndofAugust
2008-06-10, 22:31:43
-.- danke ich wusste es fehlt etwas aber konnte es nicht beziffern!


Was gibt es denn für gute foren?

Oberon
2008-06-10, 22:33:13
-.- danke ich wusste es fehlt etwas aber konnte es nicht beziffern!



Da fehlt ein "&": Is mir auch oft passiert. :biggrin:

!_Tomcat_!
2008-06-10, 22:36:52
& was fehlt da? :rolleyes:

Aber ein Absturz deswegen? Welchen Compiler verwendest Du?
Borland würde an der Stelle sagen "Syntaxfehler" und würde die Zeile anstreichen. Hilft ungemein ;)

Wenn Du Dich jetzt mit C quälst... Mir hat es mit Perl! sehr geholfen etwas C zu können. C ist ein guter Grundstein.

Edit: Mist, zu langsam für meinen joke :(

AtTheEndofAugust
2008-06-10, 23:09:39
#include <stdio.h>

void main()

{
int i;
int zahl;

printf ("Welche Zahl soll ueberprueft werden?\n");
scanf ("%d", &zahl);


for (i=2; i<zahl; i++)

{

if (zahl%i==0)
{
printf("Die Zahl ist keine Primzahl");
}

else

{
printf("Die Zahl ist eine Primzahl");
}


}
}







Warum schreibt mir das Programm Den Ausgabesatz mehrfach hin, statt nur einmal und wie behebe ich das?

Ajax
2008-06-10, 23:13:36
& was fehlt da? :rolleyes:

Aber ein Absturz deswegen? Welchen Compiler verwendest Du?
Borland würde an der Stelle sagen "Syntaxfehler" und würde die Zeile anstreichen. Hilft ungemein ;)

Wenn Du Dich jetzt mit C quälst... Mir hat es mit Perl! sehr geholfen etwas C zu können. C ist ein guter Grundstein.

Edit: Mist, zu langsam für meinen joke :(
Stichwort Adressoperator. Das ist ein Pointer, den Du da vergessen hast.

Oberon
2008-06-10, 23:27:54
...
Eigentlich kenn ich mich ja gar nicht aus mit C, aber ich denke, bei dir erfolgt die Ausgabe mehrfach, weil die Bedingung für die Ausgabe mehrfach erfüllt ist. Wenn zB 24 überprüft wird, wird bei allen Teilern von 24 "keine Primzahl" ausgegeben, genauso bei den "Nicht-Teilern". Ich glaube, mit dem Einfügen einer break-Anweisung ließe sich dieses Problem beheben. Wie gesagt - ohne Gewähr.
€: Wobei mir grade auffällt, dass sich das dann wohl nur auf den ersten Fall auswirken würde..hm. Stell deine Frage doch lieber in einem Programmierforum. :D

Laz-Y
2008-06-10, 23:35:38
Warum schreibt mir das Programm Den Ausgabesatz mehrfach hin, statt nur einmal und wie behebe ich das?

Na du hast halt ne schleife. Die wird so lang durchlaufen bis i => zahl. Bei ner großen Zahl kann das dauern ;)

AtTheEndofAugust
2008-06-10, 23:44:31
ja okay aber wie stell ich das an, dass der Satz nur einmal erscheint. bzw. er bei finden eines Teilers (Modulo = 0) direkt ausgibt, dass es keine Primzahl ist

Plutos
2008-06-11, 00:37:56
ja okay aber wie stell ich das an, dass der Satz nur einmal erscheint. bzw. er bei finden eines Teilers (Modulo = 0) direkt ausgibt, dass es keine Primzahl ist

Ich kann leider keine C-Syntax, aber grundsätzlich: du könntest in der Schleife zählen (z.B. in der Variable zähler), wie oft

if (zahl%i==0)

falsch ist (also i ein Teiler von zahl ist, zähler zählt die Anzahl dieser Teiler)

und damit nach der Schleife einen Befehl anwenden, der etwa so lauten könnte:

wenn zähler > 0 dann gib aus "keine Primzahl"
ansonsten gib aus "Primzahl"

Geht sicher auch eleganter, aber so würde es zumindest funktionieren ;). So erhältst du gleichzeitig die Anzahl der Teiler von zahl, falls das wichtig ist. Ansonsten gibt es doch in C sicher auch ein Statement, um eine Schleife bei eintreten einer bestimmten Bedingung (Teiler gefunden) sofort zu verlassen, aber das weiß sicher einer der Gurus ;).

F4kenick
2008-06-11, 01:10:28
for (i=2; i<zahl; i++)

um die Abfrage noch schneller zugestaltet:
- i kann ab 3 in 2er Schritten springe (wenn durch 2 nicht teilbar, dann auch nicht durch 4, 6, 8, ...)
- du brauchst nur bis i > sqrt(zahl) abzufragen (weil i² = zahl wäre der höchste Teiler der in Frage kommt, weil wenn i größer als die Wurzel ist, is der Faktor mit dem Multipliziert werden muss kleiner als i und damit schon getestet)

pest
2008-06-11, 06:54:58
#include <stdio.h>

void main()

{
int i;
int zahl;

printf ("Welche Zahl soll ueberprueft werden?\n");
scanf ("%d", &zahl);


for (i=2; i<zahl; i++)

{

if (zahl%i==0)
{
printf("Die Zahl ist keine Primzahl");
}

else

{
printf("Die Zahl ist eine Primzahl");
}


}
}







Warum schreibt mir das Programm Den Ausgabesatz mehrfach hin, statt nur einmal und wie behebe ich das?

so ;)


void main()

{
int i;
int zahl;

printf ("Welche Zahl soll ueberprueft werden?\n");
scanf ("%d", &zahl);


int isprim=0;
for (i=2; i<zahl; i++)
{

if (zahl%i==0) isprim=1;

}

if (isprim==1) printf("Zahl ist keine Primzahl\n")
else printf("Zahl ist Primzahl");
}

DocEW
2008-06-11, 09:29:41
Kannst auch mit einem break aus der Schleife rausgehen.
Oder eine bool-Variable machen, die du setzt, sobald zahl%i==0 ist. Die Schleife sieht dann vom Prinzip so aus:

foundThatIsPrime=false;
while( !foundThatIsPrime && i < zahl ) {
if (zahl%i==0)
{
foundThatIsPrime=true;
}
i++;
}

mekakic
2008-06-11, 09:40:23
Wieso stürzt mein Compiler bei folgendem Quelltext ab?
Ein Compiler sollte eigentlich nicht abstürzen, solange man zumindest nicht für Konsolen entwickelt.
:)

ShadowXX
2008-06-11, 09:49:56
Kannst auch mit einem break aus der Schleife
rausgehen.

Und hoffentlich ne Schelle fangen wenn jemand den Code danach überprüft.....lernt man das tatsächlich heutzutage so, das man mit break aus schleifen springt oder mittendrin irgendwo ein return einbaut?

Ich hab diese echt dumme Angewohnheit jetzt schon bei mehreren unser "Werkssemester"-Studenten gesehen.


Oder eine bool-Variable machen, die du setzt, sobald zahl%i==0 ist. Die Schleife sieht dann vom Prinzip so aus:

foundThatIsPrime=false;
while( !foundThatIsPrime && i < zahl ) {
if (zahl%i==0)
{
foundThatIsPrime=true;
}
i++;
}
Das ist doch schon viel netter, wobei es im Prinzip auch reicht den Zähler auf den Vergleich zum rausspringen zu setzen (dann ist es auch egal ob for oder while, natürlich nur wenn man den hinterher nicht noch für was anderes braucht).

pest
2008-06-11, 10:00:47
optimieren kann man das Ganze bis zum GetNo...z.b. Sieb des Eratosthenes (http://de.wikipedia.org/wiki/Sieb_des_Eratosthenes)

DocEW
2008-06-11, 15:36:32
Das ist doch schon viel netter, wobei es im Prinzip auch reicht den Zähler auf den Vergleich zum rausspringen zu setzen(...).
Manipulation der Zählvariablen finde ich persönlich aber auch nicht besser als ein break. Was hast du dadurch gewonnen, außer der Unsicherheit, dass die Variable 10 Zeilen weiter wieder zurück geändert wird?

Coda
2008-06-11, 16:24:45
Ich frag mich auch was an einem break so schlimm sein soll.

SGT.Hawk
2008-06-11, 16:39:25
Meine ich auch,besser als goto.

Monger
2008-06-11, 16:59:57
Vorallem ist ein frühes zurückkehren viel leichter kontrollierbar, als zwanghaft den Programmfluss bis zum Ende durchzupeitschen.

Wenn man Breaks und Continues zwanghaft unterbindet, handelt man sich teilweise ganz üble und aufgeblähte Konstrukte ein.

PHuV
2008-06-11, 17:14:21
Vorallem ist ein frühes zurückkehren viel leichter kontrollierbar, als zwanghaft den Programmfluss bis zum Ende durchzupeitschen.

Wenn man Breaks und Continues zwanghaft unterbindet, handelt man sich teilweise ganz üble und aufgeblähte Konstrukte ein.

:up: genau so ist es, und so einen Code will ich bestimmt nicht warten. Zudem gibt es immer wieder Abfragen, die man nicht am Schleifenanfang abfragen bzw. mit einbringen kann.

Tiamat
2008-06-12, 09:22:56
Also unsere Profs sind auf break und continue gar nicht gut zu sprechen.
Wer in einem Testat durchfallen möchte, kann gerne mal ein paar Sprungmarken in den Code einbauen ;D
Eine sinnvolle Erklärung hierfür haben sie allerdings nicht dafür gegeben.
In einigen Büchern heißt es, die Benutzung von break und continue wären der Benutzung von Flags vorzuziehen. Ich glaube, ich schreib ihm mal ne Mail, würde mich interessieren.

Monger
2008-06-12, 09:29:41
Wer in einem Testat durchfallen möchte, kann gerne mal ein paar Sprungmarken in den Code einbauen ;D

Sprungmarken à la GoTo haben auch einen handfesten Nachteil: du kannst mit ihnen aus einem Scope raus und in einen völlig anderen rein springen. Du kannst damit also Code brechen, der gar nicht innerhalb deines aktuellen Scopes liegt - und das ist WIRKLICH hässlich!

Continue, break und return sind dagegen immer nur auf den aktuellen Scope bezogen - mehr als aus der aktuellen Schleife rausspringen geht halt nicht. Insofern sind sie ziemlich narrensicher.

Superguppy
2008-06-12, 10:13:57
Ich programmiere zwar jetzt schon ein ganzes Jahr lang in C, aber den Sinn von continue habe ich bisher nicht eruieren können. Es reicht doch eigentlich, wenn man gar nichts hin schreibt, damit die Schleife weiter läuft, solange die Prüfbedingung keinen Abbruch erfordert. :confused:

pest
2008-06-12, 10:15:30
Ich programmiere zwar jetzt schon ein ganzes Jahr lang in C, aber den Sinn von continue habe ich bisher nicht eruieren können. Es reicht doch eigentlich, wenn man gar nichts hin schreibt, damit die Schleife weiter läuft, solange die Prüfbedingung keinen Abbruch erfordert. :confused:

continue springt direkt zum schleifenanfang

Gohan
2008-06-12, 10:31:50
Kannst auch mit einem break aus der Schleife rausgehen.
Oder eine bool-Variable machen, die du setzt, sobald zahl%i==0 ist. Die Schleife sieht dann vom Prinzip so aus:

foundThatIsPrime=false;
while( !foundThatIsPrime && i < zahl ) {
if (zahl%i==0)
{
foundThatIsPrime=true;
}
i++;
}

Jetzt bring ihm doch nicht direkt die bösen Sachen wie break bei! :( Pfui!

ShadowXX
2008-06-12, 10:51:48
Also unsere Profs sind auf break und continue gar nicht gut zu sprechen.
Wer in einem Testat durchfallen möchte, kann gerne mal ein paar Sprungmarken in den Code einbauen ;D
Ich ergänze noch um: Wer bei uns in der Firma rausfliegen möchte kann gerne ein break einsetzen.

Ich sehe auch nicht wo ein break besser wartbar wäre.
Davon abgesehen sind breaks extrem unelegant.


Manipulation der Zählvariablen finde ich persönlich aber auch nicht besser als ein break. Was hast du dadurch gewonnen, außer der Unsicherheit, dass die Variable 10 Zeilen weiter wieder zurück geändert wird?

Lies doch bitte mal ich schreibe.

Bei meinem Beispiel der Anwendung ist es egal ob die Variable 10 Zeilen später geändert wird.
Davon abgesehen: Wenn ich den Code schreibe weiß ich auch was ich 10 Zeilen später mache.

Sprungmarken à la GoTo haben auch einen handfesten Nachteil: du kannst mit ihnen aus einem Scope raus und in einen völlig anderen rein springen. Du kannst damit also Code brechen, der gar nicht innerhalb deines aktuellen Scopes liegt - und das ist WIRKLICH hässlich!

Continue, break und return sind dagegen immer nur auf den aktuellen Scope bezogen - mehr als aus der aktuellen Schleife rausspringen geht halt nicht. Insofern sind sie ziemlich narrensicher.
Ja du kannst, musst aber nicht.

Wenn Goto böse ist (und das ist es), dann breaks genauso, denn auch ein Goto könnte ich genau so plazieren das es genau das gleiche macht wie der break....ist das Goto dann plötzlich gut?

Monger
2008-06-12, 11:13:35
Ja du kannst, musst aber nicht.

Wenn Goto böse ist (und das ist es), dann breaks genauso, denn auch ein Goto könnte ich genau so plazieren das es genau das gleiche macht wie der break....ist das Goto dann plötzlich gut?
Das ist jetzt weibliche Logik. Nur weil man theoretisch mit einem Granatwerfer jagen kann, ist ein Jagdmesser nicht gleich eine Kriegswaffe.

Du kannst mit einem Goto böse Dinge tun, die du mit einem continue, break und return nicht hinbekommst - und damit ist ein Goto böse, und das andere Zeug nicht.

Ich ergänze noch um: Wer bei uns in der Firma rausfliegen möchte kann gerne ein break einsetzen.

Du bist in einer seltsamen Firma! :|

Ich sehe auch nicht wo ein break besser wartbar wäre.
Davon abgesehen sind breaks extrem unelegant.

Wenn du eine Menge Bedingungen hast die zum Abbruch einer Schleife führen könnten, sind die mit einem break ganz schnell erschlagen. Versuchst du das selbe mit If-Then-Else Konstrukten zu lösen, kommst du schnell mal in sagenhafte Schachtelungstiefen.

Den Kontrollfluss in solchen Klammerwäldern zu warten, ist unglaublich hässlich.

PHuV
2008-06-12, 11:18:24
Ich programmiere zwar jetzt schon ein ganzes Jahr lang in C, aber den Sinn von continue habe ich bisher nicht eruieren können. Es reicht doch eigentlich, wenn man gar nichts hin schreibt, damit die Schleife weiter läuft, solange die Prüfbedingung keinen Abbruch erfordert. :confused:

Wenn Du in der Schleife jedoch eine Reihe von Bedingungen prüfen mußt (und sie aus Lesbarkeitsgründen auch nicht alle im Schleifenanfang reinpacken willst), kommt das sogar recht häufig vor.

Ich habe z.B. 20 Jahren alten Code pflegen müssen, und um die bisherige Progammlogik nicht all zu sehr ummodeln zum müssen, habe ich ab und zu break und continue eingesetzt. Gerade bei altem und sehr komplexen Code kann es tödlich sein, ihn zu sehr umzustrukturieren.

PHuV
2008-06-12, 11:21:17
Das ist jetzt weibliche Logik. Nur weil man theoretisch mit einem Granatwerfer jagen kann, ist ein Jagdmesser nicht gleich eine Kriegswaffe.

Du kannst mit einem Goto böse Dinge tun, die du mit einem continue, break und return nicht hinbekommst - und damit ist ein Goto böse, und das andere Zeug nicht.

Sehe ich auch so. Aber ich muß gestehen, ich war einmal sogar auf ein goto angewiesen, weil sonst alles andere zu umständlich gewesen wären. Auch ein goto kann durchaus Sinn machen. Generell sollte man es aber immer vermeiden.

Aquaschaf
2008-06-12, 11:21:43
Davon abgesehen: Wenn ich den Code schreibe weiß ich auch was ich 10 Zeilen später mache.

Es geht um Wartbarkeit. Ein paar Monate später weißt du es wahrscheinlich nicht mehr. Und jemand anderes der den Code liest noch weniger.

Wenn Goto böse ist (und das ist es), dann breaks genauso, denn auch ein Goto könnte ich genau so plazieren das es genau das gleiche macht wie der break....ist das Goto dann plötzlich gut?

Was für ein Unsinn. Du kannst auch ein 'goto' so platzieren dass es das selbe wie 'if' macht. Also ist 'if' genauso böse?

Xmas
2008-06-12, 11:30:44
goto ist nicht generell "böse", und break erst recht nicht. break ist in einigen Fällen eleganter als Flags, wer da aus Überzeugung dass break ja "böse" sein muss trotzdem Flags einsetzt hat nicht verstanden was guten Code ausmacht.

Superguppy
2008-06-12, 12:42:45
continue springt direkt zum schleifenanfang
Ah, okay dann ergibt das natürlich schon Sinn. Ich weiß nur noch immer nicht, warum unser Vortragender an der FH wohl break, aber nicht continue erklärt bzw. in irgendwelchen Vorzeigebeispielen verwendet hat.

Wenn Du in der Schleife jedoch eine Reihe von Bedingungen prüfen mußt (und sie aus Lesbarkeitsgründen auch nicht alle im Schleifenanfang reinpacken willst), kommt das sogar recht häufig vor.
Hm, ja leuchtet ein. Wobei ich so etwas mit einer Endlosschleife und Bedinungsabfragen samt breaks am Ende der Schleife gelöst hätte. Wie sooft etwas dazu gelernt und gesehen, dass es beim Programmieren immer mehrere Lösungen gibt, die zum Ziel führen (aber zum Teil unterschiedliche elegant sind). :smile:

DocEW
2008-06-12, 13:09:01
Lies doch bitte mal ich schreibe.
Bei meinem Beispiel der Anwendung ist es egal ob die Variable 10 Zeilen später geändert wird.
Dann verstehe ich anscheinend nicht, was du meinst. Schreib mal bitte ein Code-Fragment, was deutlich das verdeutlicht.

Davon abgesehen: Wenn ich den Code schreibe weiß ich auch was ich 10 Zeilen später mache.
Hehe, jo genau. Dieses Argument kann man immer einsetzen, z.B. auch um ein Goto zu rechtfertigen. "Ich weiß ja, wo ich hinspringe." :|

Wenn Goto böse ist (und das ist es), dann breaks genauso, denn auch ein Goto könnte ich genau so plazieren das es genau das gleiche macht wie der break....ist das Goto dann plötzlich gut?
Also wenn du unbedingt dieser verqueren Logik folgen willst: Ja, wenn du ein "goto startOfLoop" machst ist das genau das gleiche wie ein "break" und auch nicht böser. Aber mit goto kann man halt ganz allgemein irgendwo hin springen, und DAS ist böse.

AtTheEndofAugust
2008-06-12, 14:01:33
kleine frage noch:

Wieso nudelt der die Schleife durch, obwohl die Bedinung der for schleife nicht erfüllt ist?


#include <stdio.h>
#include <conio.h>
int main()

{

int i=11;



for (i = 1; i <= 10; i++) printf ("%d\n",i);



getch();

return(0);
}

DocEW
2008-06-12, 14:03:02
Weil die Schleifeninitialisierung (i=1) ausgeführt wird, bevor zum ersten Mal geprüft wird, ob i<=10 ist.

Gast
2008-06-12, 14:03:06
kleine frage noch:

Wieso nudelt der die Schleife durch, obwohl die Bedinung der for schleife nicht erfüllt ist?


#include <stdio.h>
#include <conio.h>
int main()

{

int i=11;



for (i = 1; i <= 10; i++) printf ("%d\n",i);



getch();

return(0);
}

Die Bedingung ist erfüllt.
Du setzt zwar erst i auf 11 aber in der for() setzt du i auf 1 bevor die Bedingung überhaupt geprüft wird.

AtTheEndofAugust
2008-06-12, 14:04:39
e: hab glaub ich die llsung selbst:

Die initialisierung von i=1 in der schleife "überschreibt" die vorherige Anweisung bei int!


Richtig?

Gast
2008-06-12, 14:21:03
Ja

del_4901
2008-06-12, 18:35:49
Also mein (Ex)Informatiklehrer (noch an der Schule) hat uns vor Jahren auch erzählt, das breaks unelegant seien. Wenn er das heute nochmal sagen würde, würde ich ihn auslachen. Ich weiß nicht wo die das her haben, warscheinlich einfach nur dumm nachgeplappert, von irgend jemanden. Kann es sein, das es zu archaischen Zeiten Compilerbugs bezüglich dem break gegeben hat? Das müsste ja schon älter als 15 jahre sein. ;)
Der Fowler hat mal gesagt: "Jeder kann Code schreiben, den Maschinen verstehen können, aber nur die wenigstens können Code schreiben, den auch Menschen verstehen können."

noid
2008-06-12, 19:35:49
Also mein (Ex)Informatiklehrer (noch an der Schule) hat uns vor Jahren auch erzählt, das breaks unelegant seien. Wenn er das heute nochmal sagen würde, würde ich ihn auslachen. Ich weiß nicht wo die das her haben, warscheinlich einfach nur dumm nachgeplappert, von irgend jemanden. Kann es sein, das es zu archaischen Zeiten Compilerbugs bezüglich dem break gegeben hat? Das müsste ja schon älter als 15 jahre sein. ;)
Der Fowler hat mal gesagt: "Jeder kann Code schreiben, den Maschinen verstehen können, aber nur die wenigstens können Code schreiben, den auch Menschen verstehen können."

Wenn du 200 Zeilen alten Code mit "PseudoGotos" und Dutzenden Flags mit 10 Zeilen Code und einer Lookuptabelle ersetzt hast, dann fühlt sich der Tag gleich zehnmal besser an... "DoLabel54Code" X-(
Mein Lieblingssatz ("wieso neu schreiben? Wir haben doch vor 15Jahren das schonmal entwickelt - und dann in c portiert!")

Goto, continue und break (außer bei switchcase) sind deshalb schlimm, weil diese anweisung bei verschachtelten schleifen auch nicht wirklich intuitiv ist.

del_4901
2008-06-12, 19:43:29
Wenn du 200 Zeilen alten Code mit "PseudoGotos" und Dutzenden Flags mit 10 Zeilen Code und einer Lookuptabelle ersetzt hast, dann fühlt sich der Tag gleich zehnmal besser an... "DoLabel54Code" X-(
Mein Lieblingssatz ("wieso neu schreiben? Wir haben doch vor 15Jahren das schonmal entwickelt - und dann in c portiert!")

Goto, continue und break (außer bei switchcase) sind deshalb schlimm, weil diese anweisung bei verschachtelten schleifen auch nicht wirklich intuitiv ist.
Also bei 200 Zeilen Murks-Code bin ich schneller mit neu schreiben, bevor ich mich da reingelesen habe. GoTo finde ich auch nicht so besonders toll, aber was break und continue angeht, da bin ich Fan von. Gerade weil man damit if/else Konstukte in Schleifen entschachteln kann. Das ist viel Menschen freundlicher, da hat man nämlich alles auf einen Blick, und nicht erst 10 Zeilen später.
Und wenn man bei (hässlich) in sich verschachtelten Schleifen nicht durchsiehst, dann refactort man das einfach in eine aussagekräftige Funktion. Und schon hat man wieder den Überblick.