"We are back" « oc.at

C Anfänger kommt nicht weiter

noir 25.11.2012 - 22:47 6684 32
Posts

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11343
Zitat von icy
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.


Zitat von icy
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
Registered: n/a
Location:
Posts: n/a
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
Avatar
Registered: Dec 2007
Location: Salzburg/OÖ
Posts: 2314
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 :D

hier mein Code:
Code: C
#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
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11343
Zitat von noir
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.

Zitat von noir
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
Avatar
Registered: Dec 2007
Location: Salzburg/OÖ
Posts: 2314
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
Registered: n/a
Location:
Posts: n/a
Zitat von noir
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
Avatar
Registered: Dec 2007
Location: Salzburg/OÖ
Posts: 2314
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

Code: C
#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
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
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

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25563
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
Avatar
Registered: Nov 2002
Location: OÖ/RI
Posts: 5262
My fault, doch schon zu lange her..

noir

Overclocking Team Member
Avatar
Registered: Dec 2007
Location: Salzburg/OÖ
Posts: 2314
@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

Zitat von Obermotz
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 :D

AdRy

Auferstanden
Avatar
Registered: Oct 2002
Location: Wien
Posts: 5239
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
Registered: Jun 2004
Location: daham
Posts: 16
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

Administrator
Legends never die
Avatar
Registered: Aug 2003
Location: nö
Posts: 25563
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. :p

Caption

Little Overclocker
Avatar
Registered: May 2006
Location: Tirol
Posts: 120
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...e6073fe2a99a2c6

Also 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)
Code: C
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
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz