function pointers: trying to pass a function as an argument

Pages: 12
Aug 31, 2018 at 2:42pm
If you don't want to use function pointers, then sure, do an if-else and directly call fk_1(x) or fk_2(x), respectively.
Your original post was where you were attempting to pass in a function pointer. If you don't want to do it this way, then don't.

Let's put it this way. The following two programs are equivalent in input/output.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Example program
#include <iostream>
#include <cmath>

double f1(double x)
{
    return x*x*x - 3*x*x + 6*x;   
}

double f2(double x)
{
    return x*x + std::sin(x);   
}

void process(int n)
{
    if (n == 1)
    {
        std::cout << "The answer is: " << f1(0.0) + f1(1.0) + f1(2.0) << "\n";
    }
    else if (n == 2)
    {
        std::cout << "The answer is: " << f2(0.0) + f2(1.0) + f2(2.0) << "\n";
    }

}

int main()
{
    std::cout << "1. Process f1\n"
              << "2. Process f2\n";
              
    int n;
    std::cin >> n;
    
    process(n);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Example program
#include <iostream>
#include <cmath>

double f1(double x)
{
    return x*x*x - 3*x*x + 6*x;   
}

double f2(double x)
{
    return x*x + std::sin(x);   
}

void process(double(*f)(double))
{
    std::cout << "The answer is: " << f(0.0) + f(1.0) + f(2.0) << "\n";
}

int main()
{
    std::cout << "1. Process f1\n"
              << "2. Process f2\n";
              
    int n;
    std::cin >> n;
    
    if (n == 1)
    {
        process(f1);
    }
    else if (n == 2)
    {
        process(f2);   
    }
}


However, I think most would agree that the 2nd program is slightly easier to extend to other functions, and has overall better design because it separates user-input logic from the algorithm's logic itself.
Last edited on Aug 31, 2018 at 3:07pm
Aug 31, 2018 at 3:07pm
Thank you Ganado. I would like to learn how to pass function pointers, so if you could assist me - please let me know what I should do? Or have I done something wrong in the snippet that keskiverto asked mo to fill?
Last edited on Aug 31, 2018 at 3:40pm
Aug 31, 2018 at 3:10pm
I edited my post to show two equivalent programs. One with function pointers, one without. Hope that helps.
Aug 31, 2018 at 3:38pm
Thanks Ganado. I've rewritten my program with two simpson functions each calculating the integral for that specific function (fk_1 or fk_2) taking into account your proposed examples. However, I do have a question is it possible to send a function pointer to simpson(a,b,n, fk_1 or fk_2) and then depending on what is the 4th parameter the simpson function calculates the integral of either fk_1 or fk_2 in one simpson function?
Last edited on Aug 31, 2018 at 3:38pm
Aug 31, 2018 at 3:56pm
is it possible to send a function pointer to simpson(a,b,n, fk_1 or fk_2) and then depending on what is the 4th parameter the simpson function calculates the integral of either fk_1 or fk_2 in one simpson function?
Yes. That's pretty much the entire point of function pointers.

Pass in fk_1 if you want it to use fk_1 as the function for calculation.
simpson(a, b, n, fk_1);
Pass in fk_2 if you want it to use fk_2 as the function for calculation.
simpson(a, b, n, fk_2);

where your function should begin with:
double simpson(double a, double, b, int n, double(*function)(double) { ... }
Last edited on Aug 31, 2018 at 3:57pm
Aug 31, 2018 at 7:36pm
aurimas13 wrote:
I understand your given example - it's easy. It should go like this:
1
2
3
4
5
6
7
8
9
10
11
12
double simpson2(double start, double end, int steps)
{
  double sum = 0.0; 
  double h = (start - end) / steps; 
  double h2 = h / 2;
  for (int i = 0; i < n; i++)
  {
    double left = a + i * h;
    sum += function(left) + 4 * function(left + h2) + function(left + h);
  }
  return h / 6 * sum;
}

Close. However, I requested:
I wrote:
// compute and return the integral of function fk_2

Your code has no fk_2 anywhere, and then there is a mystery a too.
A tricky part about coding is that details are important.

Lets fix those:
1
2
3
4
5
6
7
8
9
10
11
12
double simpson2(double start, double end, int steps)
{
  double sum = 0.0; 
  double h = (start - end) / steps; 
  double h2 = h / 2;
  for (int i = 0; i < n; i++)
  {
    double left = start + i * h;
    sum += fk_2(left) + 4 * fk_2(left + h2) + fk_2(left + h);
  }
  return h / 6 * sum;
}


That settled, add the function pointer back to the list of arguments and replace every occurrence of fk_2 with the name of the pointer:
1
2
3
4
5
6
7
8
9
10
11
12
double simpson(double start, double end, int steps, Func fun)
{
  double sum = 0.0; 
  double h = (start - end) / steps; 
  double h2 = h / 2;
  for (int i = 0; i < n; i++)
  {
    double left = start + i * h;
    sum += fun(left) + 4 * fun(left + h2) + fun(left + h);
  }
  return h / 6 * sum;
}

Would that that do what was requested?



Now it would be good, if you would re-read the http://www.cplusplus.com/articles/Gw6AC542/

Your current homework might not request it, but you could practice this:
Create three files:
simpson.h declare the function simpson here. If you do use the alias Func, put it here too.

simpson.cpp implementation of function simpson.

pratimas_13.cpp the rest: main(), fk_1(), fk_2(), text(), etc

You have to compile the simpson.cpp and the pratimas_13.cpp separately and then link the object files together.
Topic archived. No new replies allowed.
Pages: 12