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.
Related
int (*x(int))[5] says x is a function that takes an int argument, and returns a pointer to an integer array of 5 elements.
I can also use typedef to simplify x:
typedef int Array[5];
typedef Array *Array_ptr;
typedef Array_ptr Array_ptr_fn(int);
My question is, how do I use this type Array_ptr_fn?
// Define some_x to have type Array_ptr_fn,
Array_ptr_fn some_x;
// But then how do I use some_x since function cannot return array.
The first thing to note is that x is not a function pointer, but an actual function declaration. It's not a variable. A pointer to x would have the type int (*(*ptr_to_x)(int))[5].
The second thing to note is that the return value of x is neither int[5], nor int[], nor int*, but int (*)[5]. That is, you need to write (*retval)[0] to get to an actual int value.
With that in mind, it's not that hard to write a proof of concept that uses these types:
#include <stdio.h>
int arr[5] = { 11, 22, 33, 44, 55 };
int (*ptr)[5] = &arr;
int (*x(int ignored))[5]
{
return ptr;
}
int main(void)
{
int (*(*ptr_to_x)(int))[5] = &x;
int (*i)[5] = ptr_to_x(123);
printf("%d\n", (*i)[2]);
return 0;
}
Array_ptr_fn some_x; /* ERROR */
You cannot use the type Array_ptr_fn to define a variable... but you can use a pointer to that type to store a function reference (with that interface) to be called in the future, as in:
int (*f1(int))[5]; /* implemented elsewhere */
Array_ptr_fn *some_function = f1;
int (*my_array)[5] = f1(27);
/* or equivalently */
int (*my_second_array)[5] = some_function(27);
In the function read, I need to access the values of integer a and integer b from the main function without declaring them in the prototype of the function read, using pointers.
Pointer x should point to integer a, and pointer y should point to integer b.
#include <stdio.h>
void read(int zzz[], int n) {
int *arr = zzz, *x=a,*y=b;
}
int main() {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
return 0;
}
How this could be implemented?
There are two ways that the read function can read the values or addresses of a and b:
Pass them as parameters
Make a and b global
So if you don't want to make them parameters, you need to move them outside of the main function and before the read function.
Also, read is the name of a system function, so you should name it something else so you don't conflict with it.
You have already received the more conventional answer. It is the most logical choice for your given restriction.
However ... Silly artificial restrictions sometimes deserve a silly contrived solution in kind.
A less conventional way would be to create an understanding with the function that the values will be passed in with the array pointer in some non-standard way.
For example, you can make two extra array members to represent a and b.
int array_for_my_read[array_size + 2];
/* instead of a and b, you use those extra array members */
...
int *x = zzz + n, *y = x + 1;
Alternatively, you could create a special structure that holds the array, and the pointers. Then the function recovers the pointer to the structure from the array pointer.
struct extra_parameters {
int *a;
int *b;
int zzz[zzz_size];
};
...
struct extra_parameters x;
int a, b;
x.a = &a;
x.b = &b;
read(x.zzz, zzz_size);
...
void *p = (char *)zzz - offsetof(struct extra_parameters, zzz);
struct extra_parameters *xp = p;
int *a = xp->a, *b = xp->b;
How do you pass an array to a function where that function can edit it's contents?
like when doing
function(int *x)
{*x = 10;}
main()
{int x;
function(&x);}
how could i do the same using a character array?
whenever I do
function(char *array[], int *num)
{ int x = *num;
*array[x] = 'A'; }
main()
{ char this[5] = "00000"; //not a string
int x = 3;
function(&this, &x); }
DEV C++ says
[Warning] passing arg 1 of `function' from incompatible pointer type
obviously I did something wrong, so please tell me how to fix that. Thanks :D
You should write:
void function(char array[], int *num)
{
int x = *num;
array[x] = 'A';
}
void main()
{
char my_array[5] = "00000";
int x = 3;
function(my_array, &x);
}
Notation char *array[] is an array of pointers that you do not need here.
When you pass an array somewhere, you should not take its address. Arrays are adjusted to pointers by default.
EDIT:
Function prototypes:
void function(char array[], int *num);
void function(char *array, int *num);
are absolutely identical. There is no even minor difference between them.
Since arrays can only be passed by address, you don't really want a char * array here, just a char array:
rettype function(char *array, int *num)
{
array[*num] = 'A';
}
int main()
{
char arr[] = "1234567890";
int i = 2;
function(arr, &i);
}
In C, array names "devolve" to a pointer to the head of the array, by passing "&array", you're passing a pointer to a pointer to the head of the array, thus the warning.
char array[512];
myfunc(array, foo);
is the proper way to do what you want.
Actually you have taken one dimension array. So you can define function in two ways...
(i)
function(char array[], int *num)
{ int x = *num;
*array[x] = 'A'; }
main()
{ char this[5] = "00000"; //not a string
int x = 3;
function(this, &x); }
and
(ii)
function(char *array, int *num)
{ int x = *num;
*array[x] = 'A'; }
main()
{ char this[5] = "00000"; //not a string
int x = 3;
function(this, &x); }
But in your function definition, you wrote *array[] as argument which means the array is two dimensional array. So you should declare array as two dimensional array.
function(char *array[], int *num)
{ int x = *num;
//implement your code }
main()
{ char this[5][10];
// you can initialize this array.
int x = 3;
function(this, &x); }
I think it will be helpful to you.
Okay, the first thing to remember is that there's no such thing as a pointer "to an array" although you'll hear that said fairly often. It's sloppy.
(As pointed out below, the terminology "pointer to an array" does strictly have a meaning -- but I maintain that you've been confused by it. What really happens is that every pointer contains an address. Depending on the declaration, the compiler can identify if it's being used correctly in context, and that's what your error message is really telling you: what you declared in the function is a pointer to an array of chars, which is to say the same thing as a char **, instead of a char *, which is what you're passing. But char *, or char **, or char ******, the important point is that you're making it too complex -- you already have the address you need identified by the array name.)
Pointers is pointers, they're addresses.
An array in C is simply an allocated chunk of memory, and it's name represents the address of the first element. So
char a[42];
is a block of memory 42 char's long, and a is its address.
You could rewrite your second function as
void foo(char* a, int num){ // (3)
// notice that you don't need the word function and
// for lots of reasons I wouldn't use it as a function name.
a[num] = 'A'; // (4)
}
int main(){
// Sadly "00000" IS a string no matter what your comment
// says. Use an array initializer instead.
char arry[5] = {'0','0','0','0','0' } ; // (1)
foo(arry,3); // (2)
}
This does what I believe your code means to do. Note that
(1) Since "00000" really is a string, it's actually creating an array 6 elements long which could have been initialized with the array initializer
{'0','0','0','0','0', 0 }
(2) The array (which I named 'arry' instead of 'this' since 'this' is often a keyword in C-like languages, why risk confusion?) is already an address (but not a pointer. It can be on the right-hand side of an assignment to a pointer, but not on the left hand side.)
So when I call
foo(arry,3);
I'm calling foo with the address of the first element of arry, and the number 3 (you don't need to declare a variable for that.)
Now, I could have also written it as
foo(&arry[0],3);
You would read that as "find the 0-th element of arry, take its address." It is an identity in C that for any array
char c[len];
the expression c and &c[0] refer to the same address.
(3) that could also be defined as foo(char arry[], int num). Those are equivalent.
(4) and when you refer to a[num] you're referring directly to the num-th element of the memory pointed to by a, which is at the address of the start of the array arry. You don't need all that dereferencing.
Don't be disturbed that this is a little hard to follow -- it's tough for everyone when they start C.
Firstly dont use this as a variable name, its a C++ keyword. Sorry didnt realise it was a C question.
main()
{
char foo[5] = "00000"; //not a string
int x = 3;
function(foo, &x);
}
You dont take the memory address of foo. foo when used in a pointer-accepting context degrades into a pointer to the first element. *foo is the same as foo[0] which is the same as *(foo + 0)
like wise foo[3] is the same as *(foo + 3) (the compiler takes care of multiplying the element size).
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).
how to return more than one value from a function?
A function can only have a single return value. You could either pack multiple values into a compound data type (e.g. a struct), or you could return values via function parameters. Of course, such parameters would have to be passed using pointers to memory declared by the caller.
1
Declare method like this foo (char *msg, int *num, int *out1, int *out2);
and call it like this
int i=10;
char c='s';
int out1;
int out2;
foo(&c,&i,&out1,&out2);
Now what ever values u assign to out1 and out2 in function will be available after the function returns.
2
Return a structure having more than one members.
In C, one would generally do it using pointers:
int foo(int x, int y, int z, int* out);
Here, the function returns one value, and uses out to "return" another value. When calling this function, one must provide the out parameter with a pointer pointing to allocated memory. The function itself would probably look something like this:
int foo(int x, int y, int z, int* out) {
/* Do some work */
*out = some_value;
return another_value;
}
And calling it:
int out1, out2;
out1 = foo(a, b, c, &out2);
You cannot return more than 1 value from a function. But there is a way. Since you are using C, you can use pointers.
Example:
// calling function:
foo(&a, &b);
printf("%d %d", a, b);
// a is now 5 and b is now 10.
// called function:
void foo(int* a, int* b) {
*a = 5;
*b = 10;
}
Functions can return arrays or lists