How do I convert int* to int (*p)(void)? - c

I'm trying to do it this way:
int (*p)(void);
int *i;
...
p = (int *(void))i;
But it's causing syntax error:
error: cast specifies function type
What's wrong here?

You should respect error in this case. You must not convert a pointer to function to an int pointer or other way around. That might result in undefined behavior.
If you insist then, syntax should be:
p = (int (*)(void))i;

i is a pointer to an integer, and p is a function pointer returning and int and taking no arguments. They are not compatible/castable in any way, shape or form.

What the compiler says. int (*p)(void) is a function pointer declaration (pointer to a function which returns an int). int *i; is a scalar pointer declaration (pointer to an int). You can't cast one into the other.

Write
p = (int (*)(void))i;
Here's an example:
#include <stdio.h>
int f(){
printf("test\n");
return 0;
}
int main()
{
int (*p)(void);
int *i;
i = (int*)f;
p = (int (*)(void))i;
printf("i=%p\n", i);
printf("p=%p\n", p);
((int (*)(void))i)(); //here, it will call f()
return 0;
}

If you must do it ( and I am in no way saying that you should) then:
typedef int (*fp)(void);
int *i;
fp p;
...
p = (fp)((void*)i);

*i points to a simple integer, while *p is a pointer to a function with no arguments returning an integer. Thus, these two have completely different types, and because you said p shall point to a function returning an int, you can not tell it to point to an int.
However, you can try to wrap both in a union like the following:
union u {
int *i;
int (*p)(void);
};
int f(void){
return 5;
}
int main(int argc, char *argv[]) {
union u myU;
int a=6;
myU.i=&a;
myU.p=&f;
return 0;
}
Note that after assigning &f, you can simply call myU.p(). But if you leave out the assignment of &f and call myU.p() afterwards, it results in undefined behaviour (i.e. program crashes).

You don't. That is, unless you know better than the compiler that the pointer stored in your int * came from an int (*p)(void) in the first place. As others have said, that second type is a pointer to a function that takes no parameters and returns an int. The first type is a simple pointer to an integer (or more than one integer if treated as an array).

Related

Shifting pointer to some address by calling another function

Why in this code the pointer shifts to another location:
#include <stdio.h>
void f(int *p)
{
int j=2;
p=&j;
printf("%d\n%p\n%d\n",*p,&j,p);
}
int main(void)
{
int *q;
int m=98;
q=&m;
f(q);
printf("%p ",q);
return 0;
}
Output:
2
0x7ffff5bf1bcc
0x7ffff5bf1bcc
0x7ffff5bf1bc8
I understand that when the function f() is done with printing value of j and address of j the memory occupied by j goes back to the stack but IMO p should continue pointing that location even after the function is over & it should be printing the same address in main as well. What is wrong with this?
Considering you meant printf("%p ", (void *)q); in the actual code,
No, function argument(s) in C is (are) passed by value. It won't reflect the changes made to the parameter into the actual arguments used (in function call) themselves.
To put it into other words, the function parameters are local to the function (call) scope, any changes made to them won't be reflected to the actual arguments.
So, if you need to change a pointer, you need to pass a pointer to the pointer which needs to be changed.
Consider a rather light-hearted but realistic scenario.
void f (int x) { x = 10; }
int main(void) { f(5); printf ("%d", 5); return 0;}
Now, do you expect it to print 10?
That said, an advice. Always cast the argument to %p conversion specifier to (void *) (if it is not already). printf() is a variadic function and for pointers, no default argument promotion happens, so the supplied argument type needs to match the expected type, explicitly. Otherwise, technically it is undefined behavior.
Learn the difference between Pointers and Pointers to pointers - the pointer passed p is no doubt good to change the value of the variable it is pointing to (m), but to change the memory location it is pointing to - you need a pointer to pointer.
Expanding on top of what #SouravGhosh said, when you pass in a pointer to an int you are making a copy of the pointer. If you wanted to change the pointer you need to be doubly indirect and pass in a pointer to a pointer to an int. The first pointer is copied and you can directly affect the second pointer.
void f(int ** p)
{
int j = 2;
*p = &j;
printf("%d\n%p\n%p\n",*p,&j,p);
}
int main(void)
{
int ** q = (int **)malloc( izeof(int *));
int m = 98;
*q = &m;
f(q);
printf("%p ",q);
free(q);
return 0;
}
And the output is
2
0xffffcbcc
0xffffcbcc
0xffffcbcc
If you do this you'll see that it never changes:
#include <iostream>
#include "Header2.h"
#include "header1.h"
#include <stdio.h>
void f(int *p)
{
int j = 2;
p = &j;
printf("%d\n%p\n%p\n", *p, &j, p);
}
int main(void)
{
int *q;
int m = 98;
q = &m;
printf("Value of pointer q before calling f() =%p ", q);
f(q);
printf("Value of pointer q after calling f() =%p ", q);
return 0;
}

