问题
This question was asked in my Sem-2 examination. Question asked us to give the desired output.
int main(void)
{
int a[] = {10,20,30,40,50,60};
int (*p1)[2]=a , (*p2)[3]= a;
if(sizeof(p1)==sizeof(p2))
printf("%d",*(*p1+2));
if(sizeof(*p1)==sizeof(*p2))
printf("%d",*(*(p2+1)));
return(0);
}
Compiler warnings:
Warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
initialization from incompatible pointer type [-Wincompatible-pointer-types]
Output that I expect: 20
Output that I get when I run it: 30
Using : gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
回答1:
Let's ignore the undefined behavior to work out what is probably happening.
p1
and p2
are both pointing to a[0]
(ignoring the incompatible pointer types).
p1
and p2
are both pointers. Pointers to object types are generally the same size (assume this is the case), so sizeof(p1)==sizeof(p2)
will be true.
p1
is of type int (*)[2]
, so *p1
is of type int[2]
. In most expressions, an array will decay to a pointer to its first element, so in the expression *(*p1+2)
, *p1
will decay to an int *
and will be pointing to a[0]
. Therefore *p1+2
will be pointing to a[2]
. Therefore *(*p1+2)
will be the same as a[2]
, which has the value 30
. Therefore the program prints 30
.
An array does not decay to a pointer when it is the operand of the sizeof
operator. *p1
is of type int[2]
and *p2
is of type int[3]
, so sizeof(*p1)==sizeof(*p2)
is equivalent to sizeof(int[2])==sizeof(int[3])
, which is false. Therefore the second printf
call that prints the value of *(*p2+1)
is not evaluated.
(Let's pretend the second printf
is called and that *(*p2+1)
is evaluated. *p2
is of type int[3]
and in this expression it decays to an int *
pointing to a[0]
. Therefore *p2+1
points to a[1]
. Therefore, *(*p2+1)
will be the same as a[1],
which has the value 20
.)
来源:https://stackoverflow.com/questions/60285607/problem-in-sizeof-operator-and-poiner-declaration