how to make a array of pointer to call func pointer? - c

i have code to array of func pointer
#include <stdio.h>
int sum(int a, int b);
int subtract(int a, int b);
int mul(int a, int b);
int div(int a, int b);
int (*p[4]) (int x, int y);
int main(void)
{
int result;
int i, j, op;
p[0] = sum; /* address of sum() */
p[1] = subtract; /* address of subtract() */
p[2] = mul; /* address of mul() */
p[3] = div; /* address of div() */
printf("Enter two numbers: ");
scanf("%d %d", &i, &j);
printf("0: Add, 1: Subtract, 2: Multiply, 3: Divide\n");
do {
printf("Enter number of operation: ");
scanf("%d", &op);
} while(op<0 || op>3);
result = (*p[op]) (i, j);
printf("%d", result);
return 0;
}
int sum(int a, int b)
{
return a + b;
}
int subtract(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
if(b)
return a / b;
else
return 0;
}
code for array of pointer to function:
#include <stdio.h>
int sum(int, int);
int product(int, int);
int subtract(int, int);
int main()
{
int i = 0;
int a = 10;
int b = 5;
int result = 0;
int (*pfun[3])(int, int);
pfun[0] = sum;
pfun[1] = product;
pfun[2] = subtract;
for( i = 0 ; i < 3 ; i++)
{
result = pfun[i](a, b);
printf("\nresult = %d", result);
}
result = pfun[1](pfun[0](a, b), pfun[2](a, b));
printf("\n\nThe product of the sum and the subtract = %d\n",result);
}
int sum(int x, int y)
{
return x + y;
}
int product(int x, int y)
{
return x * y;
}
int subtract(int x, int y)
{
return x - y;
}
now how to combine this two program. such that array of pointers pointing to func pointers and the func pointers may have different number of args? any suggestion.

You not only need to store function pointers with a variable number of arguments (that is not very difficult, you could use a union for instance), but you also need to make sure you call the functions with the correct argument, and that is a bit trickier given your design.
I suggest to use a stack instead. All your functions would only take the stack as an argument:
void sum(stack_t *stack);
void subtract(stack_t *stack);
void product(stack_t *stack);
And your array could be declared this way:
typedef void callback_t(stack_t *);
callback_t *p[] =
{
sum,
subtract,
product,
/* ... */
};
Then for instance sum would be implemented as such:
void sum(stack_t *stack)
{
if (depth(stack) < 2)
perror("Not enough arguments in stack!");
int b = popstack(stack);
int a = popstack(stack);
int c = a + b;
pushstack(stack, c);
}
But unary minus would be implemented this way:
void neg(stack_t *stack)
{
if (depth(stack) < 1)
perror("Not enough arguments in stack!");
int a = popstack(stack);
pushstack(stack, -a);
}
Each function decides how many arguments they need. The caller does not need to know.

Related

Passing structure as argument in C function

typedef struct { int b, p; } A;
void f(A c);
int main()
{
int i;
A a = {1,2};
f(a);
printf("%d,%d\n",a.b,a.p);
return 0;
}
void f(A c)
{
int j;
c.b += 1;
c.p += 2;
}
In the following code, why is it that a.b and a.p are still 1 and 2 even after being passed through f(a), which should change them to 2 and 3?
What you are using is called call by value, in call by value the changes you are doing to function arguments will not be reflected in the caller, for that you need call by reference
typedef struct { int b, p; } A;
void f(A c);
void f2(A *c);
int main()
{
int i;
A a = {1,2};
// call by value
f(a);
printf("%d,%d\n",a.b,a.p);
//call by referecne
f2(&a);
printf("%d,%d\n",a.b,a.p);
return 0;
}
void f(A c)
{
int j;
c.b += 1;
c.p += 2;
}
void f2(A *c)
{
int j;
c->b += 1;
c->p += 2;
}

Storing returned values of a function as structure array in C [duplicate]