Following a pointer in C

I will show the entire code, but look for the quotes above the pointers as I will be talking about my problem there. I will tell you what I think happened there at the quote comments. The code compiles and runs, I just need help understanding parts of the code.
#include <stdio.h>
#include <stdlib.h>
int *get_data(int num_grades);
float calc_average(int num_grades, int grades[]);
void display_average(float ave);
int main()
{
int num_grades = 10;
const int MAX_GRADE = 100;
Below this quote box at: int *result = get_data(num_grades);
I have a pretty simple understanding of pointers at this point, as I've been introduced to them recently, however I can't seem to wrap my head around what happens when you assign a function to a pointer. What I think should happen is that the pointer int *result should be pointing at an address. Instead its pointing to a function that is also a pointer i think. So is this a pointer to a pointer at: int *result = get_data(num_grades); ?
I will put the rest of my question at the get_data function below.
int *result = get_data(num_grades);
^ Above ^
if (num_grades ==0)
printf("no grades to average\n");
else
{
float ave = calc_average(num_grades, result);
display_average(ave);
}
free(result);
return 0;
}
float calc_average(int num_grades, int grades[])
{
float ave;
int i;
int sum = 0;
for (i = 0; i < num_grades; i++)
{
sum+=grades[i];
}
ave = (float)sum/num_grades;
return ave;
}
void display_average(float ave)
{
printf("average: %.2f\n", ave);
}
Below this quote box,
I think this is a function pointer that returns a int pointer?
So, inside the body of the function, we create a new pointer, allocate memory for it, assign grades for each 'pointee' i think, and then I'm not sure why a[i] = grade is working, what are these indexes coming from, I don't understand why this is working if there is no array declared. Can someone explain what is happening here? How does this work? I'm really confused here.
int *get_data(int num_grades)
{
int* a;
a = malloc(num_grades * sizeof(int));
int i;
for (i = 0; i < num_grades; i++)
{
printf("enter a grade: ");
int grade;
scanf("%d", &grade);
if(grade<=100)
{
a[i] = grade;
}
else
{
printf("grade needs to be > 0 and <= 100\n");
i--;
}
}
return a;
^ Above, this whole function ^
}
get_data is a function which returns a pointer to an integer. First of all:
int *result = get_data(num_grades);
in this line you are not assigning to result a pointer to function, but the result of the function being called with num_grades as argument. That is to say, to the a you calculated in the body of get_data. And after that:
int *get_data(int num_grades)
this is the declaration of a function called get_data which takes one int parameter and returns a pointer to int. You could rearrange the spaces like this:
int* get_data(int num_grades)
if it makes things clearer. In this context, saying that get_data is a pointer to function would not even make sense, since it's immediately followed by its body. For reference:
int (*get_data)(int num_grades);
this is how the declaration of a pointer to function taking one int param and returning an int looks like. And there can't be a function body after it.
... however I can't seem to wrap my head around what happens when you assign a function to a pointer.
You aren't assigning a function to a pointer; you're assigning the return value of the function (which happens to be an int * value) to a variable which happens to store int * values.
So is this a pointer to a pointer at: int *result = get_data(num_grades); ?
No. int * means 'pointer to int'.
I think this is a function pointer that returns a int pointer?
No. The function returns an int * (pointer to int). There is a function pointer in your code, though that isn't a function (because it's a function pointer) and it doesn't return anything (because it's not a function; it's a function pointer).
Remember, int * means 'pointer to int'.
and then I'm not sure why a[i] = grade is working, what are these indexes coming from, I don't understand why this is working if there is no array declared. Can someone explain what is happening here? How does this work? I'm really confused here.
The array[index] operator is actually a pointer[index] operator. It's syntactic sugar for *(array + index) or *(pointer + index).
Whenever an expression that has an array type is used (with the exception being taking the sizeof or &addressof an array), the expression is converted to a pointer. The pointer points to the first item of the array...
So whilst your pointer declaration will have different semantics for the sizeof and &addressof operators, it'll have the same semantics for the 'array subscript' operator.
A similar concept applies to functions (hence the "function pointer" explanation above). Technically, in your expression int *result = get_data(num_grades); you're not applying the function(argument) operator; you're applying the function_pointer(argument) operator. The expression denoting the function is converted to a function pointer...

passing pointer as size of an array in C

