What is pointer to array of integers - c

In this example, what it means? In my opinion in this, to all the address of array b[] ,array a[] will point correspondingly to all its location ? So do we write it in the following way?
int (*a)[10];
int b[10];
a = &b;

a is a pointer to an array of 10 ints. a=&b; means that a is pointing to array b, i.e, It contains the address of the first byte of b which is the address of array b.

It means a is a pointer to an array of 10 ints. The declaration like this where number of elements is specified is used to make pointers to two-dimensional arrays. Like
int (*a)[10];
int b[][10];
a=b;
If you are creating a pointer to one dimensional array, declaration like this is not necessary. If you have b an array of 10 ints and you want to make a pointer to it simply do this
int *a;
int b[10];
a=b;
Also & is not necessary on arrays because b is already the address of first element in the array. & is only necessary when you want an address of specific member of the array like int *a=&b[5];

a is a pointer to an array of 10 integers.
So, for example, a++ will increase a
by the size of int(ie = 4 bytes)

Related

Define an array to 2 dimensional array

I have this code:
int a[2][3]={{1,2},{1,3,4}};
int b[2][3]={{4,6},{22,33,55}};
int (*comb1[4])[3]={a,b,a,b};//works
int (*comb2[4])[2][3]={a,b,a,b};//it gives me warning: initialization from incompatible pointer type
Quoting http://cdecl.org/:
1.declare comb1 as array 4 of pointer to array 3 of int
2.declare comb2 as array 4 of pointer to array 2 of array 3 of int
I want to use the comb as 3dim array, where the first dimension selects the pointer of [2][3] and the rest identify the element.
This is achieved by comb1, is it possible to achieve something similar using in the inside of the declaration the [2][3]. (like what I have tried to do with comb2 without success. At the end I want to use e.g. comb2[0][0][0])
I'm assuming you want a pointer to a two-dimensional array. Your second declaration is correct (for an array of those), but your initializer is wrong: a and b are arrays, not pointers to arrays.
Fix:
int (*ab[4])[2][3]={&a,&b,&a,&b};
If you want to use comb[0][0][0] to access the first element of a, andcomb[1][0][0] to access the first element of b, you should use comb1 from your question:
int (*comb[4])[3] = {a, b, a, b};
This might be confusing, since comb is supposed to contain pointers to a and b, which are 2x3 matrices, not arrays of 3 ints, as this declaration seems to indicate. Shouldn't the number 2 be somewhere in there?
But remember that arrays are second-class citizens in C, and in most cases they are handled not as actual arrays, but as pointers to the first element in the array. This is also true concerning pointers to arrays. In general you don't use pointer to array, but pointer to the first element of the array. The address would be the same, but the data types are different. Here is a simpler example:
float a[17]; // This is an array of 17 floats
float *p = a; // This is just a pointer to float, not to array of floats
a[0] = 3.14; // Setting the first element of a
p[0] = 3.14; // Setting the same element, through p
Note that there is no "17" in the declaration of p.
You can use a pointer to the array, but then you need an extra level of indirection, to follow that pointer and get the right data type:
float (*pa)[17] = &a; // Pointer to array of 17 floats
(*pa)[0] = 3.14; // Setting the first element of a, through pa
You could write pa[0][0] instead of (*pa)[0], since a[0] in C is equivalent to *a, but that would be misleading, since it would give the impression of there being a two-dimensional array, when all you have is a pointer to a single-dimensional array.
What might be really confusing is that in the code above, pa, *pa and a will all be the same memory address:
printf("a = %p\n", (void*)a);
printf("pa = %p\n", (void*)pa);
printf("*pa = %p\n", (void*)(*pa));
Output when I ran it on my computer:
a = 0x7fff875a07e0
pa = 0x7fff875a07e0
*pa = 0x7fff875a07e0
Since arrays are a bit special, pointers to arrays are a bit special too. If a is an array, both a and &a (when used in most contexts) give the same address (but different data types). And in reverse: If p is a pointer to an array, both p and *p give the same address (but different data types).
In summary: If you think that since a is 2x3 matrix, the declaration of comb should somehow say both 2 and 3, and not just 3, that is misguided.
You can do so, if you absolutely want to, as melpomene has shown. But in that case you need to write an extra pointer indirection: (*comb[0])[0][0].