This question already has answers here:
How do I return an array of struct from a function?
(3 answers)
Closed 2 years ago.
I have a function that prints out 11 points of a quadratic function ax^2 + bx + c with a, b, c as input. The function works fine except I need to use structures, not just variables x and y. How can I get my function to return a structure value and store it in a structure array then print out the structure array?
struct point {
int x;
int y;
};
struct point *findpoint(int a, int b, int c){
int i, x, y;
x = -5;
for (i = 0; i < 11; i++)
{
y = (a * (x * x)+ (b * x) + c);
printf("The points are {%d, %d}\n", x, y);
x++;
}
}
struct point arr_point[11];
int main(int argc, char *argv[]){
struct point *ptr;
printf("Enter coefficients a, b, c:");
int a, b, c;
int i;
for (i = 0; i < argc; i++){
scanf("%d %d %d", &a, &b, &c);
}
printf("%d %d %d\n", a, b, c);
findpoint(a, b, c);
return 0;
}
You can create an alias for your struct with typedef:
typedef struct {
int x;
int y;
} Foo_t;
Foo_t returnStruct() {
Foo_t foo = {1,2};
return foo;
}
int main() {
const uint8_t SIZE_ARRAY = 2;
Foo_t arrayFoo[SIZE_ARRAY];
arrayFoo[0] = returnStruct();
arrayFoo[1] = returnStruct();
for(uint8_t i=0;i<SIZE_ARRAY;i++) {
printf("Index %d: x=%d y=%d \n", i, arrayFoo[i].x, arrayFoo[i].y);
}
}

Pointer to pointer as a function parameter

I have the following code:
#include <stdio.h>
#include <stdlib.h>
int f(int x, int *py, int **ppz) {
int y, z;
**ppz += 1;
z = **ppz;
*py += 2;
y = *py;
x += 3;
return x + y + z;
}
int main(void) {
int c = 4;
printf("f(): %d\n", f(c, &c, &&c));
printf("c: %d\n", c);
return EXIT_SUCCESS;
}
How can I access **ppz correctly, because so I get an error message: "label 'c' used, but not defined".
An int** is a pointer to an int*. You need to create a variable of type int* to be able to pass a pointer to it somewhere. Here is what you should do:
int main(void) {
int c = 4;
int* pc = &c;
printf("f(): %d\n", f(c, pc, &pc));
printf("c: %d\n", c);
return EXIT_SUCCESS;
}
Refer #ikegami's answer for an explanation of the proper use of a pointer to a pointer.
You want to modify a variable of type int, so the parameter should be int *, not int **.
You'd use int ** if you wanted to modify a variable of type int * variable. That's not the case here.
For example,
void f(int **pp) {
*pp = malloc(10);
}
int main(void) {
int *p;
f(&p);
// ...
free(p);
}

Calculate power of all the numbers till n-1

Given n, the program should calculate 1^1 + 2^2 + 3^3 + ... till n-1^n-1. Below is my code, in which there is one function inside while loop which and the passed value is from n-1 in the function. The function definition has two variables which return the ans. Output is wrong always 1.
#include <stdio.h>
#include <stdlib.h>
int power(int x, int y)
{
int la, ans;
if(y==0)
return 1;
else
la= (x*power(x, y-1));
ans+=la;
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m, a, b, res, res1;
scanf("%d%d", &n, &m);
while(n-- && n>0)
{
a = power(n-1, n-1);
}
printf("%d", a);
}
return 0;
}
Some problems in your code.
As pointed in another answer, your power function was broken:
ans was not initialized
{ } were missing after the else
in the while, you compute x^x, but you forget the result, whearas you
should sum it.
first thing you do in while loop is to decrease n and to compute power(n-1, n-1)
that sound not logical.
Hence, your corrected code could be:
#include <stdio.h>
#include <stdlib.h>
int power(int x, int y)
{
if(y==0)
return 1;
else
return x*power(x, y-1);
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, m, b, a = 0;
scanf("%d%d", &n, &m);
while(n>1)
{
--n;
b = power(n, n);
a += b;
printf("%d^%d -> %3d\n",n, n, b);
}
printf("sum= %d", a);
}
return 0;
}
Gives for n = 6:
5^5 -> 3125
4^4 -> 256
3^3 -> 27
2^2 -> 4
1^1 -> 1
sum=3413
C uses braces to form blocks, your power() function looks like it's wanting to use indentation like in Python.
It should probably be:
int power(int x, int y)
{
int la, ans;
if(y==0)
return 1;
else
{
la= (x*power(x, y-1));
ans+=la;
return ans;
}
}
Of course since the first if has a return, the else is pointless, and you can simplify the code:
int power(int x, int y)
{
if (y==0)
return 1;
return x * power(x, y-1);
}
The variable ans was never assigned to, that looked broken so I simplified it out.
Of course this is susceptible to integer overflow.

