Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #19882 > unrolled thread

The question regarding type of pointers

Started bysomenath <somenathpal@gmail.com>
First post2012-04-24 21:05 -0700
Last post2012-04-29 07:32 -0400
Articles 20 on this page of 21 — 7 participants

Back to article view | Back to comp.lang.c


Contents

  The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-24 21:05 -0700
    Re: The question regarding type of pointers Kaz Kylheku <kaz@kylheku.com> - 2012-04-25 04:51 +0000
    Re: The question regarding type of pointers "Heinrich Wolf" <invalid@invalid.invalid> - 2012-04-25 07:15 +0200
      Re: The question regarding type of pointers Philip Lantz <prl@canterey.us> - 2012-04-25 00:46 -0700
        Re: The question regarding type of pointers "Heinrich Wolf" <invalid@invalid.invalid> - 2012-04-25 09:52 +0200
    Re: The question regarding type of pointers Philip Lantz <prl@canterey.us> - 2012-04-25 01:09 -0700
    Re: The question regarding type of pointers Barry Schwarz <schwarzb@dqel.com> - 2012-04-25 11:22 -0700
      Re: The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-27 23:05 -0700
        Re: The question regarding type of pointers pete <pfiland@mindspring.com> - 2012-04-28 14:59 -0400
          Re: The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-28 20:27 -0700
            Re: The question regarding type of pointers James Kuyper <jameskuyper@verizon.net> - 2012-04-29 07:37 -0400
              Re: The question regarding type of pointers pete <pfiland@mindspring.com> - 2012-04-29 09:34 -0400
                Re: The question regarding type of pointers James Kuyper <jameskuyper@verizon.net> - 2012-04-29 11:54 -0400
            Re: The question regarding type of pointers pete <pfiland@mindspring.com> - 2012-04-29 09:24 -0400
              Re: The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-29 07:38 -0700
                Re: The question regarding type of pointers James Kuyper <jameskuyper@verizon.net> - 2012-04-29 12:01 -0400
                  Re: The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-29 09:29 -0700
      Re: The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-27 22:22 -0700
        Re: The question regarding type of pointers Barry Schwarz <schwarzb@dqel.com> - 2012-04-28 20:14 -0700
          Re: The question regarding type of pointers somenath <somenathpal@gmail.com> - 2012-04-28 22:17 -0700
            Re: The question regarding type of pointers James Kuyper <jameskuyper@verizon.net> - 2012-04-29 07:32 -0400

Page 1 of 2  [1] 2  Next page →


#19882 — The question regarding type of pointers

Fromsomenath <somenathpal@gmail.com>
Date2012-04-24 21:05 -0700
SubjectThe question regarding type of pointers
Message-ID<a5d5b150-de6c-4bdf-bc53-5dd21eddc81c@a8g2000pbe.googlegroups.com>
Hello All,

I am very confused about the output of the following program.

#include<stdio.h>
int  daytab[2][13] = {
							{0,31,28,31,30,31,30,31,31,30,31,30,31},
							{0,31,29,31,30,31,30,31,31,30,31,30,31},
						 };
int day_of_year(int year,int month,int day)
{
	int i;
	int leap;
	int (*p2)[13];
	int (*p3)[2][13];
	printf("\nsizeof daytab = %d\n", (int) sizeof(daytab));
	printf("\nsizeof  p3= %d\n", (int) sizeof(*p3));
	printf("\nsizeof  p3[2][3]= %d\n", (int) sizeof(p3[2][3]));
	printf("\nsizeof  p2= %d\n", (int) sizeof(*p2));

	if (month <1 || month >12 || day <1|| day >31)
	{
		return -1;
	}
	leap = year %4 && year %100 !=0 || year %400;
	p2 = &daytab[0];
	p3 = &daytab;
	printf("\nleap =%d\n",leap);
	for (i =1 ;i<month;i++){
		day += *(*(daytab+leap)+i);
		//day += *(*(p2+leap)+i);
		//day += *(*(*p3+leap)+i);

	}

}

int main(void)
{
	int day;
	day = day_of_year(2012,3,3);
	printf("\nDay = %d\n",day);
	return 0;
}

Output of the program
sizeof daytab = 104

sizeof  p3= 104

sizeof  p3[2][3]= 52

sizeof  p2= 52

leap =1

Day = 63

My question is how  the below line getting evaluated and resulting
correct output?
day += *(*(daytab+leap)+i);

According to my understanding daytab is pointing to the whole daytab[2]
[13]  array i.e it is equivalent to  p3. So daytab +1 will point
beyond  the daytab array so trying to de reference it will cause
undefined behaviour. But I am getting the right result. Where am I
going wrong?

Along with this I would like to verify my understanding  about the p2
and p3 as well.
So p2 point to the first row of the daytab array i.e it points to
{0,31,28,31,30,31,30,31,31,30,31,30,31},

Now p2+leap will point to second row depending upon the leap value.
*(p2+leap) is pointer to one of the element of the array for example
it may point to 0 of the first row. So adding i to it will shift the
pointer in that row to the i th element. Then de-reference it  result
in the actual value.

Similarly p3 will point to the whole array daytab. The type of *p3
will be equivalent to p2. So the pointer arithmetic on p3 behave same
as p2 . But I  am not sure that i am right here as I get the out put
of
printf("\nsizeof  p3= %d\n", (int) sizeof(*p3));

as same  as
printf("\nsizeof daytab = %d\n", (int) sizeof(daytab));

I am very much confused here.

Also i am not able to understand why the output of
 printf("\nsizeof  p3[2][3]= %d\n", (int) sizeof(p3[2][3])); is 52
which is same as

 printf("\nsizeof  p2= %d\n", (int) sizeof(*p2));

I am not able correctly visualize the type of different pointers that
may be the reason for the whole confusion. Please provide some inputs
regarding this so that I can clearly understand the the pointer type.

I have read the article from the following link.
http://www.torek.net/torek/c/pa.html
After reading it i thought I have understood the different type
associated with pointer. But I am not able to understand still. It is
very much evident as I have  failed to understand the behaviour of the
above program.


Thanks
Somenath

[toc] | [next] | [standalone]


#19883

