pointer arithmetic


S

somenath

Please help me to verify my understanding about the output of the following program.


int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf
}
return 0;


}

The output is
+++++++++

Size of int = 4

sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5 int is not getting converted to pointer to first element of arry 5 of int . That's the reason the output of 2nd printf is 5 *sizeof int.

Now in case of third printf , type of *p is actually pointer to the first element of arry of 5 int or in easier way type of
*p is now int* . That's the reason the difference between *p+1 and *p+ 0 is sizeof int* . In this case it is 4.

Please let me know if my understanding is correct.
 
Ad

Advertisements

J

James Kuyper

Please help me to verify my understanding about the output of the following program.


int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf
}
return 0;


}

The output is
+++++++++

Size of int = 4

sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5 int
is not getting converted to pointer to first element of arry 5 of int .
That's the reason the output of 2nd printf is 5 *sizeof int.

Now in case of third printf , type of *p is actually pointer to the
first element of arry of 5 int or in easier way type of
*p is now int* . That's the reason the difference between *p+1 and
*p+0 is sizeof int* . In this case it is 4.

That's basically correct, except that I wouldn't have worded it quite
that way. *p is NOT a pointer to the first element of the array; but in
most contexts it gets automatically converted to such a pointer, which
is why people often get that impression. That same rule applies to all
expressions of array type. It simplifies a lot of code, but confuses a
lot of newbies.

The only exceptions to that rule are when sizeof() is applied (as in
your first printf()), or when & is applied (as when you wrote &a1), or
when a string literal is used to initialize an array of char (of which
there are no examples in your code).
 
B

Ben Bacarisse

somenath said:
Please help me to verify my understanding about the output of the
following program.

int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf

You should use %p to print a pointer, and you need to convert the
pointer explicitly to (void *):

printf("address of *p + %d = %p\n", i, (void *)(*p + i));
}
return 0;
}

The output is
+++++++++

Size of int = 4

sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5 int
is not getting converted to pointer to first element of arry 5 of int
. That's the reason the output of 2nd printf is 5 *sizeof int.

Now in case of third printf , type of *p is actually pointer to the
first element of arry of 5 int or in easier way type of *p is now
int*.

Expressions of array type "decay" to a pointer to the first element, so
yes, in most situations *p is an expression of type int *. When the
expression is the operand, this conversion does not happen.
That's the reason the difference between *p+1 and *p+ 0 is
sizeof int* . In this case it is 4.

The difference is sizeof(int) not sizeof(int *). Pointer arithmetic (on
simple architectures) is done using the size of the thing pointed to.

<snip>
 
K

Kaz Kylheku

Please help me to verify my understanding about the output of the following
program.


int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf
}
return 0;


}

The output is
+++++++++

Size of int = 4

sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5 int is
not getting converted to pointer to first element of arry 5 of int . That's
the reason the output of 2nd printf is 5 *sizeof int.

Now in case of third printf , type of *p is actually pointer to the first
element of arry of 5 int or in easier way type of

No, the type of *p is "array of 5 int", which is what you declared it to be:

int (*p)[5]

and that is why the size of *p is 20; int is 4 bytes wide on your platform and
you have 5 of them.

After p = &a1, p does point to the same memory location as &a1[0], but, in
consideration of p's type, it points to the array as a whole.

The expression *p has array type, and when evaluated, it produces a value
which is the same as &a[0]. However, that is just the value produced under
evaluation; it isn't the type of *p.

The type of a value produced by an expression under evaluation can be
different from that expression's type. For instance:

char a = 'x';

a has type "char", but under evaluation, it (usually, on most compilers)
produces a value of type int. sizeof(a) is 1, but a + 1 is an
int + int -> int addition.
*p is now int* . That's the reason the difference between *p+1 and *p+ 0 is sizeof int* . In this case it is 4.

(*p) isn't (int *); (*p) produces (int *) under evaluation.

