is a==*a?? A query regarding pointers - c

int main()
{
int a[4][3] = {10,20,30,40,50,60,70,80,90,100,110,120};
printf("%d",((a==*a) && (*a==a[0])));
return 0;
}
Prints 1 on the console.
Anyone has logical explanation??

Arrays are converted to pointer when used in an expression except when they are an operand of sizeof and unary & operator. a and *a are of different types (after decay) but have the same address value.
a decays to pointer to first element (first row) of array and is of type int (*)[3].
*a dereference the row pointed by a and further decayed to pointer to first element of first row. It is of type int *.
a[0] is representing the first row which is of type int [3]. In expression it decays to pointer to first element of first row and is of type int * after decay.
As the address of an array the address of first byte, therefore address of an array, address of first row and address of first element all have the same value. So, after decay, all of a, *a and a[0] points to same location.
Here is a graphical view of the above explanation:
What exactly is the array name in c?

Is a==*a?
The answer is yes if the array a is multi dimensional array.
so what if it is single dimensional? let me give you an example.
void main()
{
int a[4]={1,2,3,4};
printf("%d",((a==*a)&&(*a==a[0])));
}
The answer in this case would be 0.
This is because 'a' represent address of array or address of first element of array but *a represent value(pointer to that value). the address and value are different types so answer would be 0.
But in case of multi dimensional arrays 'a' represented as a[0][0] because it represent pointer to the first element of first sub array of multi dimensional array.
So the answer is yes if the array is multi dimensional array

Related

Why application of indirection to a two-dimensional array gives a pointer?