Changing **array + a to *array[a]

What my program does is it finds 2 numbers of an array that are closest to the average, one is bigger, one is smaller. It works fine, however I need to change for example **array+a to *array[a].
However, when I load the program, it crashes after I input the numbers. If I try to print *array[0], *array[1], etc. it works fine. When I try to print or just do something with *array[a], *array[b], it crashes. Thank you for your help.
#include <stdio.h>
#include <stdlib.h>
int input (int *t, int *array[]);
void calculation (int *array[], int *t, int *x, int *y);
void output (int *x, int *y);
int main()
{
int *array, t, x, y;
input (&t, &array);
calculation (&array, &t, &x, &y);
output (&x, &y);
return 0;
}
int input (int *t, int *array[])
{ int n, *ptr;
printf ("How big is the array?");
scanf ("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
int k;
printf ("Enter the numbers:");
for (k=0; k<n; k++)
{ scanf ("%d", ptr + k);
}
*t=n;
*array=ptr;
return 0;
}
void calculation (int *array[], int *t, int *x, int *y)
{ float sum=0, avg;
int min, max;
int more, less;
int a, b, c;
for (a=0; a<(*t); a++)
{sum=sum+ **array + a;
}
avg=sum/(*t);
min= *array[0];
max= *array[0];
for (b=0; b<(*t); b++)
{ if (max < (**array + b)) max=(**array + b);
if (min > (**array + b)) min=(**array + b);
}
more=max;
less=min;
for (c=0; c<(*t); c++)
{ if (((**array + c) < avg) && ((**array + c) > less)) less=(**array + c);
if (((**array + c) > avg) && ((**array + c) < more)) more=(**array + c);
}
*x=less;
*y=more;
}
void output (int *x, int *y)
{ printf("Number that is less than the average:%d\n", *x);
printf("Number that is more than the average:%d\n", *y);
}
It would be better to rethink your function prototypes a bit. It makes sense to pass a pointer to array to the input() function since you are allocating memory for it, and you want to be able to access it when you return. But you don't need to pass in the pointer to int t; instead, just return the value of n, and assign it to t in main.
There is no reason to pass a pointer to array to the function calculation(), since you are not changing the array allocation. You can also pass in the value of t from main(), since you only use this value in calculation(), but do not change it.
Similarly, the output() function only needs copies of x and y, since it does not change them.
The rule of thumb here is that you pass a pointer to a value into a function when you want to modify the value inside the function and have access to the modified value in the calling function. But you can also return a value instead of using a pointer to it.
These changes do not alter the functionality of your code, but they substantially improve its readability. You even get a sense of what is being modified in each function just by looking at the function prototypes. Well, the changes do alter the functionality in that your original **array + a was incorrect, and needed to be either *(*array + a) or (*array)[a]. But sorting that problem out should help you to appreciate the virtue of the simpler function prototypes. Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
int input(int *array[]);
void calculation(int array[], int t, int *x, int *y);
void output(int x, int y);
int main(void)
{
int *array, t, x, y;
t = input(&array);
calculation(array, t, &x, &y);
output(x, y);
return 0;
}
int input(int *array[])
{ int n, *ptr;
printf("How big is the array?");
scanf("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
int k;
printf("Enter the numbers:");
for (k=0; k<n; k++)
{ scanf("%d", ptr + k);
}
*array=ptr;
return n;
}
void calculation(int array[], int t, int *x, int *y)
{ float sum=0, avg;
int min, max;
int more, less;
int a, b, c;
for (a=0; a<t; a++)
{sum=sum+ array[a];
}
avg=sum/t;
min= array[0];
max= array[0];
for (b=0; b<t; b++)
{ if (max < array[b]) max=array[b];
if (min > array[b]) min=array[b];
}
more=max;
less=min;
for (c=0; c<t; c++)
{ if ((array[c] < avg) && (array[c] > less)) less=array[c];
if ((array[c] > avg) && (array[c] < more)) more=array[c];
}
*x=less;
*y=more;
}
void output(int x, int y)
{ printf("Number that is less than the average:%d\n", x);
printf("Number that is more than the average:%d\n", y);
}
Just like BLUEPIXY and Some programmer dude said, it's supposed to be (*array)[a]

Resources