Pointer to pointer as a function parameter - c

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

Related

f(&a) is possible to run in C?

The explanation below confused me:
When an argument is pointer to a variable x, we normally assume that x will be modified :
f(&x);
It is possible, though, that f merely needs to examine the value of x, not change it.
I tired to understand and the code below can't work.
#include <stdio.h>
void function(int& a)
{
a = 5;
}
void func(int b)
{
b = 5;
}
int main(void)
{
int x = 0;
function(x);
printf("%d", function(x));
func(x);
printf("%d", func(x));
return 0;
}
Code refer from the second answer:
int f(int &a){
a = 5;
}
int x = 0;
f(x);
//now x equals 5
int f2(int b){
b = 5;
}
int y = 0;
f2(y);
//y still equals 0
An example actually using f(&x):
#include <stdio.h>
void f(int *p) {
*p = 4;
}
int main(void) {
int x;
f(&x); // Provide a pointer to `x`.
printf("%d\n", x); // 4
return 0;
}
Both of your program use int &a, which isn't a valid C declaration. That is why they don't even compile.

Function to increment the value of a variable in C

I wrote the same code in PHP, the value of 5 got incremented, but
why doesn't the value get incremented in C?
int foo(int x){
x++;
}
int main( ){
int y = 5;
foo(y);
printf("value of y = %d\n", y);
}
In C passing arguments is done by value rather than by reference. That is, the number that the function is working with is unique to the one passed to and has its own space in memory. To get around this do
int foo(int* x){
(*x)++;
}
int main( ){
int y = 5;
foo(&y);
printf("value of y = %d\n", y);
}
You should pass the parameter by reference to function foo.
int foo(int *x){
(*x)++;
}
int main( ){
int y = 5;
foo(&y);
printf("value of y = %d\n", y);
}
Because x, y are local variables to their functions. The scope of the variable lies within the block of the function. So you can't change the value of those variables from outside the block.
Solution:
Either you declare those variables as global variables
int y;
int foo(){
y++;
}
int main( ){
y = 5;
foo();
printf("value of y = %d\n", y);
}
Or using reference you can do that
int foo(int *x){
(*x)++;
}
int main( ){
int y = 5;
foo(&y);
printf("value of y = %d\n", y);
}
Might be in PHP it is directly pass-by-reference. But C has different function calls.
If you want to increment the value in the function and it should reflect in the main function. There are two possible ways :
1.
int foo(int x)
{
return ++x; //returning the incremented value
}
2.
void foo(int *x)
{
++(*x);//this function is pass-by-reference.
}
Please let me know if there are any issue.
What you could also be doing if you want to avoid using pointers is as below
int addone(int n);
int main(void) {
int n=0;
printf("Before: %d\n", n);
n=addone(n);//assign the returned value from function to the variable 'n'
printf("After: %d\n", n);
return 0;
}
int addone(int n) {
n++;
return n;
}

Some issue concerning fprint and pointers

I am taking an OS course and I have some questions about the following codes
#include <stdio.h>
int * addition(int a, int b){
int c = a + b;
int *d = &c;
return d;
}
int main(void){
int result = *(addition(1,2));
int *result_ptr = addition(1,2);
/*never interchange */
printf("result = %d\n", *result_ptr);
printf("result = %d\n", result);
return 0;
}
//this code outputs 3
3
Here is what happens when i swap the printfs, in fact the second one just prints out a random address
#include <stdio.h>
int * addition(int a, int b){
int c = a + b;
int *d = &c;
return d;
}
int main(void){
int result = *(addition(1,2));
int *result_ptr = addition(1,2);
/*never interchange */
printf("result = %d\n", result);
printf("result = %d\n", *result_ptr);
return 0;
}
//this code outputs 3
and a random address
However, if i make them into one printf
#include <stdio.h>
int * addition(int a, int b){
int c = a + b;
int *d = &c;
return d;
}
int main(void){
int result = *(addition(1,2));
int *result_ptr = addition(1,2);
/*never interchange */
printf("result = %d %d \n", result, *result_ptr);
return 0;
}
//this code outputs 3 3
I wonder if the printf clear the memory so the pointer becomes dangerous?
The problem is in your addition function. You're returning the address of a local variable. Because locals live on the stack, the memory for that variable goes out of scope when the function returns. This caused undefined behavior such as what you experienced.
For this to work properly, you need to allocate memory on the heap using malloc:
int *addition(int a, int b){
int *d = malloc(sizeof(int));
*d = a + b;
return d;
}
When this function returns, you need to be sure to free the pointer that was returned after you're done with it. Otherwise, you'll have a memory leak.

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

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.

where location to assign function pointer point to a function

I have a funtion_ptr function pointer which point to add_int function.
case 1: when lay a statement function_ptr = &add_int outside main function
--> compiler error: error C2373: 'function_ptr' : redefinition; different type modifiers (this is in )
#include <stdio.h>
int add_int(int n, int m){
return n + m;
}
int(*function_ptr)(int, int);
function_ptr = &add_int; // it's here
void main(){
int sum = (* function_ptr)(2, 3);
printf("sum = %d", sum);
_getch();
}
case 2: function_ptr = &add_int; in main function --> it is true
#include <stdio.h>
int add_int(int n, int m){
return n + m;
}
int(*function_ptr)(int, int);
void main(){
function_ptr = &add_int; // it's now here
int sum = (* function_ptr)(2, 3);
printf("sum = %d", sum);
_getch();
}
Could anyone explain for me different between the two case.
Thanks!
function_ptr = &add_int; is an assignment statement. Statements are allowed inside functions, but outside functions only declarations are allowed. Since assignment is not a declaration, the compiler issues an error.
If you want to assign the pointer as part of its declaration/definition, you could combine the declaration and the assignment, like this:
#include <stdio.h>
int add_int(int n, int m){
return n + m;
}
int(*function_ptr)(int, int) = &add_int;
int main(){
int sum = (* function_ptr)(2, 3);
printf("sum = %d", sum);
return 0;
}
Demo.
You don't need the & in the assignment statement, the function's name (add_int) IS its address... and the assignment statement should be within the bounds of a function.
Here's an example that works:
#include <stdio.h>
int add_int(int n, int m);
int(*function_ptr)(int, int);
void main(){
function_ptr = add_int;
int sum = (* function_ptr)(2, 3);
printf("sum = %d", sum);
getc(stdin);
}
int add_int(int n, int m){
return n + m;
}

Resources