predict the answer

S

sophia

Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

and the winning answer was :-

This question may have different answers depending on the compiler
used(16/32 bit) and the processor used

case 1:- a 32 bit compiler and a little endian machine

here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself


case 2:- a 32 bit compiler and a big endian machine

it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0

case 3:- a 16 bit compiler and a little endian machine


Here size of int will be 2 now a points to the first element in the
array i.e 10 now (char *)a + 2 points to 2 byte positions away from
the current position i.e it will point to lower byte position of 20
1.e( 00010100 00000000) so output will be 20 itself

case 4:- a 16 bit compiler and a big endian machine
it will point to byte position (00000000) of 20 i.e(00000000 00010100)
so output will be 0

how correct is the above answer ?
can any improvements be made in this answer ?
 
R

Richard Heathfield

sophia said:
Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

and the winning answer was :-

This question may have different answers depending on the compiler
used(16/32 bit) and the processor used

case 1:- a 32 bit compiler and a little endian machine

here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself


case 2:- a 32 bit compiler and a big endian machine

it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0

case 3:- a 16 bit compiler and a little endian machine


Here size of int will be 2 now a points to the first element in the
array i.e 10 now (char *)a + 2 points to 2 byte positions away from
the current position i.e it will point to lower byte position of 20
1.e( 00010100 00000000) so output will be 20 itself

case 4:- a 16 bit compiler and a big endian machine
it will point to byte position (00000000) of 20 i.e(00000000 00010100)
so output will be 0

how correct is the above answer ?
can any improvements be made in this answer ?

Here's the code again:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

int a[] = {10,20,30,40,50}; defines an array of int with five elements.
int *p; defines a pointer to int.
a yields &a[0], the address of the lowest-address byte in the a array,
which is guaranteed to be aligned correctly for int because it's an int
array.
(char *)a yields the same address, but with type char *.
Because arrays are guaranteed to be contiguous with no padding before or
after any array member, (char *)a + sizeof(int) yields the address of the
second int in the array, with type char *. Again, this is guaranteed to be
aligned correctly for int.
(int *) yields the same address as its operand, but with type int *.
p = assigns that address to p.
printf("%d", *p); will write "20" to the standard output device.
Guaranteed. (Well, printf can fail, and of course there's no newline, but
you know what I mean.)

It seems to me that the answer you saw is completely broken.
 
I

Ian Collins

sophia said:
Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

and the winning answer was :-

This question may have different answers depending on the compiler
used(16/32 bit) and the processor used

case 1:- a 32 bit compiler and a little endian machine

here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself


case 2:- a 32 bit compiler and a big endian machine

it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0
No, it will not. p points the the second int in the array, byte order
(or sizeof int ) has no effect.
how correct is the above answer ?

Incorrect.
 
V

Vladimir Oka

sophia said:
Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

and the winning answer was :-

0. Nothing, as you didn't emit a terminating \n in the printf
above (without it an implementation is not required to output
anything on the standard output). ;)

I haven't read the rest very carefully, but they seems sound,
and also off topic in this newsgroup, as they go beyond the
Standard C, and into the particulars of implementation. I'm sure
this will be pointed out by others, too.
 
V

Vladimir Oka

Vladimir said:
I haven't read the rest very carefully, but they seems sound, and also

Obviously so (I actually didn't go past the 1. and a bit of 2.).

Richard and Ian were of course correct.

Sophia, are you sure you copied the code correctly, as there are
ways to make it behave in a fashion similar to the given
answers? This is just not one of those.
 
R

Robbie Hatley

sophia said:
Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

and the winning answer was :-

This question may have different answers depending on the compiler
used(16/32 bit) and the processor used

case 1:- a 32 bit compiler and a little endian machine

here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself


case 2:- a 32 bit compiler and a big endian machine

it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0

case 3:- a 16 bit compiler and a little endian machine


Here size of int will be 2 now a points to the first element in the
array i.e 10 now (char *)a + 2 points to 2 byte positions away from
the current position i.e it will point to lower byte position of 20
1.e( 00010100 00000000) so output will be 20 itself

case 4:- a 16 bit compiler and a big endian machine
it will point to byte position (00000000) of 20 i.e(00000000 00010100)
so output will be 0

how correct is the above answer ?

Not correct at all. It will always print 20, because the
pointer always points at the 20, and it's always an int
pointer.
can any improvements be made in this answer ?

The answer is wrong for the code. But I think your code
could be made to produce that answer, yes. Like so:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int b = 0;

b = (int)(*((char*)a + sizeof(int)));
printf("%d\n", b);
return EXIT_SUCCESS;
}

