myGully.com

myGully.com (https://mygully.com/index.php)
-   Programmierung (https://mygully.com/forumdisplay.php?f=67)
-   -   Fehlersuche in C (https://mygully.com/showthread.php?t=2224792)

fontsix 05.02.11 19:18

Fehlersuche in C
 
Hallo zusammen ich bin dabei mich auf eine kommende Klausur vorzubereiten. In diesem Programm sollen 10 Fehler sein, wovon ich bereits 9 gefunden habe. Daher erscheinen also auch manche Stellen als fehlerfrei, also bitte nicht wundern. Nun suche ich allerdings schon hartnäckig seit einer Weile den 10. Fehler. Ich vermute folgende Geschichte, p ist ja als Zeiger deklariert, in einer Zeile wird dann allerdings p=a; gesagt, der Compiler meckert aber nicht, und in der Zeile mit dem
PHP-Code:

 scanf("%lf",p++); 

kommt mir irgendetwas spanisch vor, p ist ja nicht als variable deklariert und ist es möglich innerhalb des scanf-Befehls irgendetwas hochzählen zu lassen ? Das ergibt für mich keinen Sinn. Würde mich freuen wenn jemand helfen kann.

Liebe Grüße Marcel

PHP-Code:

#include<stdlib.h>    // #include<stdlib.h> fehlt    - 1. Fehler
#include<stdio.h>    // #include<stdio.h>    -    2. Fehler
#include<math.h>
#define DIM 30            // #define DIM 30        -    3. Fehler
/* Mittelwerter und der Streuung von Messungen*/
int main()
int i,n;
  
double a[DIM],s1,s2,mw,str,*p;
  
printf("\nEingabe von n ");
  
scanf("%d",&n);        // scanf("%d",&n); oder scanf("%i",&n);        -    4. Fehler
  
if (n>DIM)
  { 
fprintf(stderr,"Die Dimension ist zu gross");    // fprintf(stderr,"Die Dimension ist zu gross");        -    5. Fehler
    
exit(2);
  }
  
p=a;  
  for (
i=0;i<n;i++)
  { 
printf("\nEingabe von a[%2d] ",i);        // printf("\nEingabe von a[%2d] ",i);    -    6. Fehler
    
scanf("%lf",p++);    
  }
  
s1=s2=0;
 
  for (
i=0;i<n;i++)
  { 
s1+=a[i];
    
s2+=a[i]*a[i];        // s2+=a[i]*a[i];        -    7. Fehler
  
}
  
mw=s1/n;            // mw=s1/n;        -    8. Fehler
  
str=sqrt((s2-n*mw*mw)/(n-1));        //  str=sqrt((s2-n*mw*mw)/(n-1));        -    9. Fehler
  
printf("\nMittelwert = %lf",mw);
  
printf("\nStreuung = %lf",str);
  return 
0;
  } 


germgerm 05.02.11 19:58

Zitat:

Zitat von fontsix (Beitrag 21872679)
... Ich vermute folgende Geschichte, p ist ja als Zeiger deklariert, in einer Zeile wird dann allerdings p=a; gesagt, der Compiler meckert aber nicht, und in der Zeile mit dem
PHP-Code:

 scanf("%lf",p++); 

kommt mir irgendetwas spanisch vor, p ist ja nicht als variable deklariert und ist es möglich innerhalb des scanf-Befehls irgendetwas hochzählen zu lassen ? Das ergibt für mich keinen Sinn. ...

Ob du scanf eine Referenz oder einen Pointer übergibst (der auf etwas zeigt), kommt auf das Gleiche hinaus. Also, das müsste passen.
Funktionen können in C sehr verschachtelt, werden. Daher passt das p++ auch.
Das bedeutet, dass zuerst scanf ausgeführt wird und danach p erhöht wird.
Bei ++p wäre es umgekehrt.

Was meiner Meinung nach falsch ist:
Bei n=0 oder n=1 gibt es eine Division durch Null.

fontsix 05.02.11 20:34

Das Programm ist dazu gedacht um den Mittelwert und die Streuung von Messwerten zu errechnen, wobei n die Anzahl der Messwerte darstellt.

Die Formel für die Streuung steht so in der Form in guten Messtechnik Büchern. Wenn n=0 oder n=1 wäre ja sinnlos, aus keinem Messwert kann ich auch keinen Mittelwert und keine Streuung bilden und aus einem Messwert auch nicht. Das ist nicht der Fehler.

germgerm 06.02.11 07:26

Zitat:

Zitat von fontsix (Beitrag 21872994)
wobei n die Anzahl der Messwerte darstellt.

Ist mir klar gewesen.

Zitat:

Zitat von fontsix (Beitrag 21872994)
Die Formel für die Streuung steht so in der Form in guten Messtechnik Büchern. Wenn n=0 oder n=1 wäre ja sinnlos, aus keinem Messwert kann ich auch keinen Mittelwert und keine Streuung bilden und aus einem Messwert auch nicht. Das ist nicht der Fehler.

Die Formeln stimmen. Trotzdem ist es ein Programmfehler, der zu Abstürzen führen kann. Unsinnige Eingaben gehören entweder abgefangen bzw bei jeder Berechnung mit einer Division muss sichergestellt sein, dass nichts passieren kann.

flotti 07.02.11 11:21

p = a; // der zeiger zeigt auf das erste feld des arrays
p = &a[0] // wäre eindeutiger gewesen, ist aber so völlig richtig

scanf("%lf",p++); // mit p++ wird der zeiger nach aufruf von scanf ein feld (also die größe eines doubles) weitergeschoben

man hätte auch scanf("%lf",&a[i]); schreiben können

aber nen fehler kann ich leider auch nicht finden ^^'
aber das mit dem n = 0 sollte man wirklich abfangen

lds17pl 07.02.11 20:15

copy & past des Quelltextes in die DEV-C++ IDE (freier C++ Compiler hier [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...])
- Compiler & Linker: keine Fehler
- Eingabe Werte (Anzahl Werte <31) o.k => Ausgabe: NICHTS!!!!

Modifikation 1: Hilfsvariable temp[80] definiert sowie 2x gets(temp) (Einlesen eines leeren Strings mit "CR" = Enter):
1) s1=s2=0;gets(temp);
2) printf("\nStreuung = %lf",str);gets(temp);
=> es wird nur 1x CR nach Ausgabe von Mittelwert und Streuung verlangt
=> wird das 1. gets(temp) auskommentiert ("// gets(temp)" erfolgt ebenfalls KEINE Ausgabe und KEIN Stop

Modifikation 2:
zusätzliches gets(temp) nach Meldung "Die Dimension ist zu gross")
=> kein Stop bei Eingabe > 30

