Calling a function inside a function in C

348 Views Asked by At

I've been trying to code a program that solves quadratic equations. Everything seemed fine to me, but the functions I try to go again didn't start after I'd called them. I can't understand what I made wrong.

#include <stdio.h>
#include <math.h>

int main(){
    float a, b, c, delta, x1, x2;
    char YN;
    void enter(){
        printf("Insert the value of 'a':\n");
        scanf("%f", &a);
        printf("Insert the value of 'b':\n");
        scanf("%f", &b);
        printf("Insert the value of 'c':\n");
        scanf("%f", &c);
        delta = (b*b) - (4 * a * c);
        x1 = (-b-sqrt(delta))/(2*a);
        x2 = (-b+sqrt(delta))/(2*a);
    }

    void solve(){
        if (delta > 0){
            printf("The first root of the equation is %f.", x1);
            printf("The second root of the equation is %f.", x2);
        }
        else if (x1 == x2){
            printf("The only root of the equation is %f.", x1);
        }
        else{
            printf("The equation has no real roots.");
        }
    }

    void input(){
        scanf("%c", &YN);
    }

    void check(){
        if (YN == 'Y'){
            solve();
        }
        else if (YN == 'N'){
            enter();
        }
        else {
            input();
        }
    }

    enter();
    printf("Your equation must be: %f x^2 + %f x + %f, is it correct? Type Y for yes, N for no.\n", a, b, c);
    input();
    check();
    return 0;
}

Because I thought the variables make the function not work, I tried having variables outside the solve function, but it didn't really work.

3

There are 3 best solutions below

5
Matthew G On BEST ANSWER

In standard C, you cannot define functions inside other functions. Instead, you must declare/define your functions separately outside of main().

Additionally, you can have global variables that can be accessed "globally" by all of your functions. They are not scoped to a specific function. To do this, declare them outside of your main function.

There are a few issues with this:

  1. It is not recommended to have all of your variables global. Instead of referencing global variables, learn how to use function parameters and pass by reference. You could clean this up by having your functions return values as well.
  2. In my opinion the functions you have here don't need to be in their own functions. They could be all included in your main function.

Here is an example of your code with the correct formatting:

#include <stdio.h>
#include <math.h>

// Function Declarations here
void enter();
void solve();
void input();
void check();

// Global Variables
float a, b, c, delta, x1, x2;
char YN;

int main(){
    enter();
    solve();
    input();
    check();

    enter();
    printf("Your equation must be: %f x^2 + %f x + %f, is it correct? Type Y 
       for yes, N for no.\n", a, b, c);
    input();
    check();
    return 0;
}

// Function Definitions here

void enter(){
        printf("Insert the value of 'a':\n");
        scanf("%f", &a);
        printf("Insert the value of 'b':\n");
        scanf("%f", &b);
        printf("Insert the value of 'c':\n");
        scanf("%f", &c);
        delta = (b*b) - (4 * a * c);
        x1 = (-b-sqrt(delta))/(2*a);
        x2 = (-b+sqrt(delta))/(2*a);
}

void solve(){
    if (delta > 0){
       printf("The first root of the equation is %f.", x1);
       printf("The second root of the equation is %f.", x2);
    }
    else if (x1 == x2){
       printf("The only root of the equation is %f.", x1);
    }
    else{
       printf("The equation has no real roots.");
    }
}

void input(){
    scanf("%c", &YN);
}

void check(){
    if (YN == 'Y'){
       solve();
    }
    else if (YN == 'N'){
       enter();
    }
    else {
       input();
    }
}
0
0___________ On

You have plenty issues here.

  1. Nested functions.
  2. You do not use parameters and return values of functions
  3. Bad function logic (in your case only input functions make sense). Generally logic is very poor
  4. You do not check delta before taking the square root.
double getFloatValue(const char *message)
{
    double f;
    do 
    {
        printf("\n%s", message);
    }while(scanf("%lf", &f) != 1);
    return f;
}

char getChar(const char *message)
{
    int c;

    printf("%s", message);
    do
    {
        c = fgetc(stdin);
        if(c == EOF) 
        {
            c = 'N';
            break;
        }
        c = toupper((unsigned char)c);

    }
    while(!isalpha((unsigned char )c) && c != 'Y' && c != 'N');
    return c;
}

int main(){
    double a, b, c, delta, x1, x2;
    char YN;

    do 
    {
        a = getFloatValue("Enter a:");
        b = getFloatValue("Enter b:");
        c = getFloatValue("Enter c:");

        printf("\nEquation: %f * X^2 %+f * X %+f\n", a, b, c);

        delta = (b*b) - (4 * a * c);
        if(delta >= 0)
        {
            x1 = (-b-sqrt(delta))/(2*a);
            x2 = (-b+sqrt(delta))/(2*a);
            if(x1 == x2) 
            {
                printf("The only root of the equation is %f.\n", x1);
            }
            else
            {
                printf("The first root of the equation is %f.\n", x1);
                printf("The second root of the equation is %f.\n", x2);
            }
        }
        else
        {
            printf("No roots\n");
        }
    }while(getChar("Another equation? (Y/N)") == 'Y');

    return 0;
}

https://godbolt.org/z/jb74M4qWq

0
Craig Estey On

You have nested functions.

Although this is [somewhat] allowed with gcc, it is non-standard. The generated code is ugly/error prone.

Better to just make the vars global scope. Or, restructure your program so you don't need to do this (e.g. pass more items as parameters).


You're trying to do a "lambda" function or "closure".

One way is to have a struct that contains all the variables that were function scoped in main and pass around a pointer to that. Here's a skeletal example:

struct vars {
    float a, b, c, delta, x1, x2;
};

void
enter(struct vars *v)
{
    printf("Insert the value of 'a':\n");
    scanf("%f", &v->a);

    printf("Insert the value of 'b':\n");
    scanf("%f", &v->b);

    printf("Insert the value of 'c':\n");
    scanf("%f", &v->c);

    v->delta = (v->b * v->b) - (4 * v->a * v->c);
    v->x1 = (-v->b - sqrt(v->delta)) / (2 * v->a);
    v->x2 = (-v->b + sqrt(v->delta)) / (2 * v->a);
}

int
main(void)
{
    struct vars vars;

    enter(&vars);
    // ...

    return 0;
}

Note that: "there's no such thing as a free lunch". In languages that support lambda functions (e.g. C++, etc.) the hidden/generated code would be similar to the above.