To recap, what type something *is* and what type value it *produces* are
sometimes different in C.
 
S

somenath

Please help me to verify my understanding about the output of the following

int main(void)

int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf

return 0;




The output is


Size of int = 4

sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5 int is
not getting converted to pointer to first element of arry 5 of int . That's
the reason the output of 2nd printf is 5 *sizeof int.

Now in case of third printf , type of *p is actually pointer to the first
element of arry of 5 int or in easier way type of



No, the type of *p is "array of 5 int", which is what you declared it to be:



int (*p)[5]



and that is why the size of *p is 20; int is 4 bytes wide on your platform and

you have 5 of them.



After p = &a1, p does point to the same memory location as &a1[0], but, in

consideration of p's type, it points to the array as a whole.



The expression *p has array type, and when evaluated, it produces a value

which is the same as &a[0]. However, that is just the value produced under

evaluation; it isn't the type of *p.

According to my understanding the the type of *p also changed from array 5 of int to int* in this expression while evaluating the expression. That's the reason *p+ 1 point to the next integer not to next array 5 of int.

The type of a value produced by an expression under evaluation can be

different from that expression's type. For instance:



char a = 'x';



a has type "char", but under evaluation, it (usually, on most compilers)

produces a value of type int. sizeof(a) is 1, but a + 1 is an

int + int -> int addition.

The sizeof(a+1) is 4 , According to my understanding type of a + 1 is int so the output of sizeof(a +1)will be sizeof int
(*p) isn't (int *); (*p) produces (int *) under evaluation.



To recap, what type something *is* and what type value it *produces* are

sometimes different in C.
Ok. Got it.
 
B

Barry Schwarz

Please help me to verify my understanding about the output of the following
program.
int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf
for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf
}
return 0;
}
The output is

Size of int = 4
sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54
The type of *p is array 5 of int in sizeof operator, as arr of 5 int is
not getting converted to pointer to first element of arry 5 of int . That's
the reason the output of 2nd printf is 5 *sizeof int.
Now in case of third printf , type of *p is actually pointer to the first
element of arry of 5 int or in easier way type of

No, the type of *p is "array of 5 int", which is what you declared it to be:

int (*p)[5]

and that is why the size of *p is 20; int is 4 bytes wide on your platform and
you have 5 of them.

After p = &a1, p does point to the same memory location as &a1[0], but, in
consideration of p's type, it points to the array as a whole.

The expression *p has array type, and when evaluated, it produces a value
which is the same as &a[0]. However, that is just the value produced under
evaluation; it isn't the type of *p.

According to my understanding the the type of *p also changed from array 5 of int to int* in this expression while evaluating the expression. That's the reason *p+ 1 point to the next integer not to next array 5 of int.

Your understanding is incorrect! The type of *p will never change. It
will forever be an array of 5 int. However, when the expression *p
is evaluated, the result of that evaluation will be converted per the
rule for evaluating expressions having array type.
The sizeof(a+1) is 4 , According to my understanding type of a + 1 is int so the output of sizeof(a +1)will be sizeof int

When performing integer arithmetic, all operands of rank less than int
will be promoted to at least int. The same discussion would be
equally true if a was a short.
 
Ad

Advertisements

B

Ben Bacarisse

somenath said:
On 2014-02-21, somenath wrote:
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;

After p = &a1, p does point to the same memory location as &a1[0], but, in
consideration of p's type, it points to the array as a whole.

The expression *p has array type, and when evaluated, it produces a value
which is the same as &a[0]. However, that is just the value produced under
evaluation; it isn't the type of *p.

According to my understanding the the type of *p also changed from
array 5 of int to int* in this expression while evaluating the
expression. That's the reason *p+ 1 point to the next integer not to
next array 5 of int.

I think you've been confused by a technicality in Kaz's post. In C the
term "value" carries with it the idea of the type of that value, but I
think you took Kaz's "it produces a value which is the same as &a[0]" to
refer only to the address that results from the conversion. &a[0] also
has a type (int *) so saying that the value is the same as &a[0] means
that *p is converted to a pointer to a[0] with type int *.

