2017-02-18 2 views
-2

Я пытаюсь найти область и периметр круга с помощью указателей. Правильный код выглядит следующим образомУказатели на C, ненормальное поведение

#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; 
} 

Но если я заменю тип данных радиуса плавать при декларировании и сканирования радиуса и изменений типа r в areaperi() он дает мне ошибку.

#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; 
} 

[Ошибка] Конфликтующие типы для areaperi

Я использую Dev C++.

Я не понимаю, почему мой код не работает для плавающего значения радиуса.

+1

ли вы изменить типы как в прототипе функции и определения функции? –

+2

Если вы изменяете тип данных радиуса, необходимо также изменить секцию scanf. – lordofire

+1

Вы не указали код, в котором вы * замените тип данных *. Как вы ожидаете, что мы скажем вам, почему он не работает, когда вы не показываете нам, что вы сделали? Если вы хотите, чтобы мы объяснили, почему ваш код не работает, укажите ваш код. Мы не можем видеть ваш экран с того места, где мы находимся, и мы не можем читать ваши мысли. –

ответ

5

Это не ненормальное поведение на всех; это требуется по стандарту C.

В данный момент, когда вы звоните areaperi(), прототип функции отсутствует. Следовательно, считаются функция, которая возвращает int и его аргументы могут быть по умолчанию акции - float преобразуется в double и любом целом типе короче, чем int (так short и char) повышается до int.

При изменении определения areaperi() к:

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

типа первого аргумента больше не согласуется с выведенным типом, так что вы получите сообщение об ошибке.

Ваша функция должна быть объявлена ​​до ее использования. Он не возвращает значение, поэтому он должен быть объявлен и определен с возвратом типа void. Также main() returns an int. И это хорошая идея, чтобы эхо ввода, а также рассчитанные значения, особенно, поскольку код не проверяет, что вызов scanf() был успешным.

Следовательно, вам нужно:

#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; 
} 

Причина существуют эти правила есть «обратная совместимость» с предварительным стандартом C.

Обратите внимание, что C99, а затем требует функции должны быть объявлены прежде, чем они используется и требует, чтобы все функции имели явный тип возврата. Это хорошая практика, чтобы убедиться, что декларация на самом деле является прототипом. Обратите внимание, что если вы написали void areaperi(); до main(), оно объявило бы функцию, но не предоставит прототип - он говорит, что areaperi() - это функция, которая не возвращает никакого значения, но список аргументов не описывается и может быть чем угодно, кроме переменной длины список аргументов (для прототипа требуется прототип, а в конце прототип - , ...)).

+1

Итак, код OP работал бы даже без возвращаемого типа и без прототипа функции, если бы они использовали 'double radius;' (или даже 'float radius;') и 'areaperi (double r, float * a, float * b) {} '? (Не рекомендуется, чтобы кто-то это делал!) –

+2

@DavidBowling: Да - в этих условиях он будет работать правильно. Современный компилятор будет судить обо всех вещах (особенно если вы ставите много на пути предупреждающих флагов), но компилятор C90 согласится с вашими предлагаемыми модификациями и создаст действительную программу. (Мы можем обсуждать отдельно о 'void main()' - это касательно этого обсуждения.) –

2

Дайте forward declaration на areaperi() функцию и добавить void в качестве возвращаемого типа

#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

попробуйте этот код

#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

Добро пожаловать в Stack Overflow. Код хорош, но вы должны действительно объяснить сделанные вами изменения и почему они решают проблему (или почему отсутствие изменений вызывает проблему). –

Смежные вопросы