Consider the following pointer declarations.
int *p[10];
int (*q)[10];
What is the difference between 1st and second. How to read them in plain English?
Example:
int *p; // it will be read as "p is a pointer to an int"
int **p; // p is a pointer to an integer pointer.
int *p[10] is an array of 10 pointers to int. int (*q)[10] is 1 pointer to an array of 10 ints.
Related
I couldn't understand use of (int*) p in following program for pointer to an array
#include<stdio.h>
void main()
{
int s[4][2];
int (*p)[2];
int i,j,*pint;
for(i=0;i<=3;i++)
{
p=&s[i];
pint=(int*)p; /*here*/
printf("\n");
for(j=0;j<=1;j++)
printf("%d",*(pint+j));
}
}
can i use *p instead of (int*) p here. thanks in advance
In your code,
pint=(int*)p;
p is of type int (*)[2], i.e., pointer to an array of 2 ints, and pint is a int *. They are not compatible types, so you need the cast.
If you have an array declaration like this
int s[4][2];
then these three pointers have the same value
int ( *p1 )[4][2] = &s;
int ( *p2 )[2] = &s[0];
int *p3 = &s[0][0];
because all the pointers point to the initial address of the extent of memory allocated for the array.
However the pointers have different types because they point to objects of different types.
The first pointer points to the array in whole as a single object.
the second pointer points to an array element that in turn has the array type int[2].
And the third array point to a scalar object of the type int.
So you may not assign directly one pointer to another because they are incompatible though as it was mentioned they have the same value (address).
You need to cast one pointer type to another pointer type explicitly.
This assignment in the original program
p=&s[i];
assigns the address of each element (array of the type int[2]) to the pointer. In fact it is the address of the first element of the array that is it is equal to &s[i][0]. However the first expression and the last expression have different pointer types.
So you need to use casting in this assignment
pint=(int*)p;
Now using the pointer arithmetic in this expression
*(pint+j)
you can traverse all scalar elements of the array initially pointed to by the pointer p.
Pay attention to that this declaration of main
void main()
is nit a standard declaration.
You should declare the function main like
int main( void )
How can you interpret the following line of code?
int (*arrayABC)[10];
In my textbook, it says that we have a pointer to a pointer to the 0th element of an integer array.
However, I don't quite understand this.
My interpretation: We have some variable, which gets as its value some address. This address is then the address of the 0th element of an UNNAMED integer array. Basically we have a pointer to the 0th element.
Why then to have a pointer TO A POINTER?
This is a pointer to an array. It is not a pointer to a pointer. Arrays and pointers are different. An array has an address, but an array is not an address. An array is a series of contiguous elements.
This pointer points to the whole array and not just the first element, in the same way that a float * points to the whole float and not just the first byte.
If you have for example:
int foo[10];
int (*arrayABC)[10] = &foo;
then the expressions (*arrayABC) and foo are identical. E.g. foo[3] is the same as (*arrayABC)[3].
If you have an object of a type T then a pointer to the object is declared like
T obj;
T *ptr = &obj;
Now let's the type T is defined the following way
typedef int T[10];
Thus the code above
T obj;
T *ptr = &obj;
can be rewritten using the typedef definition like
int obj[10];
int (*ptr)[10] = &obj;
In the both cases, when T is some abstract type and when T is an alias for int[10], ptr is a pointer to an object. In the last case ptr is a pointer to an array of 10 elements of type int. That is the object pointed to by ptr has array type. Arrays and poiters are different types.
Try the following simple demonstrative program
#include <stdio.h>
int main( void )
{
typedef int T[10];
T a;
T *pa = &a;
printf( "%zu\n", sizeof( *pa ) );
int b[10];
int ( *pb )[10] = &b;
printf( "%zu\n", sizeof( *pb ) );
}
Its output is
40
40
As you can see the both values are equal to the size of an integer array of 10 elements. So the pointers point to arrays.
If you write
int *arrayABC[10];
you will get an array of 10 pointers of type int *.
If you write
int (*arrayABC)[10];
you will get a pointer to an array of 10 integers.
In my textbook, it says that we have a pointer to a pointer to the 0th element of an integer array.
Your textbook is ... badly worded, let's leave it at that. It's a pointer to a 10-element array of int.
I can kind of see where the book is coming from. Given the declaration
int (*a)[10];
the expression *a will have type int [10] (10-element array of int). However, unless that expression is the operand of the sizeof or unary & operators, it will be converted ("decay") from type int [10] to int *, and the value of the expression will be the address of the first element of the array:
Expression Type "Decays" to Value
---------- ---- ----------- -----
*a int [10] int * Address of first element of the array;
equivalent to `&(*a)[0]`.
Thus, if I call a function like
foo( *a );
what the function actually receives will be a pointer to the first element of the pointed-to array (its type will be int *, not int **).
So in effect, yes, a often winds up behaving as a pointer to a pointer to the first element of the array; however, its type is not "pointer to pointer to int", and type matters. Given:
int (*a)[10];
int **b;
then you'll get different behavior for the following:
sizeof *a vs. sizeof *b
a + i vs b + i (also applies to a++ vs b++)
This question already has answers here:
C pointer to array/array of pointers disambiguation
(13 answers)
Closed 8 years ago.
I just want to make sure the difference between *a[5] and (*a)[5] in C language.
I know that the *a[5] means the array a can have five elements and each element is pointer.
so,
char *p = "ptr1";
char *p2 = "ptr2";
char *a[5] = { p , p2 };
It does make sense.
But when I changed *a[5] to (*a)[5] it doesn't work.
char (*a)[5] = { p , p2};
What does (*a)[5] mean exactly?
In addition,
is there any difference between *a[5] and a[5][], and (*a)[5] and a[][5]?
A great web site exist that decodes such prototypes: http://cdecl.org/
char *a[5] --> declare a as array 5 of pointer to char
char a[5][] --> declare a as array 5 of array of char
char (*a)[5] --> declare a as pointer to array 5 of char
char a[][5] --> declare a as array of array 5 of char
They are different types:
char *a[5]; // array of 5 char pointers.
char (*a)[5]; // pointer to array of 5 chars.
In the first example you got an array of pointers because the brackets take precedence when parsing. By putting the asterisk inside the parenthesis you override this and explicitly put the pointer with higher precedence.
You use parentheses to make the pointer designator * "closer" to the variable, which alters the meaning of the declaration: rather than an array of pointers, you get a single pointer to an array.
Here is how you can use it:
char x[5]={'a','b','c','d','e'};
char (*a)[5] = &x;
printf("%c %c %c %c %c\n", (*a)[0], (*a)[1], (*a)[2], (*a)[3], (*a)[4]);
Note that the compiler knows that a points to an array:
printf("%z\n", sizeof(*a)); // Prints 5
Demo on ideone.
char *a[5];
create an array of 5 pointers to char
printf("%c",*a[5])
a is an array of pointers
so this expression means print the sixth element character value a[5] is pointing to.
char (*a)[5]
create an array of 5 char and assign a the address of the first element of this created array
printf("%c",(*a)[5])
a points to the first element of an array of character
So this expression means print the sixth char element value of the array that a is pointing to.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Sizeof an array in the C programming language?
Why sizeof(param_array) is the size of pointer?
void printSizeOfArray(int a[])
{
printf("%lu\n", sizeof(a));
}
int main()
{
int it;
int a[4] = {0};
printSizeOfArray(a);
return 0;
}
When I run the code I get 8. Why is a pointer to an array a pointer of type void?
And if a pointer to an array is of type void, why, when I write:
int *it;
int a[4] = {0};
it = a;
printf("%lu\n", sizeof(it));
It works ok as well? How can I point with an int?
Also, why does it print 8 in the second and not 4? It is a pointer to array (void*) and not an int.
Arrays in C often "decay" to just pointers to the first element. This pointer doesn't retain any information about the size of the array, as you've noticed. When an array is passed to a function, such decay occurs.
The proper size can only be computed with the proper declaration in scope. So, you can make it work for functions, but then then size of the array becomes part of the function's prototype which is rarely useful:
void printSizeOfArray(int a[3]);
This is why typical C code always passes the size separately.
Basically, C's support for arrays is "weak".
int *a; // this is a pointer
int arr[]; // this is an array. not a pointer, not a "pointer to void"
Why is a pointer to an array a pointer of type void?
It's not. It's an array. When you pass it to a function it decays into a pointer to an int. Why do you think it's a void *?
When I run the code I get 8.
That's the size of a pointer on your 64-bit system. Try this:
int *a;
printf("%d\n", sizeof(a));
You'll see it's 8, because a pointer on your system takes 8 bytes.
And if a pointer to an array is of type void, why, when I write:
int *it = a;
It works ok as well? How can I point with an int?
That's because it decays into a pointer to an int. You can use a void * to point to it as well because void * is typeless (it can point to anything).
Also, why does it print 8 in the second and not 4?
It should never print 4. You're question should be "why does it print 8 and not 32?". It's printing 8 because that's the number of bytes to represent a pointer to an int on your system and it is a pointer to an int. If you did sizeof(a) you should see a result of <array_size> * sizeof(int) so that's most likely 4*8 on your system or 32.
It's because of arrays decay into pointers in function calls, hence when you call a function with an array name, the argument in function is actually the pointer of that type so the sizeof() gives you the size of the pointer on that machine, that's why its printing 8
Mind one thing:
void printSizeOfArray(int a[])
and
void printSizeOfArray(int *a)
are same
I have an array of int pointers int* arr[MAX]; and I want to store its address in another variable. How do I define a pointer to an array of pointers? i.e.:
int* arr[MAX];
int (what here?) val = &arr;
The correct answer is:
int* arr[MAX];
int* (*pArr)[MAX] = &arr;
Or just:
int* arr [MAX];
typedef int* arr_t[MAX];
arr_t* pArr = &arr;
The last part reads as "pArr is a pointer to array of MAX elements of type pointer to int".
In C the size of array is stored in the type, not in the value. If you want this pointer to correctly handle pointer arithmetic on the arrays (in case you'd want to make a 2-D array out of those and use this pointer to iterate over it), you - often unfortunately - need to have the array size embedded in the pointer type.
Luckily, since C99 and VLAs (maybe even earlier than C99?) MAX can be specified in run-time, not compile time.
Should just be:
int* array[SIZE];
int** val = array;
There's no need to use an address-of operator on array since arrays decay into implicit pointers on the right-hand side of the assignment operator.
IIRC, arrays are implicitly convertible to pointers, so it would be:
int ** val = arr;
According to this source http://unixwiz.net/techtips/reading-cdecl.html, by using the "go right when you can, go left when you must" rule, we get the following 2 meanings of the declarations given in the previous answers -
int **val ==> val is a pointer to pointer to int
int* (*pArr)[MAX] ==> pArr is a pointer to an array of MAX length pointers to int.
I hope the above meanings make sense and if they don't, it would probably be a good idea to peruse the above mentioned source.
Now it should be clear that the second declaration is the one which moteutsch is looking for as it declares a pointer to an array of pointers.
So why does the first one also work? Remember that
int* arr[MAX]
is an array of integer pointers. So, val is a pointer to, the pointer to the first int declared inside the int pointer array.
#define SIZE 10
int *(*yy)[SIZE];//yy is a pointer to an array of SIZE number of int pointers
and so initialize yy to array as below -
int *y[SIZE]; //y is array of SIZE number of int pointers
yy = y; // Initialize
//or yy = &y; //Initialize
I believe the answer is simply:
int **val;
val = arr;
As far as I know there is no specific type "array of integers" in c, thus it's impossible to have a specific pointer to it. The only thing you can do is to use a pointer to the int: int*, but you should take into account a size of int and your array length.