Array address arithmetic

V

vjay

Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.
 
T

Tomás Ó hÉilidhe

@localhost.talkaboutprogramming.com:
Check the code below guys
void main()



int main(void)


{
char a[5] = {1,2,3,4,5};



Unusual to store numbers in a char, but how and ever.

char *ptr;
ptr = (char*)(&a + 1);


Here you take the address of the array "a", and add one to it. This will
give you the address of the first byte after the fifth element in the
array "a".

printf("%d",*(ptr-1));


"ptr-1" leaves you with the address of the fifth element in "a".

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression
ptr = (char*)(a + 1); i get output as 1.what is the difference between
(&a + 1) and (a + 1) in the above mentioned expression.Help guys its
confusing.



Pointer arithmetic depends on the size of the "pointed to" type. The
size of the "pointed to" type in &a is "sizeof(char[5])".
 
J

James Fang

Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));

}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

try the following:
int main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)((char*)&a + 1);
printf("%d",*(ptr-1));
getchar();
}
 
A

Anthony Fremont

vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);

Don't you mean this:
ptr = (char *)(&a[0] + 1);

Didn't you get some kind of warning? What compiler are you using?
 
N

Noé Falzon

vjay a écrit :
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

I would say it is because &a is a pointer to an array of 5 chars, and
thus (&a + 1) add the size of one array of 5 chars. It brings you one
char after the 5.
Then ptr being a pointer to a char, doing (ptr-1) brings you one char
back, right on the 5.

I think you meant (a+1). This way, it would have worked. The name of the
array is a pointer to its first element. So "a" is really a pointer to a
char, and (a+1) points to the second element of your array.

It's all due to the difference between a pointer to a char ("a"), and a
pointer to an array of chars ("&a").

Hope i'm not mistaken,
Noé
 
J

James Kuyper

vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

When you add an integer n to a pointer to a given type, the result is a
new pointer pointing that n elements of that type farther down. The
expression &a has the type char(*)[5], which means it points at an
entire array of 5 chars. Therefore, when you add 1 to it, it points at
the next array of 5 characters. Converting it to char* result in a
pointer that would point at the first char of that next array. When you
subtract 1, the behavior is undefined; however, on most real-world
implementations, the actual behavior is to point at the last char of the
previous array, which contained a 5.

In the expression (a+1), the name of the array decays into a pointer to
the first element of the array, and therefore has the type char*. When
you add 1 to that pointer, it points at the next char. When you subtract
1, it goes back to pointing at the first char, as you expected.
 
J

James Kuyper

Anthony said:
vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);

Don't you mean this:
ptr = (char *)(&a[0] + 1);

Didn't you get some kind of warning? What compiler are you using?

On what basis? If you were writing the text of the warning message, what
would it say? As far as I can see, the only thing wrong with this code
is vjay's incorrect understanding of what it does.
 
A

Anthony Fremont

James said:
Anthony said:
vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);

Don't you mean this:
ptr = (char *)(&a[0] + 1);

Didn't you get some kind of warning? What compiler are you using?

On what basis? If you were writing the text of the warning message,
what would it say? As far as I can see, the only thing wrong with
this code is vjay's incorrect understanding of what it does.

Thanks, I get it now, I guess I just never had a need to try such a thing
before.
 
P

pete

vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.
what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

ptr == a + 5
(char*)(&a + 1) == a + 5
&a + 1 == (char(*)[5])(a + 5)




/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
char a[5] = {1,2,3,4,5};
char *ptr = (char*)(&a + 1);

if ( ptr == a + 5) {
puts("ptr == a + 5");
}
if ( (char*)(&a + 1) == a + 5) {
puts("(char*)(&a + 1) == a + 5");
}
if ( &a + 1 == (char(*)[5])(a + 5)) {
puts("&a + 1 == (char(*)[5])(a + 5)");
}
return 0;
}

/* END new.c */
 
J

Joe Wright

vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

You've been hanging out here for a while now haven't you? Why do you not
grasp what everybody is telling you? What you have posted is not
compilable and also incorrect. Watch ..

#include <stdio.h>

int main(void)
{
char a[5] = {1, 2, 3, 4, 5};
char *ptr;
ptr = (char *) (&a + 1);
printf("%d", *(ptr - 1));
return 0;
}

Now it's compilable and correct.
Expressing &a gives an address of type 'array 5 of char'. (&a + 1) gives
the address of the 'next' array 5 of char. You cast this address to
char* and store it in ptr. This effectively points one past the end of
array a. ptr - 1 points to the end of a and *(ptr - 1) is a[4] with value 5.
 
B

Bart C

vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

Thanks, your post and it's replies has clarified something that I hadn't
fully grasped; in int a[5], then:

&a is not the same thing as a, when considering Type.

Apparently a is the same as &a[0] (pointer to int), &a means a pointer to
the entire array (pointer to array of 5 ints). The values however are the
same. (Although why &a doesn't decompose to &(&a[0]) is another mystery;
maybe it only decomposes when there isn't an & in front)
void main()

With quotes, this gives 5 times as many Google hits as "int main(void)".
Looks like a lot of people can't get it right.

Bart
 
P

pete

Bart said:
vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

Thanks, your post and it's replies
has clarified something that I hadn't
fully grasped; in int a[5], then:

&a is not the same thing as a, when considering Type.

Apparently a is the same as &a[0] (pointer to int),
&a means a pointer to
the entire array (pointer to array of 5 ints).
The values however are the same.
(Although why &a doesn't decompose to &(&a[0]) is another mystery;
maybe it only decomposes when there isn't an & in front)

That's very close to being correct.

N869
6.3.2 Other operands
6.3.2.1 Lvalues and function designators

[#3] Except when it is the operand of the sizeof operator or
the unary & operator, or is a string literal used to
initialize an array, an expression that has type ``array of
type'' is converted to an expression with type ``pointer to
type'' that points to the initial element of the array
object and is not an lvalue.
 
K

Kenneth Brody

vjay said:
Check the code below guys
void main()
{
char a[5] = {1,2,3,4,5};
char *ptr;
ptr = (char*)(&a + 1);
printf("%d",*(ptr-1));
}

The output of the program is 5

But what i expected was 1.When i replace &a with a in the expression ptr =
(char*)(a + 1); i get output as 1.what is the difference between (&a + 1)
and (a + 1) in the above mentioned expression.Help guys its confusing.

Consider:

What does it mean when you say "&something + 1"?

What is the value of "sizeof a"?

If there were a "typeof" operator, what would be "typeof a"?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

Bart C said:
Apparently a is the same as &a[0] (pointer to int), &a means a pointer to
the entire array (pointer to array of 5 ints). The values however are the
same. (Although why &a doesn't decompose to &(&a[0]) is another mystery;
maybe it only decomposes when there isn't an & in front)
[...]

The answers to these and a number of similar questions can be found in
section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>.
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top