Modifikation 3:
scanf("%lf",a[i]) statt (auskommentiertem) scanf("%lf",p++)
=> Programmabsturz

Seltsam ist weterhin, daß im Debug die jeweils aktuellen Werte a[],s1,s2,mw,str,*p
bei zeilenweiser Ausführung nicht angezeigt werden können (Watch-Funktion) :confused:
:(

germgerm 08.02.11 12:06

@lds17pl

Ich verstehe nicht, warum es bei dir nicht funktionieren soll.
Läuft mit mingw und vc++ ohne Modifikationen.

Bei Mod3 musst du eine Referenz angeben:

Code:

scanf("%lf",&a[i])
Bzw. den Code lassen wie er oben war ^^

lds17pl 08.02.11 18:48

Richtig! :T die Referenz fehlt bei scanf(...)

aber darum geht es im Grunde nicht - ich versuchte den 10. Fehler einzugrenzen :(


Es bleibt :confused:

germgerm 08.02.11 18:57

Für mich ist es ein schwerer Fehler eine Division durch Null zuzulassen.

wmosebach 08.02.11 21:44

Zitat:

Zitat von germgerm (Beitrag 21886133)
Für mich ist es ein schwerer Fehler eine Division durch Null zuzulassen.

Dies sollte definitiv bei der Eingabe abgefangen werden. Im Fall von n=1 || n = 0 springt dir dein Programm im Dreieck. Wenn das kein Fehler ist, weiß ich auch nicht... ;)

wmosebach 10.02.11 15:17

Zitat:

s1=s2=0;
man könnte dies noch ankreiden. Da es sich um doubles handelt könnte man auch sagen s1=s2=0.0;
Ob dies Vorschrift ist, weiß ich aber auch nicht genau...

germgerm 10.02.11 15:31

Zitat:

Zitat von wmosebach (Beitrag 21893729)
man könnte dies noch ankreiden. Da es sich um doubles handelt könnte man auch sagen s1=s2=0.0;
Ob dies Vorschrift ist, weiß ich aber auch nicht genau...

Kein Fehler.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:00 Uhr.

Powered by vBulletin® (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.