i have tried this
char c[4];
int i=89;
memcpy(&c[0],&i,4);
cout<<(int)c[0]<<endl;
cout<<(int)c[1]<<endl;
cout<<(int)c[2]<<endl;
cout<<(int)c[3]<<endl;
the output is like:
89
0
0
0
which pretty trains my stomache cuz i thought the number would be saved in memory like 0x00000059 so how come c[0] is 89 ? i thought it is supposed to be in c[3]...
Because the processor you are running on is little-endian. The byte order, of a multi-byte fundamental type, is swapped. On a big-endian machine it would be as you expect.
This is because you're running the program on a little endian cpu. See also endianness here and there.
Endian-ness is obviously the answer as Goz has pointed out.
But for those who are unclear of what that means, it's also important to understand that the order of bytes displayed in the example is the same as the order in the original int. Memcpy doesn't change the byte order, regardless of the edian type of the platform.
Byte order arises when we address smaller units like bytes. It's an essentially arbitrary decision the CPU designer gets to make: big-endian or little-endian.
It's useful to simplify the situation and realize that it is mainly the connection to peripherals that is byte ordered. Yes, it can be discovered via byte addressing as you have proved, but in general scalar values are loaded and stored as units, into registers, and in this case byte order doesn't change anything. The most significant bits are on "the left", at least, the way we usually write numbers. And that's why the <<
and >>
operators always produce the exact same results on big-endian vs little-endian machines when used according to the language standards.
But in order to read and write data streams to peripheral devices, you are forced to choose a byte order. This is because peripherals are fundamentally byte stream devices. Does the lowest address have the most significant bits or the least? It's done both ways and the camps used to be rather evenly divided.
Because memory itself is byte addressed, it's certainly possible to derive different behavior without a peripheral, but this typically doesn't happen without a deliberate peek inside like you did.
Imagine a CPU that has no bytes, only 32-bit words, addressed as 0, 1, 2. The C compiler makes char, int, and long all 32-bit objects. (This is allowed by Cx9.) Wow, no byte order issues! It's both! But .. what happens when we hook up our first peripheral??
1.Well, x86 has registers that alias smaller registers, but that's another story.
Different machines can have different byte ordering, but take a look at this code and think about what happens, depending on how the bytes are laied out:
long x = 89;
short *p = (short*)&x;
short y = *p;
If you want your application to be portable or developed within a team, you probably don't want to follow this logic as it would cause hard to catch bugs and prolong development.
User contributions licensed under CC BY-SA 3.0