Now I think *THAT* will produce just the answers you gave,
because the pointer is now a char pointer, not an int
pointer, so when you dereference it with the "*" I think
it gives the byte that it points to (the lowest-RAM-address
byte of the "20"), cast back to an int. So I think it will
print "20" for little-endian and "0" for big-endian,
regardless of sizeof(int).
 
S

sophia

sophia said:
Dear all,
The following is the question which i saw in a C column contest in a
magazine
what will be the output of
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));
printf("%d",*p);
return EXIT_SUCCESS;
}
and the winning answer was :-
This question may have different answers depending on the compiler
used(16/32 bit) and the processor used
case 1:- a 32 bit compiler and a little endian machine
here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself
case 2:- a 32 bit compiler and a big endian machine
it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0

No, it will not. p points the the second int in the array, byte order
(or sizeof int ) has no effect.
how correct is the above answer ?

Incorrect.

I have checked the answer on little endian machines using the
following
compilers gcc 4.03, Dev -C++ ,turbo C++ 3.0
and the answer seems to be correct

But I haven't checked the answer on a big endian machine

but as per the diagram given here:- http://www.df.lth.se/~pi/endian.html
the answer should be correct with the modification given
by Robbie Hatley (int)(*((char*)a + sizeof(int)));
 
R

Richard Heathfield

sophia said:

I have checked the answer on little endian machines using the
following
compilers gcc 4.03, Dev -C++ ,turbo C++ 3.0
and the answer seems to be correct

But I haven't checked the answer on a big endian machine

Question: What is the Universal Gravitational Constant?
Answer: If we're on Earth, it's 6.673E-11 mmm/kg/ss. On Mars, it's 42. On
Jupiter, it's 6.

I have checked the answer on Earth, and the answer seems to be correct.

But I haven't checked the answer on Mars or Jupiter.
 
S

sophia

sophia said:




Question: What is the Universal Gravitational Constant?
Answer: If we're on Earth, it's 6.673E-11 mmm/kg/ss. On Mars, it's 42. On
Jupiter, it's 6.

I have checked the answer on Earth, and the answer seems to be correct.

But I haven't checked the answer on Mars or Jupiter.

Thats really a great answer. you have a great humour sense.
Any way just to satisfy my curiosity

The value of Boltzmann constant is 1.380 6504(24) × 10-23 J/K
on Earth what will be its value on other inter dimensional worlds
if they exists OR at least in Mars ?
 
S

santosh

sophia said:
Thats really a great answer. you have a great humour sense.
Any way just to satisfy my curiosity

The value of Boltzmann constant is 1.380 6504(24) × 10-23 J/K
on Earth what will be its value on other inter dimensional worlds
if they exists OR at least in Mars ?

Did you understand what Richard wrote? The answer is the same as for G.
 
P

pete

sophia said:
Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;
}

and the winning answer was :-

This question may have different answers depending on the compiler
used(16/32 bit) and the processor used

case 1:- a 32 bit compiler and a little endian machine

here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself

case 2:- a 32 bit compiler and a big endian machine

it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0

case 3:- a 16 bit compiler and a little endian machine

Here size of int will be 2 now a points to the first element in the
array i.e 10 now (char *)a + 2 points to 2 byte positions away from
the current position i.e it will point to lower byte position of 20
1.e( 00010100 00000000) so output will be 20 itself

case 4:- a 16 bit compiler and a big endian machine
it will point to byte position (00000000) of 20 i.e(00000000 00010100)
so output will be 0

how correct is the above answer ?
can any improvements be made in this answer ?

(int*)((char*)a + sizeof(int)) == &a[1]

p equals the address of a[1].
That's all there is to it.
It's not an endian issue.
 
S

sophia

arrays are guaranteed to be contiguous with no padding before or
after any array member

Is it because all the elements are of the same type ?

now consider this

int a[] = {10,20,30,40,50};
float f = 3.14f;
void *p[]= {&a[1],&a[0],&a[2],&a[4],&f};

now my question is

In all cases all the elements of p will be stored contiguous with no
padding before or after any array member ?
 