I want to pass a pointer as a size element of an array
example:
void hello(int array1[how can i refer pointer "ptr" here][2])
{
// i want to access the array used in the main() here
printf("hi");
}
int main()
{
int c=5;
int *ptr=&c;
a[*ptr][2];
a[0][1]=0;
a[0][2]=4;
}
I apologize for not being clear with my question here , i want to access the array used in the main() function in my hello() function.
You will have to use the value pointed to by the pointer:
a[*ptr][2];
ptr is the address pointed to by the pointer not the value stored there. You use the dereference operator * to get the value.
Of course, ptr is not of type int, it's of type int * (integer pointer). An array subscript must be of type int.
Maybe what you want is a[*ptr][2].
You need to deference the pointer by using *ptr so
int c = 5;
int *ptr = &c;
a[*ptr][2];
otherwise you are not using the value of ptr you are using its address in memory which returns an error.
Use the dereference operator *:
a[*ptr][2];
The expression *ptr tells the compiler to use the value pointed to by ptr.
As for your updated question, that's not possible. But it's not needed either, as it's passed as a pointer anyway.
When declaring a function, this:
void foo(int a[5][5])
is the same as this:
void foo(int a[][2])
And also the same as this:
void foo(int (*a)[2])
It has pretty much been answered already, you can't call an adress in the array a[0x3950f2][2]
Always use the pointer* to get the position in the array a[*ptr][2] to get the expected value - in this case: a[*ptr][2] == a[5][2]. You may read this.
Edit to your updated question: You can't to this. You can use the pointer when you call the function or when using the variable in the function.
Your second edit:
void hello(int **array1)
{
// i want to access the array used in the main() here
printf ("hi");
a[0][0] = 24;
}
int main()
{
int c = 5;
int *ptr = &c;
int **a;
a[*ptr][2];
a[0][1] = 0;
a[0][2] = 4;
hello (a);
return 0;
}

usage of double pointers as arguments

Please find the code snippet as shown below:
#include <stdio.h>
int My_func(int **);
int main()
{
int a =5;
int *p = &a;
My_Func(&p);
printf("The val of *p is %d\n,*p);
}
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
*p = Ptr;
}
How does by using a double pointer as a argument in my_Func function and making change of value reflects the same in the main function but if we use a single pointer in My_Func does not change the value in main?Please do explain me with examples if possible
Advanced thanks
Maddy
int **p is a pointer to a pointer-to-int. My_Func(int **p) works by changing the value of integer that the pointer-to-int points to i.e. int a.
Without changing the implementation, the function will not work with a pointer-to-int parameter int *p as there is a second level of indirection. In addition, you're setting the value to a local variable that is created on the stack. When the function is completed the memory used for the variable will be reclaimed, therefore making the value of a invalid.
void My_Func(int **p)
{
int val = 100; // Local variable.
int *Ptr = &val; // This isn't needed.
*p = Ptr;
} // val dissapears.
Remove the second level of indirection and copy val by value instead of pointing to it:
#include <stdio.h>
void My_Func(int *p)
{
int val = 100;
*p = val;
}
int main(void)
{
int a = 5;
My_Func(&a);
printf("The val of a is %d\n", a);
return 0;
}
In short, in C when you pass something as a parameter, a copy will be passed to the function. Changing the copy doesn't affect the original value.
However, if the value is a pointer, what it points to can be changed. In this case, if you want to affect the pointer, you need to pass a pointer to it down to the function.
Use it in the function declaration:
void func(int *p)
{
int val =100;
int *temp=&val;
p=temp;
}
p starts pointing to another address i.e. address of val. So it will print the value 100.
Important note: Try it in your downloaded compiler (always in case of pointers) not in the online compiler. The online compiler doesn´t keep track of lost addresses in stack.
You are assigning the address of local variable, which will soon disappear when My_Func returns. You can use following in your code. However you can do the same thing just by using single pointer, double pointer is not required in this example.
void My_Func(int **p)
{
int val = 100;
int *Ptr = &val;
**p = *Ptr;
}

assignment after function returning array of pointers

