-2

I'm trying to find the area and perimeter of a circle using pointers. The correct code looks like this

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

But if I replace the data type of radius to float while declaring and scanning the radius and change type of r in areaperi() it gives me an error.

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

[Error]Conflicting types for areaperi

I use Dev C++.

I don't understand why my code doesn't work for floating value of radius.

  • 1
    Did you change types in both the function prototype and the function definition? – ad absurdum Feb 18 '17 at 06:21
  • 2
    If you change the radius data type, scanf section should also be changed. – lordofire Feb 18 '17 at 06:22
  • 1
    You've not shown the code where you *replace the data type*. How do you expect us to tell you why it's not working when you don't show us what you've done? If you want us to explain why your code isn't working, include your code. We can't see your screen from where we are, and we can't read your mind. – Ken White Feb 18 '17 at 06:23
  • @lordofire Yeah, I've changed in scanf too – Sreevathsa Gowru Feb 18 '17 at 06:23
  • 1
    This can't be actual code. There is no return type for `areaperi()`, and no function prototype (or perhaps `areaperi()` is defined before `main()`?) – ad absurdum Feb 18 '17 at 06:28
  • @DavidBowling: those points are the main reasons for the problem. – Jonathan Leffler Feb 18 '17 at 06:32
  • Did you compile with warning level set to full (`-Wall`)? The compiler warnings tell exactly what the problem is. – JJJ Feb 18 '17 at 06:36

3 Answers3

5

It's not abnormal behaviour at all; it's required by the C standard.

At the point where you call areaperi(), there is no prototype in scope for the function. Consequently, it is deemed to be a function that returns an int and its arguments are subject to default promotions — float is converted to double and any integer type shorter than int (so short and char) are promoted to int.

When you change the definition of areaperi() to:

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

the type of the first argument no longer agrees with the inferred type, so you get the error.

Your function should be declared before it is used. It doesn't return a value, so it should be declared and defined with return type void. Also, main() returns an int. And it is a good idea to echo the input as well as the calculated values, especially as the code doesn't check that the scanf() call was successful.

Hence, you need:

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

The reason these rules exist is 'backwards compatibility' with pre-standard C.

Note that C99 and later requires functions to be declared before they're used, and requires all functions to have an explicit return type. It is good practice to ensure that the declaration is in fact a prototype. Note that if you wrote void areaperi(); before main(), it would declare the function but would not provide a prototype — it says that areaperi() is a function that returns no value but the argument list is not described and could be anything except a variable-length argument list (those require a prototype and the prototype has , ...) at the end).

Community
  • 1
  • 1
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
  • 1
    So, the OP's code would have worked even without the return type, and without a function prototype, if they had used `double radius;`, (or even `float radius;`), and `areaperi(double r, float *a, float *b){}`? (Not recommending that anyone should do this!) – ad absurdum Feb 18 '17 at 06:53
  • 2
    @DavidBowling: Yes — under those conditions, it would work correctly. A modern compiler would bitch about all sorts of things (especially if you set much in the way of warning flags), but a C90 compiler would accept your proposed modifications and create a valid program. (We can negotiate separately about `void main()` — it is tangential to this discussion.) – Jonathan Leffler Feb 18 '17 at 06:55
2

Give forward declaration to areaperi() function and add void as return type

#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;
}
jophab
  • 4,386
  • 9
  • 37
  • 54
2

try this 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;
}
jophab
  • 4,386
  • 9
  • 37
  • 54
  • 3
    Welcome to Stack Overflow. The code is good, but you should really explain the changes you made and why they solve the problem (or why the absence of the changes causes the problem). – Jonathan Leffler Feb 18 '17 at 06:44