<snip>
 
S

somenath

somenath writes:


On 2014-02-21, somenath wrote:
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;

After p = &a1, p does point to the same memory location as &a1[0], but, in
consideration of p's type, it points to the array as a whole.

The expression *p has array type, and when evaluated, it produces a value
which is the same as &a[0]. However, that is just the value produced under
evaluation; it isn't the type of *p.
According to my understanding the the type of *p also changed from
array 5 of int to int* in this expression while evaluating the
expression. That's the reason *p+ 1 point to the next integer not to
next array 5 of int.



I think you've been confused by a technicality in Kaz's post. In C the

term "value" carries with it the idea of the type of that value, but I

think you took Kaz's "it produces a value which is the same as &a[0]" to

refer only to the address that results from the conversion. &a[0] also

has a type (int *) so saying that the value is the same as &a[0] means

that *p is converted to a pointer to a[0] with type int *.

Yes. I am sorry. I was not aware of that in C "value" carries the idea of type of the value. So whenever somebody speaking about value the type of the value also gets mentioned automatically.

Also I was under the assumption that the type of pointer gets really changed in the above mentioned circumstance. But it does not. "The type of *p will never change. It will forever be an array of 5 int. However, when the expression *p is evaluated, the result of that evaluation will be converted per the rule for evaluating expressions having array type" from Barry Schwarz's article.

I would like to thank all of you for helping me in my C learning path.
 
S

somenath

somenath writes:
On 2014-02-21, somenath wrote:
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
After p = &a1, p does point to the same memory location as &a1[0],but, in
consideration of p's type, it points to the array as a whole.
The expression *p has array type, and when evaluated, it produces a value
which is the same as &a[0]. However, that is just the value producedunder
evaluation; it isn't the type of *p.
According to my understanding the the type of *p also changed from
array 5 of int to int* in this expression while evaluating the
expression. That's the reason *p+ 1 point to the next integer not to
next array 5 of int.
I think you've been confused by a technicality in Kaz's post. In C the
term "value" carries with it the idea of the type of that value, but I
think you took Kaz's "it produces a value which is the same as &a[0]" to
refer only to the address that results from the conversion. &a[0] also
has a type (int *) so saying that the value is the same as &a[0] means
that *p is converted to a pointer to a[0] with type int *.



Yes. I am sorry. I was not aware of that in C "value" carries the idea of type of the value. So whenever somebody speaking about value the type of the value also gets mentioned automatically.



Also I was under the assumption that the type of pointer gets really changed in the above mentioned circumstance. But it does not. "The type of*p will never change. It will forever be an array of 5 int. However, when the expression *p is evaluated, the result of that evaluation will be converted per the rule for evaluating expressions having array type" from Barry Schwarz's article.



I would like to thank all of you for helping me in my C learning path.

After learning ( I think ) the above concepts I have tried to reason out the output of the following program . Please correct me where ever I am wrong.

#include<stdio.h>

int main(void)
{
int a[] = { 1 ,2, 3, 4, 5 };
int b[] = { 1, 2, 3, 4, 5 };
int c[5] , i;
int (*p[2]);
p[0] = a;
p[1] = b;
printf("\nsizeof int = %d\n",(int ) sizeof(int));
printf("\nsizeof int* = %d\n",(int ) sizeof(int*));
printf("\nsizeof a = %d\n",(int ) sizeof(a));

printf("\nSizeof p = %d\n",(int) sizeof(p ));
printf("\nSizeof p + 1 = %d\n",(int) sizeof(p +1 ));
printf("\nSizeof *p = %d\n",(int) sizeof(*p ));
printf("\nSizeof a[0] = %d\n",(int) sizeof(a[0]));

for ( i = 0 ; i < 5 ; i++ ) {
c = *(*p + i ) * *(*(p +1 ) + i );
}
for ( i = 0; i< 5; i++ ) {
printf("%d ",c);
}


return 0;
}

