that
Hoffnungsloser Optimist
|
Ist ein Aufruf von main erlaubt? #120 Prinzipiell ist das erlaubt, aber hier nicht richtig - wenn man das ein paar tausendmal macht, geht der Stack über. Kann man gegen die Warnung etwas tun? shit.c:27:7: warning: implicit declaration of function ‘__fpurge’ [-Wimplicit-function-declaration] Ja, den Header inkludieren, der die Methode deklariert.
|
Guest
Deleted User
|
Hab mal den Aufruf auf main in main entfernt und eine Funktion draus gemacht und einen Header hinzugefügt. Kompiliert jetzt ohne Warnings. gcc -Wall -lm shit.c -o shit http://pastebin.com/j2bLZghF
Bearbeitet von am 27.11.2012, 08:40
|
noir
Overclocking Team Member
|
so habs nun mehr oder weniger "allein" geschaft mit Hilfe eurer Tipps, Galileo open book, etwas Vorlesungs Zeugs aus der FH welches ich freundlicher weise von icy bekommen habe und 2 richtungsweisenden Tipps vom Lehrer die wir (meine Klasse) gestern bekommen haben. Es hat mich ungefähr 20-30 Stunden gekostet dif. Bücher und Unterlagen zu durchforsten und daraus den Code zu basteln Und ja ich meine basteln denn mit flüssigem schreiben oder "Coden" hat das mit Sicherheit nix zu tun gehabt  hier mein Code: #include <stdio.h>
#include <stdlib.h>
#define Zero 48
#define One 49
int main()
{
int ziffer, //Variable für die Ziffernstelle
binaerZiffer, //Var. für die Binaerziffer
dezimalZahl, //Var. für die Dezimalzahl
zweierpotenz, //Var. für die Zweierpo.
ok; //Var. für die Eingabewiderh.
char janein; //Wiederholung der Berechnung
printf("Binaer Nibble to Dezimal converter");
do
{
dezimalZahl = 0;
zweierpotenz = 8;
printf ("\n 4Binaer-Ziffern eingeben: ");
for (ziffer = 1; ziffer <= 4; ziffer++)
{
ok = 0;
do
{
binaerZiffer = getche();
switch (binaerZiffer)
{
case Zero: ok = 1; break;
case One: ok = 1; break;
default: ok = 0;
printf ("\7Nur 0 oder 1 eingeben!!\n");
}//ende switch
}while (ok == 0);//ende do in for
binaerZiffer = binaerZiffer - 48;
dezimalZahl = dezimalZahl + binaerZiffer * zweierpotenz;
zweierpotenz = zweierpotenz / 2;
} //ende for-schleife
printf ("\n \t Dezimalwert: %d\n", dezimalZahl);
do
{
printf("Wollen Sie die Berechnung wiederholen?: (Ja...j, Nein...n eingeben)");
janein = getche();
janein = toupper(janein);
printf("\n");
if (janein != 'J' && janein != 'N')
{
printf("\b Fehler, nur j oder n eingeben!\n");
}
}while (janein != 'J' && janein != 'N');//ende do für abbruchbedingung
}while (janein == 'J');
return 0;
}
jetzt hätte ich nur noch eine Frage: wieso kann ich das Ganze mit der Bloodsheed IDE ohne errors und warnings compillen und bei CodeBlocks bekomme ich r to Dezimal\Bin to Dez on codeblocks\Bin to Dez\main.c||In function 'main':| r to Dezimal\Bin to Dez on codeblocks\Bin to Dez\main.c|34|warning: implicit declaration of function 'getche'| r to Dezimal\Bin to Dez on codeblocks\Bin to Dez\main.c|60|warning: implicit declaration of function 'toupper'| ||=== Build finished: 0 errors, 2 warnings ===| nochmals danke an alle
|
that
Hoffnungsloser Optimist
|
wieso kann ich das Ganze mit der Bloodsheed IDE ohne errors und warnings compillen und bei CodeBlocks bekomme ich Die Fehlermeldungen kommen vom Compiler, die IDE hat damit nichts zu tun. r to Dezimal\Bin to Dez on codeblocks\Bin to Dez\main.c||In function 'main':| r to Dezimal\Bin to Dez on codeblocks\Bin to Dez\main.c|34|warning: implicit declaration of function 'getche'| r to Dezimal\Bin to Dez on codeblocks\Bin to Dez\main.c|60|warning: implicit declaration of function 'toupper'| Du hast vergessen, die Headerfiles einzubinden, die die aufgerufenen Funktionen deklarieren. Für toupper ist das ctype.h, und wo getche ist musst du selbst herausfinden, weil das nicht zum Standard gehört.
|
noir
Overclocking Team Member
|
das ist zwar einleuchtend aber der selbe code in Bloodsheed 0 Fehler 0 Warnungen die beiden IDE's nutzen ja beide den selben compiler sprich GCC wenn ich das ganze via Bloodshed compile läuft es und mit CodeBlocks nicht
|
Guest
Deleted User
|
das ist zwar einleuchtend aber der selbe code in Bloodsheed 0 Fehler 0 Warnungen die beiden IDE's nutzen ja beide den selben compiler sprich GCC wenn ich das ganze via Bloodshed compile läuft es und mit CodeBlocks nicht Der Compiler kann andere flags bekommen und demnach mehr oder weniger Fehler ausgeben. Vielleicht nimmt er in Bloodshed auch einfach die header automatisch mit rein wenn er erkennt das welche fehlen. Am besten im Forum von den Bloodshed Entwicklern fragen, falls die eines haben. Besser wäre es denke ich das manuell zu kompilieren, ohne eine IDE. Für getche() brauchst du wohl conio.h (habe es nicht getestet).
|
noir
Overclocking Team Member
|
So bräuchte wieder mal euren Rat Selbes Programm anderer Aufbau Ich habe Probleme mit einem Pointer und zwar bekomme ich immer diese Fehlermeldung: In funktion 'calc' 109 C:\Dev-Cpp\BinToDez in Funktionen\main.c [Warning] assignment makes integer from pointer without a cast und zwar für Zeile 109, 112, 115, 118, 121 In Zeile 100 versuche ich ein Array welches ich in Zeile 38 initialisiert habe an einen Pointer zu übergeben und da dürfte irgendwas nicht passen nur komme ich nicht drauf was #include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <conio.h>
void header(void); //Überschrift
char get_jn(void); //Funktion für Programmwiederholung
int get_nibble(void); //Funktion zum einlesen des Binaernibble
int calc(void); //Funktion für die Umrechnung von Bin to Dez
void output(void); //Ausgabe
int *ptr = 0; //Pointer in dem eingentlich der Nibble gespeichert werden sollte
int *erg = 0; //Pointer für das Ergebnis
int main()
{
do
{
header ();
get_nibble ();
calc ();
output ();
}while(get_jn () == 'J' );
return 0;
}
void header(void)
{
printf("Programm zur umrechnung eines Binaernibbles in eine Dezimalzahl");
printf("\n\n\n");
}
int get_nibble(void)
{
int control;
int i[4];
printf("Bitte geben Sie den Binaernibble ein: ");
do{
scanf ("%d", &i[0]);
switch (i[0])
{
case 0: control = 1;
break;
case 1: control = 1;
break;
default: control = 0;
printf("Falsche Eingabe!");
}
}while (control == 0);
do{
scanf ("%d", &i[1]);
switch (i[1])
{
case 0: control = 1;
break;
case 1: control = 1;
break;
default: control = 0;
printf("Falsche Eingabe!");
}
}while (control == 0);
do{
scanf ("%d", &i[2]);
switch (i[0])
{
case 0: control = 1;
break;
case 1: control = 1;
break;
default: control = 0;
printf("Falsche Eingabe!");
}
}while (control == 0);
do{
scanf ("%d", &i[3]);
switch (i[3])
{
case 0: control = 1;
break;
case 1: control = 1;
break;
default: control = 0;
printf("Falsche Eingabe!");
}
}while (control == 0);
printf("Sie haben %d%d%d%d eingegeben.", i[0], i[1], i[2], i[3]);
ptr = i;
return 0;
}
int calc()
{
int zweierpotenz = 8;
int bin1, bin2, bin3 ,bin4;
bin1 = ptr+0 * zweierpotenz;
zweierpotenz = zweierpotenz / 2;
bin2 = ptr+1 + zweierpotenz;
zweierpotenz = zweierpotenz / 2;
bin3 = ptr+2 * zweierpotenz;
zweierpotenz = zweierpotenz / 2;
bin4 = ptr+3 * zweierpotenz;
zweierpotenz = zweierpotenz / 2;
erg = bin1 + bin2 + bin3 + bin4;
return 0;
}
void output(void)
{
printf("\n%d", erg);
}
char get_jn()
{
char jn;
do
{
printf ("Wollen Sie die Berechung wiederholen? (n...Nein, j...Ja)");
jn = getche ();
jn = toupper (jn);
printf ("\n");
if (jn != 'N' && jn != 'J')
{
printf ("Fehler");
}
}while (jn != 'N' && jn != 'J');
return jn;
}
Ich weis an dieser Version kann man noch einiges verbessern aber vorerst wäre es mir wichtig das ich diesen Fehler mit dem Pointer mal behebe gleichmal vorab danke für eure Hilfe
|
Obermotz
Fünfzylindernazi
|
C nimmt an, dass du die Adresse von ptr in Integer casten und anschließend damit rechnen willst. -> * wenn du auf Inhalte zugreifst..
Und vergiss nicht: Don't repeat yourself! Mittels Schleifen könntest du deinen Code um zwei Drittel kürzen..
Bearbeitet von Obermotz am 10.03.2013, 17:37
|
mat
AdministratorLegends never die
|
Er will ja den Pointer vom Array, das passt also schon. Ich hab jetzt nur ganz kurz drübergeschaut, aber ich glaub du musst einfach nur die Zeile 100 so ausschauen lassen:
ptr = (int *) i;
Btw, Pointer solltest du immer auf NULL setzen, nicht auf 0.
|
Obermotz
Fünfzylindernazi
|
My fault, doch schon zu lange her..
|
noir
Overclocking Team Member
|
@mat also ich hätte jetzt die Zeile 100 nach deinen Angaben geändert und auch die 0 in eine NULL aber der Fehler ist immer noch der gleiche C nimmt an, dass du die Adresse von ptr in Integer casten und anschließend damit rechnen willst. -> * wenn du auf Inhalte zugreifst..
Und vergiss nicht: Don't repeat yourself! Mittels Schleifen könntest du deinen Code um zwei Drittel kürzen.. Ich versteh das einfach nicht erstens hätte ich ja am Anfang den Pointer schon mit 'int' initialisiert das Array wurde ja auch als 'int' initialisiert also wo soll hier die Typumwandlung sein? Das ich den Code mittels Kontrollstrukturen um einiges effizienter machen könnte ist mir klar aber ich wollte jetzt einfach nur mal das der Code läuft im bezug auf die Pointer und Arrys und dann kann ich mich in ruhe mit den Schleifen ärgern
|
AdRy
Auferstanden
|
Ich zwar schon länger her, dass ich was mit C gemacht hab. Die Fehlermeldung ssagt doch eh alles: Imho ist das problem bei den Zeilen die Fehler geben, dass bin 1, bin 2, usw.. als int deklariert sind, ptr ist aber ein pointer. Du kannst ned einen pointer in eine int variable schreiben.
|
TTH
Bloody Newbie
|
Ich muss zugeben, mein letztes C Projekt is schon länger als ein Jahr her, aber nach der von dir beschriebenen Fehlermeldung würd ich mal folgendes versuchen: Ersetze in zeile 109
bin1 = ptr+0 * zweierpotenz; mit bin1= *(ptr+0) * zweierpotenz;
Wie gesagt, ich hab zulange nimma mit C gearbeitet um mir noch sicher zu sein, aba so hätte ich auf die Inhalte des Arrays zugegriffen.
hth TTH
|
mat
AdministratorLegends never die
|
Was machst du eigentlich mit dem globalen Pointer von einem lokalen Array? Wenn du die Daten global nutzen möchtest, dann muss du das Array am besten mit memcpy() oder per for-Schleife kopieren. Oder du initialisierst das Array gleich global. Edit: In dem Code ist einiges falsch, wenn ich mir das so genau ansehe.
|
Caption
Little Overclocker
|
1. Du erstellst in der get_nibble(void) eine lokale Variable/Array i, speicherst dir den Pointer drauf und verwendest den Inhalt AUSSERHALB des scopes -> lesen: http://openbook.galileocomputing.de...e6073fe2a99a2c6Also entweder dynamisch Speicher allokieren (malloc) und Pointer drauf returnen oder Pointer von außen mitgeben. Letzteres ist zum starten einfacher. 2. Ich glaub du hast einfach in Zeile 109 einmal dereferenzieren vergessen. Also ptr[0] oder *(ptr+0) oder *ptr. Aber das kannst vergessen so lang Punkt 1 nicht gefixt ist. Edit: ein Vorschlag zu 1. * int i[4] wandert in die main() * void get_nibble(int *i) wird der Pointer übergeben * das gleiche bei void calc(int *i) (damit ersetzt die ptr variable) int main()
{
int i[4];
do
{
header ();
get_nibble (i);
calc (i);
output ();
...
void get_nibble(int *i)
{
int control;
...
void calc(int *i)
{
int zweierpotenz = 8;
int bin1, bin2, bin3 ,bin4;
bin1 = i[0] * zweierpotenz;
...
Das Prinzip dahinter - call-by-reference - http://openbook.galileocomputing.de..._zeiger_006.htm
Bearbeitet von Caption am 10.03.2013, 19:42
|