Pointers in C - 1D and 2D

I know that, for the following:
int a[10];
a is a pointer of the type int * to a[0], while &a is a pointer of type int (*)[10].
Now my question is for the following 2D array:
int b[20][30];
Is b a pointer of the type int **? Or is it a pointer of the type int (*)[30]?
Is &b a pointer of the type int (*)[20][30]?
Arrays are not pointers (this point cannot be stressed enough).
That being said, an array decays to a pointer to its first element. For example:
int a[10];
int b[20][30];
void print_a(int *);
void print_b(int (*)[30]);
print_a(a);
print_b(b);
The first element of a is a[0], and similarly the first element of b is b[0]. You basically take that first dimension away, and change it to a (*); I'll explain more in a moment since it is a bit more complex than that.
The relationship between pointers and arrays is riddled with contextual subtleties that aren't terribly difficult to grasp, but the size information in various scopes makes it interesting and also helps to give you an idea of how the decay works:
#include <stdio.h>
int h(int *pa)
{
printf("h(int *): sizeof pa=%zu\n", sizeof pa);
printf("h(int *): sizeof *pa=%zu\n", sizeof *pa);
return *pa;
}
int g(int (*pa)[5])
{
printf("g(int (*)[5]): sizeof pa=%zu\n", sizeof pa);
printf("g(int (*)[5]): sizeof *pa=%zu\n", sizeof *pa);
return h(*pa);
}
int f(int (*pa)[3][5])
{
printf("f(int (*)[3][5]): sizeof pa=%zu\n", sizeof pa);
printf("f(int (*)[3][5]): sizeof *pa=%zu\n", sizeof *pa);
return g(*pa);
}
int main(void)
{
int arr[2][3][5] = {{{11235}}};
printf("main: sizeof arr=%zu\n", sizeof arr);
printf("main: sizeof *arr=%zu\n", sizeof *arr);
printf("%d\n", f(arr));
}
Every pointer is the same size (this may not always be true on all platforms!), but by dereferencing the pointer, you see the size of a given element of the array, whether you dereference using the unary * operator or the [N] array notation, which is equivalent to *((array)+(N)) by definition.
Anyway, going back to the difference between pointers and arrays, you should understand that int[20][30] is not the same as int **. Why is that? Because of the fact that int[20][30] decays to a pointer of type int(*)[30], no more decay can occur until the pointer is dereferenced. Moreover, int ** is actually int *(*), which means it can point to the first element of an array of pointers. That is, int ** might have once been int *[N].
int foo[x][y][z] <=> int (*foo)[y][z]
int *foo[m][n] <=> int *(*foo)[n]
int (*foo[a])[b] <=> int (**foo)[b]
In the first case, we have a 3-D array, which decays to a pointer to a 2-D array; in other words, an array of arrays and a pointer to an array are closely related and interchangeable in many contexts aside from the size issue. The first dimension x is the one that decays, leaving the y and z dimensions.
In the second case, we have a 2-D array of pointers. This decays to a pointer to an array of pointers. Again, an array of arrays is closely related to a pointer to an array, and dimension m decays, leaving dimension n.
In the third case, we have an array of pointers to arrays. It decays to a pointer to a pointer to an array. Since dimension a is closest to the variable name, that is the one that decays, leaving dimension b. Note that since it is an array of pointers to arrays, the pointers could point to the first element of arrays themselves:
int arr[2][3][5];
int (*foo[2])[5] = { arr[0], arr[1] };
int (**foo_ptr)[5] = foo;
Recap:
Array (size A) of arrays (size B) <=> Pointer to array (size B)
Array (size A) of pointers <=> Pointer to pointer
The array that decays/grows is always the innermost array/pointer, the innermost being the one closest to the variable name in the variable declaration, with arrays having higher associativity than pointers, though of course parentheses make all the difference.
This rabbit hole obviously can be confusing, but I hope I helped a bit at least!
First of all make it clear that arrays are not pointers. Relationship between pointers and arrays is subtle. I would suggest you to read second chapter of tutorial on pointers by Ted Jensen first.
I would like to tell you something in a nutshell what has been describe in this chap. Consider following example.
int a[10];
int *p;
Now you can write
p=a;
that is equivalent to
p=&a[0];
This thing make many texts to say array is name of pointer. But it is better if you say "the name of the array is the address of first element in the array" .
Because though you can write
p=a;
but you can not write
a=p;
Now come to your question:
From above discussion it should be clear that b is not pointer of type int** .For example:
int b[10][10];
int **x;
int *p;
b=&p; // this is error
x=&p; // this fine
For your other questions you may use online CDECL.
if you write
int b[10][10]; --> declare b as array 10 of array 10 of int
int (*p)[10]; --> declare p as pointer to array 10 of int
int (*p)[10][20]; --> declare p as pointer to array 10 of array 20 of int
No, a is not of type int*, it is of type int [10] (i. e. of an array type). This is why sizeof(a) will give you the size of the array (40 bytes, assuming 32 bit integers).
Likewise, b is of type int [20][30], which is nothing other than an array of arrays. I. e. sizeof(b[0]) is the size of one line array, which is 120 in this case, the size of the entire array (sizeof(b)) is 20 times the size of the line arrays, which is 2400 bytes in this case.
The trick is, that an array decays into a pointer to its first element in almost all contexts. So when you do pointer arithmetic (as in b[3]) on the 2D array, b decays into a pointer of type int (*)[30], so the pointer arithmetic skips rows, adding three times the size of a row (360 bytes in this case) - the rows are the elements of the 2D array. The resulting type of b[3] is int [30], i. e. the dereferenced pointer.
Once you have dereferenced to a row array with b[3], you can again invoke pointer arithmetic to select the correct element in this row (b[3][5]). Again, the array-pointer-decay is invoked, the mechanic is the same.
Note that there is no pointer array involved as is the case when you emulate a 2D array with an int**. The double dereference b[3][5] translates into something like ((int*)b)[3*30 + 5] by virtue of array-pointer-decay, only the element itself is accessed from memory.
int* temp;
int arraySize = 20;
temp = (int *)malloc(arraySize * sizeof(int));
This will create a section in memory 20 "ints" long, similarly as you mentioned.
int** temp;
int arraySize = 20;
int rowSize = 10;
temp = (int **)malloc(arraySize * sizeof(int *));
for(i=0; i<arraySize; i++){
temp[i] = (int *)malloc(rowSize * sizeof(int));
}
That is what the 2D array would actually look like.
temp[0] would give you the address of the first "array". In which you could do something like above int *array = temp[0] then access it like a normal array but using *array[0] to get the value.
2D arrays really don't mesh well with pointers and saying *temp[0] to get the values of the first array. You can try to mess with it, you'll figure it out, but don't have a machine that can compile C with me right now.
Reference that may help: http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html