+++
Output
+++++++++

sizeof int = 4

sizeof int* = 4

sizeof a = 20

Sizeof p = 8

Sizeof p + 1 = 4

Sizeof *p = 4

Sizeof a[0] = 4
1 4 9 16 25

+++++++++++++++++++

Let me try to explain the output one after another

sizeof a = 20

a is an array 5 of int. So sizeof returns 5 *sizeof int = 5 *4 =20

Sizeof p = 8

Here the type of p is array 2 of pointer to int. so the result is (int *) + (int *) = 4 + 4 = 8

Sizeof p + 1 = 4

In the expression (p +1), p decays to the pointer to the first element of the array. So the type of p is evaluated to int** since the first elementof array p is &p[0] and p[0] is int* . So the sizeof ( p +1 ) is sizeof(int **)


Sizeof *p = 4

So p is array 2 of pointer to int. That is p is pointing to 2 blocks of memory where both first and second block contain pointer to int (because of p[0] = a ). So *p is int* .

Sizeof a[0] = 4

Type of a[0] is int. So sizeof(a[0]) is sizeof int



Now comes the complex part
c = *(*p + i ) * *(*(p +1 ) + i );

First part *(*p + i )

So p is pointer to array of 2 int*. In the expression (*p +i) p decayed to the pointer to the first element of the array p i.e &p[0]. So the type of p is evaluated to int**. So the type of *p is evaluated to int*. So *p + i is the i th int* starting from p. De-referencing that we get the value of ith element. So essentially *( *p +i) is the complex form of a

Second part

*(*(p +1 ) + i );
p is pointer to array of 2 int*. Now in expression (p +1) p decays to the pointer to the first element of array p . So p is evaluated to int **. p+1 point to the next int ** in array p , that is p[1]. So *(p +1 ) is resulting the int *. (*(p+1) +i ) point to the ith element of p[1]. De referencing that we get the value of p[1] i.e contain of array b.

so c = *(*p + i ) * *(*(p +1 ) + i );
is complex version of c= a * b;

Hope I have got this time somewhat closer to the correct answer.
 
Ad

Advertisements

I

Ike Naar

int (*p[2]);

