2017-02-18 5 views
-2

Ich versuche, den Bereich und den Umfang eines Kreises mit Zeigern zu finden. Der richtige Code sieht wie folgt ausZeiger in C, abnormes Verhalten

#include<stdio.h> 

void main(){ 
    int radius; 
    float area, peri; 
    printf("Enter the radius of a circle: "); 
    scanf("%d", &radius); 
    areaperi(radius, &area, &peri); 
    printf("Area is %f\nPerimeter is %f", area, peri); 
} 

areaperi(int r, float *a, float *b){ 
    *a = 3.14*r*r; 
    *b = 2*3.14*r; 
} 

Aber wenn ich den Datentyp des Radius ersetzen zu schweben, während deklarieren und das Scannen des Radius und Änderungstyp von r in areaperi() es mir einen Fehler gibt.

#include<stdio.h> 

void main(){ 
    float radius; 
    float area, peri; 
    printf("Enter the radius of a circle: "); 
    scanf("%f", &radius); 
    areaperi(radius, &area, &peri); 
    printf("Area is %f\nPerimeter is %f", area, peri); 
} 

areaperi(float r, float *a, float *b){ 
    *a = 3.14*r*r; 
    *b = 2*3.14*r; 
} 

[Fehler] Widersprüchliche Typen für areaperi

verwende ich Dev C++.

Ich verstehe nicht, warum mein Code nicht für Fließwert von Radius funktioniert.

+1

Haben Sie Typen in beide Definition des Funktionsprototyp und die Funktion ändern? –

+2

Wenn Sie den Radius-Datentyp ändern, sollte auch der ScanF-Abschnitt geändert werden. – lordofire

+1

Sie haben den Code nicht angezeigt, in dem Sie * den Datentyp * ersetzen. Wie erwarten Sie, dass wir Ihnen sagen, warum es nicht funktioniert, wenn Sie uns nicht zeigen, was Sie getan haben? Wenn Sie möchten, dass wir erklären, warum Ihr Code nicht funktioniert, fügen Sie Ihren Code hinzu. Wir können Ihren Bildschirm nicht sehen, wo wir sind, und wir können Ihre Gedanken nicht lesen. –

Antwort

5

Es ist nicht abnormales Verhalten überhaupt; es ist von der C-Norm gefordert.

An dem Punkt, an dem Sie areaperi() aufrufen, gibt es keinen Prototyp im Bereich für die Funktion. Folglich ist es als eine Funktion sein, die eine int und seine Argumente unterliegen kehrt Promotions DEFAULT - float zu double umgewandelt wird und eine beliebige Integer-Typ kürzer ist als int (so short und char) an int gefördert.

Wenn Sie die Definition von areaperi() zu ändern:

areaperi(float r, float *a, float *b) 

der Typ des ersten Arguments nicht stimmt mehr mit dem abgeleiteten Typ, so dass Sie den Fehler.

Ihre Funktion sollte vor der Verwendung deklariert werden. Es gibt keinen Wert zurück, daher sollte es mit dem Rückgabetyp void deklariert und definiert werden. Auch main() returns an int. Und es ist eine gute Idee, sowohl die Eingabe als auch die berechneten Werte zu wiederholen, zumal der Code nicht prüft, ob der Aufruf erfolgreich war.

Daher benötigen Sie:

#include <stdio.h> 

void areaperi(float r, float *a, float *b); 

int main(void) 
{ 
    float radius; 
    float area, peri; 
    printf("Enter the radius of a circle: "); 
    scanf("%f", &radius); 
    areaperi(radius, &area, &peri); 
    printf("Radius is %f\nArea is %f\nPerimeter is %f", 
      radius, area, peri); 
    return 0; 
} 

void areaperi(float r, float *a, float *b){ 
    *a = 3.14*r*r; 
    *b = 2*3.14*r; 
} 

Der Grund, warum diese Regeln existieren, ist ‚Rückwärtskompatibilität‘ mit Vornorm C.

Beachten Sie, dass C99 und später Funktionen erfordert erklärt werden, bevor sie sind verwendet und verlangt, dass alle Funktionen einen expliziten Rückgabetyp haben. Es empfiehlt sich, dafür zu sorgen, dass die Deklaration tatsächlich ein Prototyp ist. Beachten Sie, dass, wenn Sie void areaperi(); vor main() geschrieben haben, würde es die Funktion deklarieren aber nicht einen Prototyp bereitstellen - es besagt, dass areaperi() eine Funktion ist, die keinen Wert zurückgibt, aber die Argumentliste wird nicht beschrieben und könnte alles außer einer variablen Länge sein Liste der Argumente (diese erfordern einen Prototyp und der Prototyp hat am Ende , ...)).

+1

Also hätte der OP-Code auch ohne den Rückgabetyp und ohne einen Funktionsprototyp funktioniert, wenn sie 'double radius;' (oder sogar 'float radius;') und 'areaperi (double r, float *) verwendet hätten. a, float * b) {} '? (Nicht empfehlen, dass jemand dies tun sollte!) –

+2

@DavidBowling: Ja - unter diesen Bedingungen würde es richtig funktionieren. Ein moderner Compiler würde sich über alle möglichen Dinge lustig machen (vor allem, wenn Sie Warnflags in die falsche Richtung setzen), aber ein C90-Compiler würde Ihre vorgeschlagenen Änderungen akzeptieren und ein gültiges Programm erstellen. (Wir können separat über 'void main()' verhandeln - es ist tangential zu dieser Diskussion.) –

2

Geben forward declaration-areaperi() Funktion und fügen Sie void als Rückgabetyp

#include<stdio.h> 

void areaperi(float r, float *a, float *b); 

void main(){ 
    float radius; 
    float area, peri; 
    printf("Enter the radius of a circle: "); 
    scanf("%f", &radius); 
    areaperi(radius, &area, &peri); 
    printf("Area is %f\nPerimeter is %f", area, peri); 
} 

void areaperi(float r, float *a, float *b){ 
    *a = 3.14*r*r; 
    *b = 2*3.14*r; 
} 
2

versuchen diesen Code

#include<stdio.h> 

void areaperi(float r, float *a, float *b); 
void main() 
{ 
    float radius; 
    float area, peri; 
    printf("Enter the radius of a circle: "); 
    scanf("%f", &radius); 
    areaperi(radius, &area, &peri); 
    printf("Area is %f\nPerimeter is %f", area, peri); 
} 

void areaperi(float r, float *a, float *b){ 
    *a = 3.14*r*r; 
    *b = 2*3.14*r; 
} 
+3

Willkommen bei Stack Overflow. Der Code ist gut, aber Sie sollten wirklich die Änderungen erklären, die Sie vorgenommen haben und warum sie das Problem lösen (oder warum das Fehlen der Änderungen das Problem verursacht). –