Pointer for C functions is not calling

Asked

Viewed 161 times

2

I’m having a problem with function pointers. I declared the pointers and stored them in an array, but when calling the functions through the pointers the compiler has an error that I have not yet been able to identify.

I am using IDE Code::Blocks 17.12 on Windows 7.

Follows the code:

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

#define PI 3.14

void circunferenciaCirculo(double raio);
void areaCirculo(double raio);
void volumeEsfera(double raio);

int main()
{
system("color 3");
void (*calculo[3])(double raio) =   
                  {circunferenciaCirculo,areaCirculo,volumeEsfera};
int sentinela = 0;
double raio = 0.0;

while(sentinela != 4){

    system("cls");
    printf("Opcoes de calculo\n\n1-Circunferencia de circulo\n2-Area de 
    circulo\n3-Volume de esfera\n4-Sair\n\nOpcao:");
    scanf("%d",&sentinela);

    switch(sentinela){

    case 1:
       system("cls");
       printf("Digite o raio:");
       scanf("%lf",&raio);
       calculo[0];
       break;


    case 2:
        system("cls");
        printf("Digite o raio:");
        scanf("%lf",&raio);
        calculo[1];
        break;

    case 3:
        system("cls");
        printf("Digite o raio:");
        scanf("%lf",&raio);
        calculo[2];
        break;

    default:
        printf("Opcao invalida!\n");
        system("PAUSE");
        break;

    }

}

return 0;
}

Note: I only posted the code of main(), if you need to place the function statement I edit after.

Besides this problem I’m having, I also have other doubts about pointer to functions.

1) Is there any performance difference between calling the function normally and calling through pointers?

2) Where function pointers are used?

2 answers

4


The biggest problem is that you are not calling any function, the call always occurs with the parentheses, equal to a normal function, in this case the variable name is equal to what would be the function name. But there are several other things that can be improved in your code, including eliminating the switch, so it makes a little more sense to use this form. What I would not use under normal conditions, there is no need in this case, a switch with direct calls would be more efficient, readable without compromising functionality, although it is interesting as an exercise. I just hope it doesn’t turn into an addiction.

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

#define PI 3.14

void circunferenciaCirculo(double raio);
void areaCirculo(double raio);
void volumeEsfera(double raio);

int main() {
    system("color 3");
    void (*calculo[3])(double raio) = {circunferenciaCirculo, areaCirculo, volumeEsfera};
    int sentinela = 0;
    while (sentinela != 4) {
        system("cls");
        printf("Opcoes de calculo\n\n1-Circunferencia de circulo\n2-Area de circulo\n3-Volume de esfera\n4-Sair\n\nOpcao:");
        scanf("%d", &sentinela);
        if (sentinela < 1 || sentinela > 4) {
            printf("Opcao invalida!\n");
            system("PAUSE");
            continue;
        }
        if (sentinela == 4) break;
        system("cls");
        printf("Digite o raio:");
        double raio = 0.0;
        scanf("%lf", &raio);
        calculo[sentinela - 1](raio);
    }
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

It can get better.

  1. Is there any performance difference between calling the function normally and call through pointers?

Yes, there is a indirect extra pointer. Although it can be trivial in certain situations, it can cost a lot in others, especially in the first call or in subsequent calls after a long time, where the load of the address where the function is in memory and no longer in cache, which is a rather slow operation. Optimization nowadays in most of the problems we solve is more saving memory access than saving processing cycles, and it tends to get worse with non-volatile memories that may have RAM a little slower in benefits of having auto persistence and very fast.

The call to the function is already an indirect, almost obligatory.

  1. In which function pointers are used?

Whenever you need to determine later which exact function to perform.

I usually say that there are only two reasons to leave a dynamic execution, that is to say only solved at runtime:

  • missing information at compile time.

    It will only be available when the code is running, whether by user typing, coming from external sources like files, databases, networks or other forms of data entry, including, of course, devices that convert analog signal to digital like cameras, microphones and other sensors.

    In some cases the information may be available before execution but after normal compilation. It is possible to make optimizations, but it usually does not pay. In others it may be. There are cases that use profile guided Optimization to change the code, this can be leveraged to optimize other things.

    There are cases that can be solved before, but it is preferable to leave to resolve later to give flexibility to the system, this is not mandatory to solve at execution time, but is usually a solution adopted, for me abusively in many cases, but has some justification.

  • Many execution variations that to solve at compile time would generate many execution paths that could even save execution cycles by eliminating some decisions and searches for data at run time, but with much more different code to run dirty-If too much chance making small context changes require access to RAM when processor memory that is much faster could have what it needs to perform. This applies to loop repetitions, object specializations and functions.

    If you know that they will have few repetitions of a small body it may be interesting to unroll the repetition, and good compilers do it for you, but it does not compensate for many. The same goes for working with several objects with similar but not identical structures (inheritance). It can be faster if you have different instances for each type but only if it is certainly 1, 2, 3 or 4, much who knows 5. If you have many it is better to use an indirect. The same goes for functions.

    If you know what function you want to call you don’t have to think of pointer to function. If you create something generic that can have N different functions being called at a given time it may be better to use the pointer, so there is only one code that takes which function you should execute at that moment according to the pointer and makes the call. If you only have 4 possibilities it may be more interesting to create 4 different algorithms that do the same thing but when calling the function you want to call a different one in each of these code instances. There’s language that makes it so easy, like C++. Others have to do in hand and generates repetition, in some cases even violates the DRY.

    This decision is always a convenience and/ or optimization and not an absolute need as is the previous reason.

    The normal function call can be "optimized" and eliminate all indirect, but would have to copy the function code at each location where it would be called. In some cases it can compensate for that some compilers do inline when pays off, or may be forced to make, but if you exaggerate the shot can backfire.

So it’s a way to parameterize the content, that is, you make a function that has a constant address in address variable, as it did in its code, although without real gain, in mine still had the gain of a few lines at the expense of less readability and performance, although negligible for this type of code.

This mechanism is very similar to the one used in object orientation. In the background the polymorphism is like this under the cloths.

  • Very well explained ! Thank you !

0

Your statements and definitions are correct. The problem is time to call the functions via the pointer.

The following lines are having no effect on your code, see:

calculo[0];
...
calculo[1];
...
calculo[2];

They should be amended to:

calculo[0]( raio );
...
calculo[1]( raio );
...
calculo[2]( raio );
  • Really the problem was the parentheses, I managed to solve the problem, obg.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.