p is an array of two pointers to int.
for ( i = 0 ; i < 5 ; i++ ) {
c = *(*p + i ) * *(*(p +1 ) + i );


since p has only two elements, for 2<i<5, *p + i does not point an
address that can be dereferenced.


Whoops, missed one asterisk.

*p + i can be dereferenced for 0 <= 1 < 5.
Sorry for the confusion.
 
B

Barry Schwarz

On Fri, 21 Feb 2014 09:37:45 -0800 (PST), somenath

snip 130 lines

Please delete previous text no longer relevant to the discussion,
especially since the broken google interface you are using keeps
inserting additional blank lines.

It would also be nice if you could limit your lines to a length
slightly less than 80.
After learning ( I think ) the above concepts I have tried to reason out the output of the following program . Please correct me where ever I am wrong.

#include<stdio.h>

int main(void)
{
int a[] = { 1 ,2, 3, 4, 5 };
int b[] = { 1, 2, 3, 4, 5 };
int c[5] , i;
int (*p[2]);

The parentheses serve no purpose in the above declaration. They are
only needed if you intended p to be a pointer to an array of 2 int
instead of a array of two pointers. Then you would code int (*p)[2].
p[0] = a;
p[1] = b;
printf("\nsizeof int = %d\n",(int ) sizeof(int));
printf("\nsizeof int* = %d\n",(int ) sizeof(int*));
printf("\nsizeof a = %d\n",(int ) sizeof(a));

printf("\nSizeof p = %d\n",(int) sizeof(p ));
printf("\nSizeof p + 1 = %d\n",(int) sizeof(p +1 ));
printf("\nSizeof *p = %d\n",(int) sizeof(*p ));
printf("\nSizeof a[0] = %d\n",(int) sizeof(a[0]));

for ( i = 0 ; i < 5 ; i++ ) {
c = *(*p + i ) * *(*(p +1 ) + i );
}
for ( i = 0; i< 5; i++ ) {
printf("%d ",c);
}


return 0;
}

+++
Output
+++++++++

sizeof int = 4

sizeof int* = 4

sizeof a = 20

Sizeof p = 8

Sizeof p + 1 = 4

Sizeof *p = 4

Sizeof a[0] = 4
1 4 9 16 25

+++++++++++++++++++

Let me try to explain the output one after another

sizeof a = 20

a is an array 5 of int. So sizeof returns 5 *sizeof int = 5 *4 =20

Sizeof p = 8

Here the type of p is array 2 of pointer to int. so the result is (int *) + (int *) = 4 + 4 = 8


The way you expressed this implies that the two addends could be
different. Since array elements are always the same type, the
expression you used for a above is more consistent
so the result is 2 * sizeof int* = 2*4 = 8
Sizeof p + 1 = 4

In the expression (p +1), p decays to the pointer to the first element of the array. So the type of p is evaluated to int** since the first element of array p is &p[0] and p[0] is int* . So the sizeof ( p +1 ) is sizeof(int **)


Sizeof *p = 4

So p is array 2 of pointer to int. That is p is pointing to 2 blocks of memory where both first and second block contain pointer to int (because of p[0] = a ).
So *p is int* .

The fact that p[0] contains the address of a[0] has no bearing on this
discussion. The sizeof *p will be the same as sizeof int* even if
p[0] contained the address of a[2], b[3], c[4], NULL, or was
indeterminate (never assigned a value).
Sizeof a[0] = 4

Type of a[0] is int. So sizeof(a[0]) is sizeof int


Now comes the complex part
c = *(*p + i ) * *(*(p +1 ) + i );

First part *(*p + i )

So p is pointer to array of 2 int*. In the expression (*p +i) p decayed to the pointer to the first element of the array p i.e &p[0]. So the type of p is evaluated to int**. So the type of *p is evaluated to int*. So *p + i is the i th int* starting from p. De-referencing that we get the value of ith element. So essentially *( *p +i) is the complex form of a

Second part

*(*(p +1 ) + i );
p is pointer to array of 2 int*. Now in expression (p +1) p decays to the pointer to the first element of array p . So p is evaluated to int **. p+1 point to the next int ** in array p , that is p[1]. So *(p +1 ) is resulting the int *. (*(p+1) +i ) point to the ith element of p[1]. De referencing that we get the value of p[1] i.e contain of array b.

so c = *(*p + i ) * *(*(p +1 ) + i );
is complex version of c= a * b;


It helps me visualize these types of expression to take advantage of
the identity
x[k] is defined to be equivalent to *(x+k)
and the special case
x[0] is the same as *x

So *(*p+i) is the same as (*p) and
(*p) is the same as p[0].

Similarly *(*(p+1)+i) is the same as p[1] and your conclusions
regarding a and b become (more) obvious.
 
T

Tim Rentsch

Kaz Kylheku said:
Please help me to verify my understanding about the output of the
following program.


int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf
}
return 0;


}

The output is
+++++++++

Size of int = 4

sizeof *p = 20
address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5
int is not getting converted to pointer to first element of arry 5
of int. That's the reason the output of 2nd printf is 5 *sizeof
int.

Now in case of third printf, type of *p is actually pointer to the
first element of arry of 5 int or in easier way type of

No, the type of *p is "array of 5 int", which is what you declared
it to be:

int (*p)[5]

and that is why the size of *p is 20; int is 4 bytes wide on your
platform and you have 5 of them.

After p = &a1, p does point to the same memory location as &a1[0],
but, in consideration of p's type, it points to the array as a
whole.