FromKaz Kylheku <kaz@kylheku.com>
Date2012-04-25 04:51 +0000
Message-ID<20120424213222.491@kylheku.com>
In reply to#19882
On 2012-04-25, somenath <somenathpal@gmail.com> wrote:
> Hello All,
>
> I am very confused about the output of the following program.
>
> #include<stdio.h>
> int  daytab[2][13] = {
> 							{0,31,28,31,30,31,30,31,31,30,31,30,31},
> 							{0,31,29,31,30,31,30,31,31,30,31,30,31},

[ ... ]

> My question is how  the below line getting evaluated and resulting
> correct output?
> day += *(*(daytab+leap)+i);

This was written by an incompetent who had no regard for writing
clear, maintainable code.

The proper style for this expression, given how daytab operates as a
straightforward two-dimensional table, and how leap and i are straighforward
integer indices into the dimensions of that table, is this:

  day += daytab[leap][i];

There is absolutely no need to obfuscate this perfectly good expression
by replacing E[I] with *((E) + I) even once, let alone twice.

[toc] | [prev] | [next] | [standalone]


#19884

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2012-04-25 07:15 +0200
Message-ID<jn819c$e9u$1@news.m-online.net>
In reply to#19882
"somenath" <somenathpal@gmail.com> schrieb im Newsbeitrag 
news:a5d5b150-de6c-4bdf-bc53-5dd21eddc81c@a8g2000pbe.googlegroups.com...

...

> leap = year %4 && year %100 !=0 || year %400;

shouldn't that be
leap = year %4 && year %100 ==0 || year %400;
?

...

> My question is how  the below line getting evaluated and resulting
> correct output?
> day += *(*(daytab+leap)+i);
>
> According to my understanding daytab is pointing to the whole daytab[2]
> [13]  array i.e it is equivalent to  p3. So daytab +1 will point
> beyond  the daytab array so trying to de reference it will cause
> undefined behaviour. But I am getting the right result. Where am I
> going wrong?

I don't know

...

> I am not able correctly visualize the type of different pointers that
> may be the reason for the whole confusion. Please provide some inputs
> regarding this so that I can clearly understand the the pointer type.

I don't know

Heiner 

[toc] | [prev] | [next] | [standalone]


#19889

FromPhilip Lantz <prl@canterey.us>
Date2012-04-25 00:46 -0700
Message-ID<MPG.2a014ba97f6f27df98969c@news.eternal-september.org>
In reply to#19884
Heinrich Wolf wrote:
> "somenath" schrieb:
> 
> > leap = year %4 && year %100 !=0 || year %400;
> 
> shouldn't that be
> leap = year %4 && year %100 ==0 || year %400;
> ?

No. It should be
    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;

[toc] | [prev] | [next] | [standalone]


#19891

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2012-04-25 09:52 +0200
Message-ID<jn8ag7$35r$1@news.m-online.net>
In reply to#19889
"Philip Lantz" <prl@canterey.us> schrieb im Newsbeitrag 
news:MPG.2a014ba97f6f27df98969c@news.eternal-september.org...
> Heinrich Wolf wrote:
>> "somenath" schrieb:
>>
>> > leap = year %4 && year %100 !=0 || year %400;
>>
>> shouldn't that be
>> leap = year %4 && year %100 ==0 || year %400;
>> ?
>
> No. It should be
>    leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;

Yes you are right! 

[toc] | [prev] | [next] | [standalone]


#19893

FromPhilip Lantz <prl@canterey.us>
Date2012-04-25 01:09 -0700
Message-ID<MPG.2a0150e78d01546498969d@news.eternal-september.org>
In reply to#19882
somenath wrote:
> 
> Hello All,
> 
> I am very confused about the output of the following program.
> 
> #include<stdio.h>
> int  daytab[2][13] = {
> 							{0,31,28,31,30,31,30,31,31,30,31,30,31},
> 							{0,31,29,31,30,31,30,31,31,30,31,30,31},
> 						 };
> int day_of_year(int year,int month,int day)
> {
> 	int i;
> 	int leap;
> 	int (*p2)[13];
> 	int (*p3)[2][13];
> 	printf("\nsizeof daytab = %d\n", (int) sizeof(daytab));
> 	printf("\nsizeof  p3= %d\n", (int) sizeof(*p3));
> 	printf("\nsizeof  p3[2][3]= %d\n", (int) sizeof(p3[2][3]));
> 	printf("\nsizeof  p2= %d\n", (int) sizeof(*p2));
> 
> 	if (month <1 || month >12 || day <1|| day >31)
> 	{
> 		return -1;
> 	}
> 	leap = year %4 && year %100 !=0 || year %400;
> 	p2 = &daytab[0];
> 	p3 = &daytab;
> 	printf("\nleap =%d\n",leap);
> 	for (i =1 ;i<month;i++){
> 		day += *(*(daytab+leap)+i);
> 		//day += *(*(p2+leap)+i);
> 		//day += *(*(*p3+leap)+i);
> 
> 	}
> 
> }
> 
> int main(void)
> {
> 	int day;
> 	day = day_of_year(2012,3,3);
> 	printf("\nDay = %d\n",day);
> 	return 0;
> }
> 
> Output of the program
> sizeof daytab = 104
> 
> sizeof  p3= 104
> 
> sizeof  p3[2][3]= 52
> 
> sizeof  p2= 52
> 
> leap =1
> 
> Day = 63
> 
> My question is how  the below line getting evaluated and resulting
> correct output?
> day += *(*(daytab+leap)+i);
> 
> According to my understanding daytab is pointing to the whole daytab[2]
> [13]  array i.e it is equivalent to  p3. So daytab +1 will point
> beyond  the daytab array so trying to de reference it will cause
> undefined behaviour. But I am getting the right result. Where am I
> going wrong?

daytab is not the same as &daytab. p3 is the same as &daytab. daytab (in 
an expression where it gets converted to a pointer) is the same as 
&daytab[0], which is the same as p2.

As Kaz pointed out, that line of code is equivalent to
    day += daytab[leap][i];
and it should have been written that way.

> 
> Along with this I would like to verify my understanding  about the p2
> and p3 as well.
> So p2 point to the first row of the daytab array i.e it points to
> {0,31,28,31,30,31,30,31,31,30,31,30,31},
> 
> Now p2+leap will point to second row depending upon the leap value.
> *(p2+leap) is pointer to one of the element of the array for example
> it may point to 0 of the first row. So adding i to it will shift the
> pointer in that row to the i th element. Then de-reference it  result
> in the actual value.

Yes.

> Similarly p3 will point to the whole array daytab. The type of *p3
> will be equivalent to p2. So the pointer arithmetic on p3 behave same
> as p2 .

*p3 (in an expression where it gets converted to a pointer) is the same 
as p2. So pointer arithmetic on *p3 behaves the same as pointer 
arithmetic on p2. (Note carefully how my statement differs from yours 
above.)

The following expressions are equivalent:
    daytab[leap][i]
    (*p3)[leap][i]
    p2[leap][i]


> But I  am not sure that i am right here as I get the out put
> of printf("\nsizeof  p3= %d\n", (int) sizeof(*p3));
> 
> as same  as
> printf("\nsizeof daytab = %d\n", (int) sizeof(daytab));
> 
> Also i am not able to understand why the output of
>  printf("\nsizeof  p3[2][3]= %d\n", (int) sizeof(p3[2][3])); is 52
> which is same as
> 
>  printf("\nsizeof  p2= %d\n", (int) sizeof(*p2));

The argument to sizeof is not one of those places where an array gets 
converted to a pointer, so sizeof *p3 is not the same as sizeof p2. 
However, sizeof **p3 is the same as sizeof *p2.

p3[2][3] would be undefined behavior if it were evaluated in this 
program, because both subscripts are out of range. However, that 
expression is still legal as an operand to sizeof, since the operand to 
sizeof isn't evaluated. sizeof p3[2][3] is the same as sizeof **p3, or 
sizeof (*p3)[0], which is the way I would write it if I ever had 
occasion to write such a thing.



[toc] | [prev] | [next] | [standalone]


#19909

FromBarry Schwarz <schwarzb@dqel.com>
Date2012-04-25 11:22 -0700
Message-ID<39cgp71somr8bjmg3rufk6ins863nhdcco@4ax.com>
In reply to#19882
On Tue, 24 Apr 2012 21:05:38 -0700 (PDT), somenath
<somenathpal@gmail.com> wrote:

>Hello All,
>
>I am very confused about the output of the following program.
>
>#include<stdio.h>
>int  daytab[2][13] = {
>							{0,31,28,31,30,31,30,31,31,30,31,30,31},
>							{0,31,29,31,30,31,30,31,31,30,31,30,31},
>						 };
>int day_of_year(int year,int month,int day)
>{
>	int i;
>	int leap;
>	int (*p2)[13];
>	int (*p3)[2][13];
>	printf("\nsizeof daytab = %d\n", (int) sizeof(daytab));
>	printf("\nsizeof  p3= %d\n", (int) sizeof(*p3));
>	printf("\nsizeof  p3[2][3]= %d\n", (int) sizeof(p3[2][3]));
>	printf("\nsizeof  p2= %d\n", (int) sizeof(*p2));
>
>	if (month <1 || month >12 || day <1|| day >31)
>	{
>		return -1;
>	}
>	leap = year %4 && year %100 !=0 || year %400;
>	p2 = &daytab[0];
>	p3 = &daytab;
>	printf("\nleap =%d\n",leap);
>	for (i =1 ;i<month;i++){
>		day += *(*(daytab+leap)+i);
>		//day += *(*(p2+leap)+i);
>		//day += *(*(*p3+leap)+i);
>
>	}
>
>}
>
>int main(void)
>{
>	int day;
>	day = day_of_year(2012,3,3);
>	printf("\nDay = %d\n",day);
>	return 0;
>}
>
>Output of the program
>sizeof daytab = 104
>
>sizeof  p3= 104

Obviously this is a lie since the call to printf did not print out the
size of p3 but the size of *p3.  p3 is a pointer and in all likelihood
its size is either 4 or 8.

>
>sizeof  p3[2][3]= 52
>
>sizeof  p2= 52

A lie for the same reason.

>
>leap =1
>
>Day = 63
>
>My question is how  the below line getting evaluated and resulting
>correct output?
>day += *(*(daytab+leap)+i);
>
>According to my understanding daytab is pointing to the whole daytab[2]
>[13]  array i.e it is equivalent to  p3. So daytab +1 will point
>beyond  the daytab array so trying to de reference it will cause
>undefined behaviour. But I am getting the right result. Where am I
>going wrong?

As an object, daytab is indeed the complete array you describe.  But
as an expression, daytab is converted to a pointer to the first
element of the array with type pointer to element type.  (There are
exceptions which don't apply here; see 6.3.2.1-3 if interested.)

So daytab in this statement is identical to &daytab[0].  Therefore,
daytab points to the first array of 13 int.  Since leap is 1,
daytab+leap points to the second array of 13 int.  The expression
*(daytab+leap) dereferences this pointer value and evaluates to the
object daytab[1].  

This object is also an array and is converted as described above.
Therefore, in this statement *(daytab+leap)  is identical to
&daytab[1][0] which is the address of the first int in the second
array.  Obviously *(daytab+leap)+i will point to the i-th int in this
array.  The expression *(*(daytab+leap)+i) dereferences this address
to produce the value of the i-th int.

As others have pointed out, the calculation for leap is incorrect and
if you changed the year to 2013 it would produce a value as if that
year were a leap year also.

>
>Along with this I would like to verify my understanding  about the p2
>and p3 as well.
>So p2 point to the first row of the daytab array i.e it points to
>{0,31,28,31,30,31,30,31,31,30,31,30,31},

p2 was never assigned a value so its value is indeterminate.  You
could say it doesn't point anywhere currently.  Since it is a pointer
to an array of 13 int, it could be made to point to the first "row"
(technically the first element) of daytab with either initialization
or assignment.  Either daytab or &daytab[0] would serve as a suitable
expression to accomplish this.

>
>Now p2+leap will point to second row depending upon the leap value.

p2+leap will point to the first or second row depending on whether
leap is 0 or 1, respectively.

>*(p2+leap) is pointer to one of the element of the array for example

*(p2+leap) is the actual array (either first or second depending on
leap).

>it may point to 0 of the first row. So adding i to it will shift the

As described above, the expression *(p2+leap) will be converted to a
pointer to the first element of the appropriate array determined by
leap.  It will point to either daytab[0][0] or daytab[1][0], both of
which happen to be 0.

>pointer in that row to the i th element. Then de-reference it  result

p2 doesn't change value.  The value of the expression will point to
the i-th element.

>in the actual value.

Yes.

>
>Similarly p3 will point to the whole array daytab. The type of *p3

Again, no value was assigned or initialized.  p3 could point to daytab
but the only valid expression for achieving this is &daytab.  Note the
difference between this and the possible expressions for p2 above.

>will be equivalent to p2. So the pointer arithmetic on p3 behave same

The type of *p3 is array of 2 array of 13 int.  The type of p2 is
pointer.  They are not equivalent.  (For example, the size of *p3 is
104 and the size of p2 is 4.)

>as p2 . But I  am not sure that i am right here as I get the out put

Pointer arithmetic on the two will NOT behave the same.  p3+1 points
104 bytes beyond p3 while p2+1 points only 52 bytes beyond p2.

>of
>printf("\nsizeof  p3= %d\n", (int) sizeof(*p3));
>
>as same  as
>printf("\nsizeof daytab = %d\n", (int) sizeof(daytab));

p3 is a pointer to an array of 2 array of 13 int.  Even though p3 has
not been assigned a value, the TYPE of *p3 is array of 2 array of 13
int.  That is all the sizeof operator cares about.  It does not
evaluate its operand.  The operator is applied to the type of the
operand.  daytab is an actual array of the same type and therefore has
the same size.

>
>I am very much confused here.
>
>Also i am not able to understand why the output of
> printf("\nsizeof  p3[2][3]= %d\n", (int) sizeof(p3[2][3])); is 52
>which is same as

p3 is pointer to an array of 2 array of 13 int.  Even though it
doesn't point to one, p3[0] is the "virtual object" it points to.
p3[1] would be the next object of this type in memory and p3[2] would
be the third such object.  So p3[2] is an array of 2 array of 13 int.
Again, p3[2][0] is the first such array of 13 int it points to.
p3[2][1] would be the second, p3[2][2] the third, and  p3[2][3] the
fourth.  Therefore, p3[3][3] is an array of 13 int.  Hence a total
size of 52.

>
> printf("\nsizeof  p2= %d\n", (int) sizeof(*p2));

p2 is a pointer to an array of 13 int.  *p2 is the array it points to
(even if it doesn't really exist).  Hence the same size.

>
>I am not able correctly visualize the type of different pointers that
>may be the reason for the whole confusion. Please provide some inputs
>regarding this so that I can clearly understand the the pointer type.
>
>I have read the article from the following link.
>http://www.torek.net/torek/c/pa.html
>After reading it i thought I have understood the different type
>associated with pointer. But I am not able to understand still. It is
>very much evident as I have  failed to understand the behaviour of the
>above program.

1 - Both the dereference operator (*) and the subscript operator ([]),
when applied to pointer, evaluate to a value that has the type of the
thing pointed to.

2 - Both operators, when applied to an array, evaluate to a value that
has the type of each of the array elements.

Thus, p3[0], which is by definition exactly the same as *p3, evaluates
to an array of 2 array of 13 int by 1 above.  Similarly, *p2 evaluates
to an array of 13 int.  And daytab[0] also evaluates to an array of 13
int by 2 above

Technically, sizeof does not evaluate its operand.  It deals only with
the type that expression would have if it were evaluated.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#20018

Fromsomenath <somenathpal@gmail.com>
Date2012-04-27 23:05 -0700
Message-ID<96bb54c9-5ea3-49ff-851b-56dfbb8eac54@qg3g2000pbc.googlegroups.com>
In reply to#19909
Many thanks for replying and providing valuable inputs.

After going through the different article I have summarized my
understanding as follows. Please provide comments. Also I would
request you to correct my understanding if it is wrong. Again many
thanks for the help.
============================================================================
So suppose we have array declaration as follows

int ar[3];

Question ==> then the question is what is ar and what is sizeof(ar)
will produce.

Before getting into the answer of this first we need to know the
following.
C does not have array value but  C has array objects.  Let us take an
example to elaborate this .The declaration int a[3] declares an
ordinary array containing 3 int. Logically this ‘ar’ should be having
value as 3 int but it does not have instead it has the address of the
first element of the array that is &ar[0]. So ar in value context will
have &ar[0].
So our first question is answered.

Next what is sizeof(ar) ?

We know that sizeof needs ar in object context ant ar is an object of
3 ints so sizeof( ar)  is 3*sizeof(int).
So our second question is answered.

Question =>  What is the sizeof(*ar)?

As said before sizeof need  *ar in object context. So value of *ar is
an ordinary int. so sizeof (*ar) will be sizeof(int)

Question => What will be the sizeof(ar+0)?

Ok. So what are we doing here? We are adding value of ar to 0. So what
is value of ar? It is the &ar[0].

That mean essentially we are adding 0 to a pointer to an int. The
resultant type will be also a pointer to int. So sizeof(ar+0) will be
equal to sizeof(int*) may be equal to sizeof(int) .

So now we should  not be surprised by the output of the following
program.
int a[3];
 printf("\nsizeof(a) =%d\n",sizeof(a));  //Prints 12
 printf("\nsizeof(a+0) =%d\n",sizeof(a+0)); //Print 4

Now let us focus on the two dimensional array.
==========================================================
Suppose we have the following declaration
 int  ar[3][3];

Question => what will be sizeof(ar)?

 We know that in this ar is in object context and ar is an object of
array 3 of 3 int .  So sizeof(ar) is sizeof(int) *3*3.

Question => what will be the sizeof (&ar)?

We know that & operator needs an object as its operand and it produces
the address of the object.
So type of &ar will be int(*)[3][3]. Hence the sizeof(&ar) is equal to
sizeof(int(*)[3][3])) may be equal to (sizeof(int))

Question=> What is sizeof( ar[3])?

So what is ar[3]? ar[3] contains the pointer  to first element of row
of int where the row size is 3. The type of ar[3] is  int(*)[3]. So
ar[0] contains the starting address of the first row ,ar[1] contains
the staring address of second row so on . Hence size of ar[3]. Is 3
*sizeof(Int (*)[3]) which may be 3 *sizeof(int*)

Question  => now the last question

What is the output of the following program?

   int ar[3][3];
   int (*p)[3][3] =&ar;
   printf("%d\n",sizeof(p[2][3]));
   printf("%d\n",sizeof(*((*p+2)+3)));


So we know in  p[2][3] is in value context. So what is the value of
p[2][3]?
P is a pointer to 3 array of 3 int. We can imagine a 3X3 matrix in RAM
and p is pointing to the beginning address of that block. So p[2]
also pointing to 3X3 block . So inside each block we have row of int
having row size as  3. So sizeof(p[2][3]) is equal to sizeof(int) *3.

So  *p+2 is same as p[2] and *((*p+2)+3) is same a p[2][3 . That’s the
reason both printf produce same output.

[toc] | [prev] | [next] | [standalone]


#20025

Frompete <pfiland@mindspring.com>
Date2012-04-28 14:59 -0400
Message-ID<4F9C3E13.41E3@mindspring.com>
In reply to#20018
somenath wrote:
 
> Now let us focus on the two dimensional array.
> ==========================================================
> Suppose we have the following declaration
>  int  ar[3][3];

> Question=> What is sizeof( ar[3])?
> 
> So what is ar[3]? ar[3] contains the pointer 

No, ar[3] doesn't contain any pointer.

ar[3] is an expression of type array of three int.


/* BEGIN new.c */

#include <stdio.h>

int 
main(void)
{
    char ar[3][7];

    printf("sizeof ar[3] is %u\n.", (unsigned)sizeof ar[3]);
    return 0;
}

/* END new.c */


-- 
pete

[toc] | [prev] | [next] | [standalone]


#20034

Fromsomenath <somenathpal@gmail.com>
Date2012-04-28 20:27 -0700
Message-ID<ce807310-bc61-4674-8657-05535111bacd@k7g2000pbo.googlegroups.com>
In reply to#20025
On Apr 28, 11:59 pm, pete <pfil...@mindspring.com> wrote:
> somenath wrote:
> > Now let us focus on the two dimensional array.
> > ==========================================================
> > Suppose we have the following declaration
> >  int  ar[3][3];
> > Question=> What is sizeof( ar[3])?
>
> > So what is ar[3]? ar[3] contains the pointer
>
> No, ar[3] doesn't contain any pointer.
>
> ar[3] is an expression of type array of three int.

I did not understand this. According to my understanding C does not
have array value instead Instead, the "value" of the array is a
pointer to the first element of that array.

So for if we have int ar[3];
ar will have address of ar[0]. Essentially it is pointer to the first
element of a row  of 3 int.
So now if we have int ar[3][3];

ar[0] will have the address of the first element of the the first row
of 3 int.
similarly ar[3] will have the address of the first  element of the
third row of 3 int.
So the type of ar[3] will be int(*)[3] in value context. Where I am
going wrong? Please correct my understanding.

>
> /* BEGIN new.c */
>
> #include <stdio.h>
>
> int
> main(void)
> {
>     char ar[3][7];
>
>     printf("sizeof ar[3] is %u\n.", (unsigned)sizeof ar[3]);
>     return 0;
>
> }

So sizeof operator needs ar[3] in object context. So ar[3] in the
above is in object context not in value context. Now ar[3] is an array
object of 7 char. So the printf will print the result as sizeof
(char ) *7 not sizeof(char (*)[7])

Now if we think about the value of ar[3] then it will be the address
of the first element of the the third row of size 7.  Please correct
me if I am wrong.

[toc] | [prev] | [next] | [standalone]


#20047

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-04-29 07:37 -0400
Message-ID<jnj952$krk$1@dont-email.me>
In reply to#20034
On 04/28/2012 11:27 PM, somenath wrote:
...
> I did not understand this. According to my understanding C does not
> have array value instead Instead, the "value" of the array is a
> pointer to the first element of that array.

C has expressions that refer to arrays. These expressions do not have a
value; the expression (NOT it's non-existent value) gets automatically
converted into a pointer to the first element of that array in many
contexts. However, an array expression does not itself have any value,
and in several important contexts no such conversion occurs.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20050

Frompete <pfiland@mindspring.com>
Date2012-04-29 09:34 -0400
Message-ID<4F9D4380.5FF5@mindspring.com>
In reply to#20047
James Kuyper wrote:
> 
> On 04/28/2012 11:27 PM, somenath wrote:
> ...
> > I did not understand this. According to my understanding C does not
> > have array value instead Instead, the "value" of the array is a
> > pointer to the first element of that array.
> 
> C has expressions that refer to arrays. These expressions do not have a
> value; the expression (NOT it's non-existent value) gets automatically
> converted into a pointer to the first element of that array in many
> contexts. However, an array expression does not itself have any value,
> and in several important contexts no such conversion occurs.

From this:
    n1570
    6.7.9 Initialization
    Semantics
    8 An initializer specifies the initial value stored in an object.
I would construe that the entire contents of an array,
is the value of an array.

The result of an implicit conversion 
of an expression of array type to a pointer,
does not depend on the value of the array,
but only depends on the address of the array.

C does not have an operator
which can assign the value of an array to another array
and C does not have an operator
which can compare the value of an array to another array.

-- 
pete

[toc] | [prev] | [next] | [standalone]


#20053

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-04-29 11:54 -0400
Message-ID<jnjo84$7kc$1@dont-email.me>
In reply to#20050
On 04/29/2012 09:34 AM, pete wrote:
> James Kuyper wrote:
...
>> C has expressions that refer to arrays. These expressions do not have a
>> value; the expression (NOT it's non-existent value) gets automatically
>> converted into a pointer to the first element of that array in many
>> contexts. However, an array expression does not itself have any value,
>> and in several important contexts no such conversion occurs.
> 
> From this:
>     n1570
>     6.7.9 Initialization
>     Semantics
>     8 An initializer specifies the initial value stored in an object.
> I would construe that the entire contents of an array,
> is the value of an array.

6.7.9p10 says: "-- if it is an aggregate, every member is initialized
(recursively) according to these rules,"
6.7.9p14 says: "Successive bytes of the string literal (including the
terminating null character if there is room or if the array is of
unknown size) initialize the elements of the array.". 6.7.9p15 say the
same for arrays of wchar_t, char16_t, and char32_t.

Therefore, I think it's more appropriate to consider 6.7.9p8 to be
referring what happens recursively to the elements of an array, rather
than implying that the array as a whole has a value.

However, your formulation: that a array has a value, but that C provides
no mechanism for reading or writing that value, only mechanisms for
reading or writing individual elements of the array, is a workable
alternative interpretation.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20049

Frompete <pfiland@mindspring.com>
Date2012-04-29 09:24 -0400
Message-ID<4F9D4101.128@mindspring.com>
In reply to#20034
somenath wrote:
> 
> On Apr 28, 11:59 pm, pete <pfil...@mindspring.com> wrote:
> > somenath wrote:
> > > Now let us focus on the two dimensional array.
> > > ==========================================================
> > > Suppose we have the following declaration
> > >  int  ar[3][3];
> > > Question=> What is sizeof( ar[3])?
> >
> > > So what is ar[3]? ar[3] contains the pointer
> >
> > No, ar[3] doesn't contain any pointer.
> >
> > ar[3] is an expression of type array of three int.
> 
> I did not understand this. According to my understanding C does not
> have array value instead Instead, the "value" of the array is a
> pointer to the first element of that array.
> 
> So for if we have int ar[3];
> ar will have address of ar[0]. Essentially it is pointer to the first
> element of a row  of 3 int.
> So now if we have int ar[3][3];
> 
> ar[0] will have the address of the first element of the the first row
> of 3 int.
> similarly ar[3] will have the address of the first  element of the
> third row of 3 int.
> So the type of ar[3] will be int(*)[3] in value context. Where I am
> going wrong? Please correct my understanding.
> 
> >
> > /* BEGIN new.c */
> >
> > #include <stdio.h>
> >
> > int
> > main(void)
> > {
> >     char ar[3][7];
> >
> >     printf("sizeof ar[3] is %u\n.", (unsigned)sizeof ar[3]);
> >     return 0;
> >
> > }
> 
> So sizeof operator needs ar[3] in object context. So ar[3] in the
> above is in object context not in value context. Now ar[3] is an array
> object of 7 char. So the printf will print the result as sizeof
> (char ) *7 not sizeof(char (*)[7])
> 
> Now if we think about the value of ar[3] then it will be the address
> of the first element of the the third row of size 7.  Please correct
> me if I am wrong.

There is no ar[3], so ar[3] has no value.

This declaration 
    {char ar[3][7];}
declares an array of 3 arrays of 7 char.
The 3 arrarys are ar[0], ar[1], and ar[2].
The size of each of those 3 arrays is 7 bytes.

It doesn't matter that there is no ar[3]
for the expression (sizeof ar[3]) 
because the operand of sizeof is not evaluated.
The type of the expression of the operand
is all that matters to the sizeof operator.

    printf("sizeof ar[3000] is %u\n.", (unsigned)sizeof ar[3000]);
would have outputed 
    "sizeof ar[3000] is 7"

Expressions of array type are converted to pointers
in all but 3 contexts:
1    operand of sizeof operator
2    operand of address operator
3    string literal initializer

When you have a declaration like
    char ar[3][7];
without any more context,
then I will describe the type of the expression (ar),
as an array type.
The type of the expression (ar + 0), is a pointer type.

You can consider the entire contents of an array
as the value of the array.
But, there is no operator in C which can assign
the value of an array to another array,
and there is no operator in C which can compare
the value of one array with another.


-- 
pete

[toc] | [prev] | [next] | [standalone]


#20052

Fromsomenath <somenathpal@gmail.com>
Date2012-04-29 07:38 -0700
Message-ID<14dcc15c-735f-4479-b7ba-4e607e64f570@t2g2000pbg.googlegroups.com>
In reply to#20049
On Apr 29, 6:24 pm, pete <pfil...@mindspring.com> wrote:
> somenath wrote:
>
> > On Apr 28, 11:59 pm, pete <pfil...@mindspring.com> wrote:
> > > somenath wrote:
> > > > Now let us focus on the two dimensional array.
> > > > ==========================================================
> > > > Suppose we have the following declaration
> > > >  int  ar[3][3];
> > > > Question=> What is sizeof( ar[3])?
>
> > > > So what is ar[3]? ar[3] contains the pointer
>
> > > No, ar[3] doesn't contain any pointer.
>
> > > ar[3] is an expression of type array of three int.
>
> > I did not understand this. According to my understanding C does not
> > have array value instead Instead, the "value" of the array is a
> > pointer to the first element of that array.
>
> > So for if we have int ar[3];
> > ar will have address of ar[0]. Essentially it is pointer to the first
> > element of a row  of 3 int.
> > So now if we have int ar[3][3];
>
> > ar[0] will have the address of the first element of the the first row
> > of 3 int.
> > similarly ar[3] will have the address of the first  element of the
> > third row of 3 int.
> > So the type of ar[3] will be int(*)[3] in value context. Where I am
> > going wrong? Please correct my understanding.
>
> > > /* BEGIN new.c */
>
> > > #include <stdio.h>
>
> > > int
> > > main(void)
> > > {
> > >     char ar[3][7];
>
> > >     printf("sizeof ar[3] is %u\n.", (unsigned)sizeof ar[3]);
> > >     return 0;
>
> > > }
>
> > So sizeof operator needs ar[3] in object context. So ar[3] in the
> > above is in object context not in value context. Now ar[3] is an array
> > object of 7 char. So the printf will print the result as sizeof
> > (char ) *7 not sizeof(char (*)[7])
>
> > Now if we think about the value of ar[3] then it will be the address
> > of the first element of the the third row of size 7.  Please correct
> > me if I am wrong.
>
> There is no ar[3], so ar[3] has no value.
>
> This declaration
>     {char ar[3][7];}
> declares an array of 3 arrays of 7 char.
> The 3 arrarys are ar[0], ar[1], and ar[2].
> The size of each of those 3 arrays is 7 bytes.
>
> It doesn't matter that there is no ar[3]
> for the expression (sizeof ar[3])
> because the operand of sizeof is not evaluated.
> The type of the expression of the operand
> is all that matters to the sizeof operator.
>
>     printf("sizeof ar[3000] is %u\n.", (unsigned)sizeof ar[3000]);
> would have outputed
>     "sizeof ar[3000] is 7"
>
> Expressions of array type are converted to pointers
> in all but 3 contexts:
> 1    operand of sizeof operator
> 2    operand of address operator
> 3    string literal initializer
>
> When you have a declaration like
>     char ar[3][7];
> without any more context,
> then I will describe the type of the expression (ar),
> as an array type.
> The type of the expression (ar + 0), is a pointer type.
>
> You can consider the entire contents of an array
> as the value of the array.
> But, there is no operator in C which can assign
> the value of an array to another array,
> and there is no operator in C which can compare
> the value of one array with another.
Many thanks for the above clarification. I  was getting confused by
the fact that if C does not have array value (refer
http://www.torek.net/torek/c/expr.html#therule) then how  in "int ar[3]
[3]" ar[3] is having entire row  (which is nothing but array of int)
as value. Now I understand I should think differently. C does have
array value but with the following rules
"there is no operator in C which can assign the value of an array to
another array, and there is no operator in C which can compare  the
value of one array with another."  I think this may be the reason for
Chris Torek's statement  "C does not have array values".

[toc] | [prev] | [next] | [standalone]


#20054

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-04-29 12:01 -0400
Message-ID<jnjol1$aao$1@dont-email.me>
In reply to#20052
On 04/29/2012 10:38 AM, somenath wrote:
> On Apr 29, 6:24�pm, pete <pfil...@mindspring.com> wrote:
...
>> This declaration
>> � � {char ar[3][7];}
>> declares an array of 3 arrays of 7 char.
>> The 3 arrarys are ar[0], ar[1], and ar[2].
>> The size of each of those 3 arrays is 7 bytes.
...
> ... "int ar[3]
> [3]" ar[3] is having entire row  (which is nothing but array of int)
> as value.

You've missed one point pete was trying to make. ar[0] is an array of 7
char (not int); ar[1] contains another 7 char; ar[2] contains another 7
char. However, ar[3] doesn't contain anything - there is no such object.
The expression ar[3] is legal, but only in contexts such as &ar[3],
which is equivalent to &*(ar+3), which is equivalent to ar+3, a pointer
one element past the end of the array.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#20056

Fromsomenath <somenathpal@gmail.com>
Date2012-04-29 09:29 -0700
Message-ID<321edb61-7a79-49dc-85b1-f1fd886a8b6b@sm5g2000pbc.googlegroups.com>
In reply to#20054
On Apr 29, 9:01 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> On 04/29/2012 10:38 AM, somenath wrote:
>
> > On Apr 29, 6:24 pm, pete <pfil...@mindspring.com> wrote:
> ...
> >> This declaration
> >> {char ar[3][7];}
> >> declares an array of 3 arrays of 7 char.
> >> The 3 arrarys are ar[0], ar[1], and ar[2].
> >> The size of each of those 3 arrays is 7 bytes.
> ...
> > ... "int ar[3]
> > [3]" ar[3] is having entire row  (which is nothing but array of int)
> > as value.
>
> You've missed one point pete was trying to make. ar[0] is an array of 7
> char (not int); ar[1] contains another 7 char; ar[2] contains another 7
> char. However, ar[3] doesn't contain anything - there is no such object.
> The expression ar[3] is legal, but only in contexts such as &ar[3],
> which is equivalent to &*(ar+3), which is equivalent to ar+3, a pointer
> one element past the end of the array.
Thanks for correction. Actually I was trying to say if we had
declaration as int ar[3][3] then what would have happen. But then also
I should have not written "value of ar[3]" instead should  have
written "value of ar[2]".
Thanks.

[toc] | [prev] | [next] | [standalone]


#20020

Fromsomenath <somenathpal@gmail.com>
Date2012-04-27 22:22 -0700
Message-ID<ab07614b-b89a-4753-a141-18d92b8f79d4@ot8g2000pbb.googlegroups.com>
In reply to#19909
Many thanks for replying and providing valuable inputs.

After going through the different article I have summarized my
understanding as follows. Please provide comments. Also I would
request you to correct my understanding if it is wrong. Again many
thanks for the help.
============================================================================
So suppose we have array declaration as follows

int ar[3];

Question ==> then the question is what is ar and what is sizeof(ar)
will produce.

Before getting into the answer of this first we need to know the
following.
C does not have array value but  C has array objects.  Let us take an
example to elaborate this .The declaration int a[3] declares an
ordinary array containing 3 int. Logically this ‘ar’ should be having
value as 3 int but it does not have instead it has the address of the
first element of the array that is &ar[0]. So ar in value context will
have &ar[0].
So our first question is answered.

Next what is sizeof(ar) ?

We know that sizeof needs ar in object context ant ar is an object of
3 ints so sizeof( ar)  is 3*sizeof(int).
So our second question is answered.

Question =>  What is the sizeof(*ar)?

As said before sizeof need  *ar in object context. So value of *ar is
an ordinary int. so sizeof (*ar) will be sizeof(int)

Question => What will be the sizeof(ar+0)?

Ok. So what are we doing here? We are adding value of ar to 0. So what
is value of ar? It is the &ar[0].

That mean essentially we are adding 0 to a pointer to an int. The
resultant type will be also a pointer to int. So sizeof(ar+0) will be
equal to sizeof(int*) may be equal to sizeof(int) .

So now we should  not be surprised by the output of the following
program.
int a[3];
 printf("\nsizeof(a) =%d\n",sizeof(a));  //Prints 12
 printf("\nsizeof(a+0) =%d\n",sizeof(a+0)); //Print 4

Now let us focus on the two dimensional array.
==========================================================
Suppose we have the following declaration
 int  ar[3][3];

Question => what will be sizeof(ar)?

 We know that in this ar is in object context and ar is an object of
array 3 of 3 int .  So sizeof(ar) is sizeof(int) *3*3.

Question => what will be the sizeof (&ar)?

We know that & operator needs an object as its operand and it produces
the address of the object.
So type of &ar will be int(*)[3][3]. Hence the sizeof(&ar) is equal to
sizeof(int(*)[3][3])) may be equal to (sizeof(int))

Question=> What is sizeof( ar[3])?

So what is ar[3]? ar[3] contains the pointer  to first element of row
of int where the row size is 3. The type of ar[3] is  int(*)[3]. So
ar[0] contains the starting address of the first row ,ar[1] contains
the staring address of second row so on . Hence size of ar[3]. Is 3
*sizeof(Int (*)[3]) which may be 3 *sizeof(int*)

Question  => now the last question

What is the output of the following program?

   int ar[3][3];
   int (*p)[3][3] =&ar;
   printf("%d\n",sizeof(p[2][3]));
   printf("%d\n",sizeof(*((*p+2)+3)));


So we know in  p[2][3] is in value context. So what is the value of
p[2][3]?
P is a pointer to 3 array of 3 int. We can imagine a 3X3 matrix in RAM
and p is pointing to the beginning address of that block. So p[2]
also pointing to 3X3 block . So inside each block we have row of int
having row size as  3. So sizeof(p[2][3]) is equal to sizeof(int) *3.

So  *p+2 is same as p[2] and *((*p+2)+3) is same a p[2][3 . That’s the
reason both printf produce same output.

[toc] | [prev] | [next] | [standalone]


#20032

FromBarry Schwarz <schwarzb@dqel.com>
Date2012-04-28 20:14 -0700
Message-ID<27pop7t31rd6vf9uan39jii9dvn9460ahr@4ax.com>
In reply to#20020
On Fri, 27 Apr 2012 22:22:34 -0700 (PDT), somenath
<somenathpal@gmail.com> wrote:

>Many thanks for replying and providing valuable inputs.
>
>After going through the different article I have summarized my
>understanding as follows. Please provide comments. Also I would
>request you to correct my understanding if it is wrong. Again many
>thanks for the help.
>============================================================================
>So suppose we have array declaration as follows
>
>int ar[3];
>
>Question ==> then the question is what is ar and what is sizeof(ar)
>will produce.
>
>Before getting into the answer of this first we need to know the
>following.
>C does not have array value but  C has array objects.  Let us take an
>example to elaborate this .The declaration int a[3] declares an
>ordinary array containing 3 int. Logically this ‘ar’ should be having
>value as 3 int but it does not have instead it has the address of the
>first element of the array that is &ar[0]. So ar in value context will
>have &ar[0].
>So our first question is answered.
>
>Next what is sizeof(ar) ?
>
>We know that sizeof needs ar in object context ant ar is an object of
>3 ints so sizeof( ar)  is 3*sizeof(int).
>So our second question is answered.
>
>Question =>  What is the sizeof(*ar)?
>
>As said before sizeof need  *ar in object context. So value of *ar is
>an ordinary int. so sizeof (*ar) will be sizeof(int)
>
>Question => What will be the sizeof(ar+0)?
>
>Ok. So what are we doing here? We are adding value of ar to 0. So what
>is value of ar? It is the &ar[0].
>
>That mean essentially we are adding 0 to a pointer to an int. The
>resultant type will be also a pointer to int. So sizeof(ar+0) will be
>equal to sizeof(int*) may be equal to sizeof(int) .

It may also be equal to sizeof(float) or sizeof(long) or even
sizeof(char).  Don't introduce extraneous irrelevant possibilities
which will only serve to reinforce someone's misconceptions.

>
>So now we should  not be surprised by the output of the following
>program.
>int a[3];
> printf("\nsizeof(a) =%d\n",sizeof(a));  //Prints 12
> printf("\nsizeof(a+0) =%d\n",sizeof(a+0)); //Print 4

Unless size_t is a typedef for int, the output from the above is
undefined (and therefore free of surprises).  If you system does not
support %z then cast the sizeof expression to match the format
conversion (in this case %d requires an int).

>
>Now let us focus on the two dimensional array.
>==========================================================
>Suppose we have the following declaration
> int  ar[3][3];
>
>Question => what will be sizeof(ar)?
>
> We know that in this ar is in object context and ar is an object of
>array 3 of 3 int .  So sizeof(ar) is sizeof(int) *3*3.
>
>Question => what will be the sizeof (&ar)?
>
>We know that & operator needs an object as its operand and it produces
>the address of the object.
>So type of &ar will be int(*)[3][3]. Hence the sizeof(&ar) is equal to
>sizeof(int(*)[3][3])) may be equal to (sizeof(int))

And when you update your compiler to the next release it may not be
equal to sizeof(int) so again why and who cares?

>
>Question=> What is sizeof( ar[3])?
>
>So what is ar[3]? ar[3] contains the pointer  to first element of row
>of int where the row size is 3. The type of ar[3] is  int(*)[3]. So

ar[3] does not exist.  The only elements of ar are ar[0], ar[1], and
ar[2].  No ar[i] contains any pointer value at all.  Each ar[i] is an
array of 3 int.  Period.  No pointers whatsoever.

The type of any ar[i] is int[3], NOT int(*)[3].  With a few
exceptions, the expression ar[i] is converted to &ar[i][0].  BUT one
of those exceptions is when it is the operand of the sizeof operator.

>ar[0] contains the starting address of the first row ,ar[1] contains
>the staring address of second row so on . Hence size of ar[3]. Is 3

ar[i] does not contain any addresses at all.

>*sizeof(Int (*)[3]) which may be 3 *sizeof(int*)

If it existed, ar[3] would be an array of 3 int.  Since sizeof does
not evaluate its operand but deals only with the type the operand
would have if it existed, the fact that ar[3] does not exist is not an
issue.  sizeof(ar[3]) is exactly 3*sizeof(int).

>
>Question  => now the last question
>
>What is the output of the following program?
>
>   int ar[3][3];
>   int (*p)[3][3] =&ar;
>   printf("%d\n",sizeof(p[2][3]));

Of course p[2][3] does not exist either but sizeof doesn't care.  p is
a pointer to an int[3][3].  p[i] is therefore one such int[3][3].
p[i][j] is therefore one of the int[3] in that int[3][3].  Therefore
sizeof(p[2][3]) is always 3*sizeof(int).

>   printf("%d\n",sizeof(*((*p+2)+3)));

p is a pointer to an int[3][3].  *p is the int[3][3] it points to.
Since the expression *p+2 is not one of the exceptions, *p is
converted to the address of the first int[3] in that int[3][3].  *p+2
is computed as the address of the third int[3] in that int[3][3].
((*p+2)+3) is the same as (*p+2+3) or (*p+5) and is simply the address
of a non-existent sixth int[3] in that int[3][3].  *((*p+2)+3)) is
this sixth int[3] itself and it's size is always 3*sizeof(int).

I expect you meant sizeof(*(*(p+2)+3)).  Since *(*(p+2)+3) is by
definition the same as p[2][3], this has been discussed in the comment
to the preceding printf.

>
>
>So we know in  p[2][3] is in value context. So what is the value of
>p[2][3]?

p[2][3] doesn't exist so it has no value.

>P is a pointer to 3 array of 3 int. We can imagine a 3X3 matrix in RAM
>and p is pointing to the beginning address of that block. So p[2]
>also pointing to 3X3 block . So inside each block we have row of int
>having row size as  3. So sizeof(p[2][3]) is equal to sizeof(int) *3.
>
>So  *p+2 is same as p[2] and *((*p+2)+3) is same a p[2][3 . That’s the

No for reasons described above.

>reason both printf produce same output.

p[2][3] dereferences p twice.  *((*p+2)+3) dereferences p twice.
*(*(p+2)+3) dereferences p twice.  All three expression have the same
type.  That is why the sizeof all three expressions is the same. Since
the object described by the expressions does not exist, it is obvious
that sizeof deals only with types and not values.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#20036

Fromsomenath <somenathpal@gmail.com>
Date2012-04-28 22:17 -0700
Message-ID<8126dc5c-ba8a-4c52-8b0d-0a3117413cea@h10g2000pbi.googlegroups.com>
In reply to#20032
> >Now let us focus on the two dimensional array.
> >==========================================================
> >Suppose we have the following declaration
> > int  ar[3][3];
>

>
> >Question=> What is sizeof( ar[3])?
>
> >So what is ar[3]? ar[3] contains the pointer  to first element of row
> >of int where the row size is 3. The type of ar[3] is  int(*)[3]. So
>
> ar[3] does not exist.  The only elements of ar are ar[0], ar[1], and
> ar[2].  No ar[i] contains any pointer value at all.  Each ar[i] is an
> array of 3 int.  Period.  No pointers whatsoever.
>
I am not able to correlate between the statements which say "C does
not have array values.Instead, the ‘value’ of the array is a pointer
to the first element of that array." with the fact " No ar[i] contains
any pointer value at all.  Each ar[i] is an  array of 3 int.  Period.
No pointers whatsoever."

Where I am going wrong? As I have mentioned earlier my understanding
is ar[i] will have the address of the first element of  the ith row.
Is this not correct? I am very confused. Please help me to understand
it correctly.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web