Here is the code which i got confused with.It would be great help if someone corrected this code?
int (*(x)())[2];
int main()
{
int (*(*y)())[2]=x;
x();
return 0;
}
int (*(x)())[2]
{
int **str;
str=(int*)malloc(sizeof(int)*2);
return str;
}
How to assign an array of pointers when returned by x?is using malloc only solution?
Thanks in advance
It's not entirely clear what you're trying to accomplish, so I'll cover more than one possibility.
First of all, a refresher on how to read and write complicated declarations in C:
Remember that () and [] have higher precedence than unary *, so *a[] is an array of pointers, while (*a)[] is a pointer to an array; similarly, *f() is a function returning a pointer, while (*f)() is a pointer to a function.
When you're trying to read a hairy declaration, start with the leftmost identifier and work your way out, remembering the rule above. Thus,
int (*(x)())[2];
reads as
x -- x
(x) -- x
(x)() -- is a function
*(x)() -- returning a pointer
(*(x)())[2] -- to a 2-element array
int (*(x)())[2] -- of int
In this case, the parens immediately surrounding x are redundant, and can be removed: int (*x())[2];.
Here's how such a function could be written and used:
int (*x())[2]
{
int (*arr)[2] = malloc(sizeof *arr); // alternately, you could simply write
return arr; // return malloc(sizeof (int [2]));
} // type of *arr == int [2]
int main(void)
{
int (*p)[2] = NULL; // alternately, you could write
... // int (*p)[2] = x();
p = x();
...
free(p);
}
Notice that the declarations of arr, p, and x() all look the same -- they all fit the pattern int (*_)[2];. THIS IS IMPORTANT. If you declare one thing as T (*p)[N] and another thing as T **q, then their types are different and may not be compatible. A pointer to an array of T is a different type than a pointer to a pointer to T.
If your goal is to create an array of pointers to functions returning int, then your types would look like int (*f[2])();, which reads as
f -- f
f[2] -- is a 2-element array
*f[2] -- of pointers
(*f[2])() -- to functions
int (*f[2])(); -- returning int
That would look something like the following:
int foo() {...}
int bar() {...}
int main(void)
{
int (*f[2])() = {foo, bar};
...
}
If you want a function that returns f, that's a little trickier. C functions cannot return array types; they can only return pointers to arrays, so your function declaration would be built up as
g -- g
g() -- is a function
*g() -- returning a pointer
(*g())[2] -- to a 2-element array
*(*g())[2] -- of pointers
(*(*g())[2])() -- to functions
int (*(*g())[2])() -- returning int
And such a beastie would be used something like this:
int foo() {...}
int bar() {...}
int (*(*g())[2])()
{
int (*(*f)[2])() = malloc(sizeof *f);
(*f)[0] = foo; // the type of the *expressions* foo and bar
(*f)[1] = bar; // is `int (*)()`, or pointer to function
return f; // returning int
}
int main(void)
{
int (*(*p)[2])();
int x, y;
...
p = g();
x = (*(*p)[0])();
y = (*(*p)[1])();
...
free(p);
...
}
Note that you can also build up hairy declarations from the outside in, using a substitution method. So,
int x(); -- x is a function returning int
int (*p)(); -- replace x with (*p) to get a pointer to a function
returning int
int (*a[2])(); -- replace p with a[2] to get an array of pointers
to functions returning int
int (*(*q)[2])(); -- replace a with (*q) to get a pointer to an array
of pointers to functions returning int
int (*(*g())[2])(); -- replace q with g() to get a function returning
a pointer to an array of pointers to functions
returning int.
Same result, different path. I prefer the first method, but either one should work.
Many people recommend using typedef to make things easier to read:
typedef int ifunc(); // ifunc is a synonym for "function returning int"
typedef ifunc *pifunc; // pifunc is a synonym for "pointer to function
// returning int
typedef pifunc farr[2]; // farr is a synonym for "2-element array of
// pointer to function returning int
typedef farr *pfarr; // pfarr is a synonym for "pointer to 2-element
// array of pointer to function returning int
pfarr g()
{
pfarr f = malloc(sizeof *f);
(*f)[0] = foo;
(*f)[1] = bar;
return f;
}
int main(void)
{
pfarr p = g();
int x, y;
x = (*(*p)[0])();
y = (*(*p)[1])();
...
}
Yes, the declarations are easier to read, but there's no connection between the declaration of pand the expression (*(*p)[1])(). You'd have to grovel back through all the typedefs to understand why that expression is written the way it is, building up a mental map for each typedef.
Yes, declarations like int (*(*g())[2])() are designed to make your eyes glaze over, hiding all that behind a typedef makes the situation worse IMO.
Don't understand what you want to do, maybe this can help
#include<stdio.h> // printf
#include<stdlib.h> // malloc free
int *x(); // forward declaration because used before definition
int main() {
int *y=x(); // y is a pointer on int
printf ("%d %d\n", y[0], y[1]);
free(y); // must call free because dynamic allocation
return 0;
}
int *x() {
int *res;
res=(int*)malloc(sizeof(int)*2); // dynamic allocation of an array of two int
// should check res != NULL
res[0]=10;
res[1]=20;
return res;
}
This following code will give you an array of pointers to functions, and standard procedures for assigning, passing of arrays applies.
#include <stdio.h>
#include <stdlib.h>
typedef int (*XFunc())();
XFunc *x[2]; /* array of XFunc pointers */
int f1()
{
printf("1\n");
return 1;
}
int f2()
{
printf("2\n");
return 2;
}
int main()
{
x[0] = (XFunc*)f1;
x[1] = (XFunc*)f2;
x[0]();
x[1]();
return 0;
}
The pointer x above will point to the first element in the (fixed) array, this pointer-value is the value that will be assigned to another variable.

Resources