What will be the output of the following C code. Assuming it runs on Little endian machine, where short int takes 2 Bytes and char takes 1 Byte.
#include<stdio.h>
int main() {
short int c[5];
int i = 0;
for(i = 0; i < 5; i++)
c[i] = 400 + i;
char *b = (char *)c;
printf("%d", *(b+8));
return 0;
}
In my machine it gave
-108
I don't know if my machine is Little endian or big endian. I found somewhere that it should give
148
as the output. Because low order 8 bits of 404(ie element c[4]) is 148. But I think that due to "%d", it should read 2 Bytes from memory starting from the address of c[4].
The code gives different outputs on different computers because on some platforms the char
type is signed by default and on others it's unsigned by default. That has nothing to do with endianness. Try this:
char *b = (char *)c;
printf("%d\n", (unsigned char)*(b+8)); // always prints 148
printf("%d\n", (signed char)*(b+8)); // always prints -108 (=-256 +148)
The default value is dependent on the platform and compiler settings. You can control the default behavior with GCC options -fsigned-char
and -funsigned-char
.
To see what sizes types have in your system:
printf("char = %u\n", sizeof(char));
printf("short = %u\n", sizeof(short));
printf("int = %u\n", sizeof(int));
printf("long = %u\n", sizeof(long));
printf("long long = %u\n", sizeof(long long));
Change the lines in your program
unsigned char *b = (unsigned char *)c;
printf("%d\n", *(b + 8));
And simple test (I know that it is not guaranteed but all C compilers I know do it this way and I do not care about old CDC or UNISYS machines which had different addresses and pointers to different types of data
printf(" endianes test: %s\n", (*b + (unsigned)*(b + 1) * 0x100) == 400? "little" : "big");
Another remark: it is only because in your program c[0] == 400
c[4]
stores 404
. In a two-byte little-endian representation, that means two bytes of 0x94
0x01
, or (in decimal) 148
1
.
b+8
addresses the memory of c[4]
. b
is a pointer to char
, so the 8
means adding 8 bytes (which is 4 two-byte shorts). In other words, b+8
points to the first byte of c[4]
, which contains 148
.
*(b+8)
(which could also be written as b[8]
) dereferences the pointer and thus gives you the value 148
as a char
. What this does is implementation-defined: On many common platforms char
is a signed type (with a range of -128
.. 127
), so it can't actually be 148
. But if it is an unsigned type (with a range of 0
.. 255
), then 148
is fine.
The bit pattern for 148
in binary is 10010100
. Interpreting this as a two's complement number gives you -108
.
This char
value (of either 148
or -108
) is then automatically converted to int
because it appears in the argument list of a variable-argument function ( printf
). This doesn't change the value.
Finally, "%d"
tells printf
to take the int
argument and format it as a decimal number.
So, to recap: Assuming you have a machine where
short int
is 2 bytes ... then this program will output either -108
(if char
is a signed type) or 148
(if char
is an unsigned type).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.