S

santosh

sophia said:
arrays are guaranteed to be contiguous with no padding before or
after any array member

Is it because all the elements are of the same type ?

now consider this

int a[] = {10,20,30,40,50};
float f = 3.14f;
void *p[]= {&a[1],&a[0],&a[2],&a[4],&f};

now my question is

In all cases all the elements of p will be stored contiguous with no
padding before or after any array member ?

Yes, I believe so.
 
M

Mark Bluemel

sophia said:
On Mar 7, 12:29 pm, Richard Heathfield <[email protected]> wrote:
now consider this

int a[] = {10,20,30,40,50};
float f = 3.14f;
void *p[]= {&a[1],&a[0],&a[2],&a[4],&f};

now my question is

In all cases all the elements of p will be stored contiguous with no
padding before or after any array member ?

You've said p is an array of pointers to void. Why should you expect
them to be stored otherwise? How they are initialised is not important.
 
R

Richard Heathfield

sophia said:
arrays are guaranteed to be contiguous with no padding before or
after any array member

Is it because all the elements are of the same type ?

now consider this

int a[] = {10,20,30,40,50};
float f = 3.14f;
void *p[]= {&a[1],&a[0],&a[2],&a[4],&f};

now my question is

In all cases all the elements of p will be stored contiguous with no
padding before or after any array member ?

3.5.7 of C89: "All the expressions in an initializer for an object that has
static storage duration or in an initializer list for an object that has
aggregate or union type shall be constant expressions."

An array has aggregate type.

3.4: " More latitude is permitted for constant expressions in
initializers. Such a constant expression shall evaluate to one of the
following:

* an arithmetic constant expression,

* an address constant, or

* an address constant for an object type plus or minus an integral
constant expression.

[...] An address constant is a pointer to an lvalue designating an object
of static storage duration, or to a function designator".

So the initialisation of p[] is illegal (but does not violate a constraint,
so no diagnostic message is required, but the behaviour of the program is
undefined).

You could fix this by making a[] and f static.

Once you've done that, the answer is "yes" - p[] will be an array of five
void *, each of which occupies exactly sizeof(void *) bytes.
 
R

Richard Tobin

arrays are guaranteed to be contiguous with no padding before or
after any array member
[/QUOTE]
Is it because all the elements are of the same type ?

now consider this

int a[] = {10,20,30,40,50};
float f = 3.14f;
void *p[]= {&a[1],&a[0],&a[2],&a[4],&f};

The elements of p are still all the same type: they're all void *.
The fact that they're initialised from values of other types doesn't
change that.

-- RIchard
 
U

user923005

Dear all,

The following is the question which i saw in a C column contest in a
magazine

what will be the output of

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a[] = {10,20,30,40,50};
int *p;
p = (int*)((char*)a + sizeof(int));

printf("%d",*p);
return EXIT_SUCCESS;

}

and the winning answer was :-

This question may have different answers depending on the compiler
used(16/32 bit) and the processor used

case 1:- a 32 bit compiler and a little endian machine

here sizeof int will be 4. now a points to first element in the array
i.e 10 ( 00001010 00000000 00000000 00000000) and (char*)a points to
00001010.
now (char*)a + 4 means (char*)a + 4 * sizeof(char)
i.e (char*)a + 4 points to 4 byte positions away from the current
position i.e it will point to byte position (00010100) of 20(00010100
00000000 00000000 00000000 ) so output will be 20 itself

case 2:- a 32 bit compiler and a big endian machine

it will point to byte position (00000000) of 20(00000000 00010100
00000000 00000000) so output will be 0

case 3:- a 16 bit compiler and a little endian machine

Here size of int will be 2 now a points to the first element in the
array i.e 10 now (char *)a + 2 points to 2 byte positions away from
the current position i.e it will point to lower byte position of 20
1.e( 00010100 00000000) so output will be 20 itself

case 4:- a 16 bit compiler and a big endian machine
it will point to byte position (00000000) of 20 i.e(00000000 00010100)
so output will be 0

how correct is the above answer ?
can  any improvements be made in this answer ?

Out of curiosity, what magazine was that?
I want to write them a scathing letter.
 

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

Forum statistics

Threads
473,787
Messages
2,569,627
Members
45,328
Latest member
66Teonna9

Latest Threads

Top