Array name as pointer and array name with & operator [duplicate]

This question already has answers here:
Difference between pointer to pointer and pointer to array?
(3 answers)
Closed 9 years ago.
Whats the difference between last 2 statements:
int a[20];
int *b=a;
int *c=&a;
I think both are same, but in a recent interview the interviewer was keen to know the difference which I didn't know.
Can somebody please explain with detail example.
I went to this post but didn't understand the array related part:
Function pointers and address of a function
int a[20];
You are declaring an array a which can hold 20 int
int *b=a;
Since a is an array, a evaluates to the base address of array a (i.e. first element of a). So b is an int pointer which points to the first element in array a
int *c=&a;
&a means address of a which is being assigned to int pointer c. But, this is not good as &a is address of an array (not the base address of the array), so you should define c as int ** (i.e. pointer to a pointer) or assign it to &a[0] (i.e. the address of the first element of array a). Since array is assigned contiguous memory, once you have the base address of the array, you can easily access the remaining elements of the array by doing *(b+i) where i is an index of the element you want to access.
However,
int a = 5;
int *b= a ; // WRONG -- b will not point to the address of variable a, but to the memory location 5, which is what you do not want
int *c = &a; //CORRECT

Experimenting with Pointers and Arrays in C

Can someone explain to me the difference between:
int *arr[5] vs. int (*arr)[5] vs. int *(*arr)[5]
I'm trying to wrap my mind around how pointers/arrays are actually represented in C...
I would suggest using http://cdecl.org.
int *arr[5] "declare arr as array 5 of pointer to int"
int (*arr)[5] "declare arr as pointer to array 5 of int"
int *(*arr)[5] "declare arr as pointer to array 5 of pointer to int"
plus a visit to this page from MSDN: Interpreting more complex declarators.
The first makes a variable named arr that is of an array length 5 of type int*, so it is an array length 5 of int pointers.
The second declares a variable named arr that is a pointer to an array length 5 of type int. So it is a pointer to an array of ints length 5.
The third is a variable named arr that is a pointer to an array of length 5 of type int pointer. So it is a pointer to an array length 5 of int pointers. Or, a pointer to the type of the first case!
To think of how to analyze things like this in the future, realize that parenthesis have the highest priority here so by having (*arr) it is first, and foremost, a pointer. Then the array notation has second highest priority, so (*arr)[5] is a pointer to an array of length 5...but what type of array? Well the type is the lowest priority, so that comes last. If we have int (*arr)[5], then it is a pointer (1st) to an array length 5 (2) of type int (3).
With that we can look at something like: int** (*arr)[7] It is a pointer named arr (1) to an array length 7 (2) of type int**, or pointers to pointers of ints (3).
As far as wondering how pointers/arrays are represented in C...
pointers and arrays are both 32 bit variables (like ints on most systems) that contain a 32 bit address to a memory location (where they point). Arrays obviously point to the beginning of an array, so *arr == arr[0]. While pointers can point to anything. When you declare an array (arr[5], arr[1000], etc.) it makes a pointer named arr as well as reserves whatever space is in between the brackets (5 or 1000). But when you declare a pointer (*arr), it does not reserve any space. Otherwise, the variable arr in both cases is simply a pointer. Also, if you want to be confusing, you could even dereference your pointers like so: pointer[0], instead of *pointer.
As a final note example, we can look at something like: int * (*arr)[5][7] and analyze both what it is and what the compiler is doing:
First, it is a pointer named arr (1), to an array length 5 (2) each to an array length 7 (3) but because an array length n is just a pointer to a reserved location in memory, so really (2) is an array length 5 to a pointer (pointing to memory blocks of size 7). Finally, each of the memory blocks of size 7 (3) is of type int * (4).
So, it is a pointer to an array length 5 of pointers to arrays of length 7 of type int *!
I hope this helps! I know I had a lot of fun playing with C and seeing what was possible and what different things did =)
A pointer is the address of another object. An array is a contiguous block of objects. So:
int *a[5];
a is an array of 5 pointers to int. This means that a represents a block of 5 contiguous address values, where each of those values can hold the address of an int.
int (*b)[5];
b is a pointer to an array of 5 ints. This means that b is a single address value, where that value can hold the address of an array of 5 ints.
int *(*c)[5];
c is a pointer to an array of 5 pointers to int. This means that c is a single address value, where that value can hold the address of an array of 5 pointers to int. This could hold the address of the first object a, so c = &a; would be valid.
int *arr[5] is an array of five int*s.
int (*arr)[5] is a pointer to an array of five ints.
int *(*arr)[5] is a pointer to an array of int*
Generally, one makes a typedef:
typedef int fiveintarray[5];
typedef int* intptr;
typedef intptr fiveintptrarray[5];
And then uses it:
fiveintarray array; //array of five integers
fiveintarray* pointer_to_array; // pointer to array of five integers
fiveintptrarray array; //array of five pointers to integers
fiveintptrarray* pointer_to_array; //pointer to array of five pointers to integers
int *arr[5] -> an array, of length 5, of pointers to int
int (*arr)[5] -> a pointer to int arrays of length 5
int *(*arr)[5] -> a pointer to a pointer to int arrays of length 5

Pointer to Array of Pointers

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.

Resources