After reading some posts on this site, I realized that array in C isn't just a constant pointer as I originaly thought, but is itself a distinct type, but in most cases array "decays" to a constant pointer to the first element of the array. Because of this new information, a question arised in my mind. Suppose we have a two-dimensional A[10][10]. Why is the result of the expression *A a pointer to the first element of the array ? I thought that in this expression, A decays to a constant pointer to the first element of the array A[0][0], and then the application of the indirection should give us the value of the A[0][0], but in fact it still gives us the address of the first element of the array. Certainly, something is wrong with my logic or my understanding of the arrays or pointers, so where do I get it wrong ?
Thanks in advance.
The first element of A is A[0], not A[0][0].
This is because A is an array of ten things. C does not have two-dimensional arrays as a primary type. An array with multiple dimensions is derived or constructed as multiple layers of arrays. To the compiler, the resulting type is still just an array, whose elements happen to be further arrays.
Thus, in *A:
A is converted to a pointer to its first element. That pointer is &A[0], so *A becomes *&A[0].
* and & cancel, so the expression becomes A[0].
A[0] is an array of ten elements, so it is converted to a pointer to its first element, &A[0][0].
*A, or A[0], is itself an array of 10 elements and and array is always expressed by a pointer to its first element. However A[10][10] (let's say an array of ints) is effectively a block of memory holding 100 ints, the 10 of the first row followed by the 10 of the second row and so on. But if the expression *A or A[0] would return an int instead of a ptr to that row, it would be impossible to use the expression A[0][0], right ?
However, because such multidimensional array is a single block of memory, it's also possible to cast it to a pointer and then access it with an expression of this kind :
((int *)A)[iRow * 10 + iCol];
Which is equivalent to the expression :
A[iRow][iCol];
But this if it's possible for a 2D array declared this way :
int main()
{
int A[10][10] = { 0 };
A[9][9] = 9999;
printf("==> %d\n", ((int *)A)[9 * 10 + 9]); //==> 9999
return 0;
}
It is not if the memory is potentially made of separate blocks of bytes (probably requiring several calls to malloc) as with this kind of expressions :
int * A[10]; // or
int ** A;
A decays to a constant pointer to the first element of the array
A[0][0]
No, it does not. Why?
C standard specifies that *(pointer + integer) == pointer[integer] so the *A is an equivalent of *(A + 0) which is A[0]. A[0] will not give you the element A[0][0] only the single dimensional array which will decay to pointer to the first element of the first row of this array.

2D Array decaying to pointer in C

This is an extended question from the answer by "Some programmer dude" in this forum.
Accessing 2D array elements using pointer arithmetic in C
To quote the answerer,
&s[0][0]. This is of type int *.
&s[0]. This is of type int (*)[2].
s[0]. This will decay to a pointer to the first element in s[0], and is equal to 1.
s. This will decay to a pointer to the first element in s, and is equal to 2.
&s. A pointer to the array, of type int (*)[4][2].
I don't get why 3 equals 1 and 4 equals 2?
I thought 3 equals 2 and 4 equals 5.
For example, putting s[0] will give the address of s[0] since it's an array, hence s[0] = &s[0].
Let's take a look at your 2D array and consider the types of the various variables you've asked about:
int s[4][2] = {
{1234,56},
{1212,13},
{1434,80},
{1312,78}
};
Now:
s is a 2D array of ints.
s[0], s[1], etc. are arrays of int.
Your question states:
putting s[0] will give the address of s[0] since it's an array, hence
s[0] = &s[0]
This is not correct. When used in an expression, the name of an array decays to a pointer to the first element of the array. What is the first element of s? It is the entire array s[0].
Since s[0] is an array, it is equivalent to the address of its first element. What is the first element of the array s[0]? It is the int s[0][0]. So since the value of the array name s[0] when used in an expression is equivalent to the address of the first element of the array, i.e., to s[0][0], we have:
s[0] == &s[0][0]
This is why (3) in the answer you have quoted is equivalent to (1).
Similarly, s is equivalent to &s[0]. When used in an expression, the array name s decays to a pointer to the entire array s[0]; as a pointer to an array of two int elements, its type is int (*) [2]. Its value is the address of &s[0], i.e., the address of the entire array (not just of its first element). This is why (4) is equivalent to (2).
As "Some programmer dude" showed in the diagram in his answer to your original question, these various pointers might point to the same location in memory, but semantically they are quite different.
Hope this helps!

Difference between x and &x in c

What is the difference between a pointer to an array and a pointer to the first element of an array? In most cases they would be same. Please specify an example when they are not the same. Thank you.
The type is different:
int x[1] = {0};
&x[0] is a pointer to the first element of x array and is of type int *.
&x is a pointer to x array and is of type int (*)[1].
But their value is the same because there is no padding in arrays:
(int *) &x == x /* in a value context the expression evaluates to 1 */
The identity of an object is given by the pair (address, type). Different objects can have the same address as long as their types are different, in which case one is a subobject of the other.
This is the case with arrays: The array is an object, and the array elements are objects, and the array elements are subobjects of the array. The first element happens to have the same address as the array itself. Something similar is true for structs and the first struct member.
So if you have an array T a[N], then the type of a is T[N] and the type of a[0] is T, and so the address of the array is
T (*array_addr)[N] = &a;
and the address of the first element is
T * elem_addr = &a[0];
Since a naked array expression decays to a pointer to the first element under certain conditions, the last line could also be written as T * elem_addr = a;, which has the exact same meaning.
The main difference is that when you obtain the reference to an array, it decays to a pointer and sizeof can't be used anymore on it to obtain the array size, eg:
int array[10];
printf("%d\n", sizeof(array)/sizeof(array[0]));
printf("%d\n", sizeof(&array)/sizeof(array[0]));
This prints on x64:
10
2
Of course you will lose any reference to the size of the array even if you convert to a pointer without any use of the & operator:
printf("%d\n", sizeof((int*)array)/sizeof(array[0])); // prints 2
you can print the a and &a, than print a++ and &a++. Through the result, you will know the answer, just try it. a means a element address, and &a means the array address. int a[] = {1, 2 };
Pointer to an array and pointer to the first element of an array is represented as q=&a and p=a. When you increment the p as p++ it will point to the next element in array but when you increment q++ it will give to the next location to the last element in that array. Thus pointer to an array represents to whole array while pointer to first element in array represents only to the first element in array.

Does name of a 2D array give its base address in C?

Does name of a 2D array give its base address in C like in 1D array? And how can i store the base address of a 2d array in a pointer variable?
It decays to a pointer to the first element:
int a[5][7];
decays to
int (*pa)[7] = a;
In practice, the value stored in pa will be the same as that of a pointer to the first int element of a, but the correct way to get a pointer to the first element of a is to use
int *p_elm = &(a[0][0]);
or equivalently
int *p_elm = &(pa[0][0]);
However, note that a pointer to the first element can't (strictly) be treated as a pointer to the beginning of a N*M array; see e.g. http://www.lysator.liu.se/c/c-faq/c-2.html#2-11
A 2D array is essentially a 1D array, where each element itself is an array.
The name of the array is equivalent to &arrayName[0].
Assigning a pointer to this address is same as always, something like:
int myArray[5][5];
int (*arrayptr)[5] = myArray;
This says arrayptr is a pointer to an array of 5 integers. Since myArray is an address to the first element, which is an int[5], our declaration is fine.
When you dereference this pointer however, you're going to get the first element, which is an array. Therefore you can do something like:
(*arrayptr)[3]; // parens necessary for precedence issues
to access the 3rd element in the array nested inside the first element of the "outer array".
It is the equivalent of
myArray[0][3];
What's happening is you're dereferencing arrayptr which will yield a 1D array (of size 5 in this case).. then you're asking for the 4th element of this 1D array.
Now, if what you're looking for is the top-left "corner" of the matrix, you will want:
int *topleft = &(myArray[0][0]);
Yes and you the store the address as:
int *p = &a[0][0];
Use the address of operator to point to the offset of base.
char base[2][2];
int *basepointer = &base;
I would like to give answer specific to your question.
Whenever you pass name of a 2D Array, that name of array will be decayed into pointer to first element,
In a multi-dimensional array, as multi dimensional array is array of arrays, so first element will be array itself.
So name of 2D array will be decayed to pointer to array, ie pointer to first row having number of elements equal to number of columns in your 2D array.
Remember 2D array is received in a function as pointer to array not pointer to pointer.
int main()
{
int arr[2][3];
display(arr);
............
}
void display( int (*arr)[3])
{
}

Please Explain the ambiguity in pointers in C?

#include<stdio.h>
main()
{ int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}};
printf("%d\n",x);
printf("%d\n",*x); }
Here first printf will print the address of first element.
So why not the second printf prints the value at the address x i.e the first value.
To print the value I need to write **x.
For pointers, x[0] is the same as *x. It follows from this that *x[0] is the same as **x.
In *x[0]:
x is a int[3][5], which gets converted to int(*)[5] when used in expression. So x[0] is lvalue of type int[5] (the first 5-element "row"), which gets once again converted to int*, and dereferenced to its first element.
*x is evaluated along the same lines, except the first dereference is done with an asterisk (as opposed to indexing), and there is no second dereference, so we end up with lvalue of type int[5], which is passed to printf as a pointer to its first element.
Arrays, when used as arguments to functions, decay into pointers to the first element of the array. That being said, the type of object that x decays into is a pointer to the first sub-array, which is a pointer to an array of int, or basically int (*)[5]. When you call printf("%d\n",*x), you are not feeding an integer value to printf, but rather a pointer to the first sub-array of x. Since that sub-array will also decay to a pointer to the first sub-array's element, you can do **x to dereference that subsequent pointer and get at the first element of the first sub-array of x. This is effectively the same thing as *x[0], which by operator precedence will index into the first sub-array of x, and then dereference the pointer to the first sub-array's element that the first sub-array will decay into.
Because of type of *x is 'pointer to array of 5 ints'. So, you need one more dereference to get the first element
PS:
#include <typeinfo>
#include <iostream>
typedef int arr[5]; // can't compile if put arr[4] here
void foo(arr& x)
{
}
int main()
{
int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}};
std::cout << typeid(*x).name() << std::endl;// output: int [5]
foo(x[0]);
return 0;
}
Think about a 2-d array as an array of pointers, with each element in the array pointing to the first element in another array. When you dereference x, you get the value that is in the memory location pointed to by x... a pointer to the first int in an array of ints. When you dereference that pointer, you will get the first element.

Resources