The expression *p has array type, and when evaluated, it produces
a value which is the same as &a[0]. However, that is just the
value produced under evaluation; it isn't the type of *p. [snip
elaboration]

This explanation is wrong. The type of an expression is
determined (in part) by its context, not whether the expression
is evaluated or not, and the type conversion occurs at compile
time, not at run time. In the expression

0 ? *p : 0

the subexpression '*p' has type (int*) even though it is never
evaluated. Conversions of this sort must occur at compile time,
and independent of any evaluation, so type checking and other
type conversions can occur -- for example, in the expression just
given, the second '0' must be converted to (int*). And that
conversion is important even if the expression as a whole is
not evaluated, eg,

sizeof (0 ? *p : 0)

must be the same as sizeof (int*).

The reason the type of '*p' in 'sizeof *p' is different from the
type of '*p' in '(0 ? *p : 0)' is the context in which the
expression '*p' appears, not whether it is evaluated.
 
T

Tim Rentsch

Barry Schwarz said:
On 2014-02-21, somenath wrote:

Please help me to verify my understanding about the output of
the following program.

int main(void)
{
int (*p)[5] ,i ;
int a1[] = { 1,2,3,4,5 };
p = &a1;
printf("\nSize of int = %d\n",(int)sizeof(int));
printf("\nsizeof *p = %d\n",(int) sizeof(*p)); //2nd printf

for ( i =0;i < 5; i++ ) {
printf("address of *p + %d = %x \n",i , (*p +i )); //3rd printf
}
return 0;
}

The output is

+++++++++

Size of int = 4
sizeof *p = 20

address of *p + 0 = 28ac44
address of *p + 1 = 28ac48
address of *p + 2 = 28ac4c
address of *p + 3 = 28ac50
address of *p + 4 = 28ac54

The type of *p is array 5 of int in sizeof operator, as arr of 5
int is not getting converted to pointer to first element of arry
5 of int . That's the reason the output of 2nd printf is 5
*sizeof int.

Now in case of third printf , type of *p is actually pointer to
the first element of arry of 5 int or in easier way type of

No, the type of *p is "array of 5 int", which is what you declared
it to be:

int (*p)[5]

and that is why the size of *p is 20; int is 4 bytes wide on your
platform and you have 5 of them.

After p = &a1, p does point to the same memory location as &a1[0],
but, in consideration of p's type, it points to the array as a
whole.

The expression *p has array type, and when evaluated, it produces
a value which is the same as &a[0]. However, that is just the
value produced under evaluation; it isn't the type of *p.

According to my understanding the the type of *p also changed from
array 5 of int to int* in this expression while evaluating the
expression. That's the reason *p+ 1 point to the next integer not
to next array 5 of int.

Your understanding is incorrect! The type of *p will never change.
It will forever be an array of 5 int. However, when the expression
*p is evaluated, the result of that evaluation will be converted per
the rule for evaluating expressions having array type.

This explanation likewise is wrong. The type of *p depends on
context, not on whether the expression is evaluated. See my
response to Kaz Kylheku upthread.
 
S

Stefan Ram

Tim Rentsch said:
The type of *p depends on context,

The type of *p is given by n1570 6.5.3.2p4:

»The unary * operator denotes indirection.« ... »If the
operand has type "pointer to type", the result has type
"type".«

No context is mentioned there.
 
Ad

Advertisements

T

Tim Rentsch

The type of *p is given by n1570 6.5.3.2p4:

The unary * operator denotes indirection. ... If the
operand has type "pointer to type", the result has type
"type".

No context is mentioned there.

Sure. And what other statements in the Standard might
have an effect on the type of '*p'? Hint: the answer
is not "the empty set".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

C pipe 1
What is the counterpart of this C pointer programme in C#? 2
strange warning 192
The behavior of the program. 2
pointer addresses 15
strange behaviour of realloc() 3
pointer array problem? 7
Queue in C 25

Top