Let me explain to you in more details how this works.
Do not cast a byte value into a pointer.
// The memory layout we will be examining.
int x = 0x12345678;
// Convert address to a char* pointer so we can examine byte-by-byte
char* p = reinterpret_cast<char*>(&x);
// p dereferences the pointer and fetches the byte at the current position that the char pointer points to.
// Similarly, p[n] fetches the nth byte from the position of the pointer p.
// Since it is a char* pointer, when dereferencing the pointer, we get a char.
// Naturally, since char is a character, std::cout will print out the character it represents.
// To avoid this, we cast it to int to make sure it prints out the actual byte.
// Coupled with std::hex prints out the hex presentation of the number.
// This is only necessary when printing.
std::cout << std::hex << "0x" << (int)p << "\n0x" << (int)p << "\n0x" << (int)p << "\n0x" << (int)p << std::endl;
// This is the same as above. We dereference the pointer and checks its value.
// Note that we do not need to cast it here. A char contains an integer like anything else, but
// std::cout will interpret it as a character, so that is the reason we must cast in order to avoid that.
if (p == 0x78 && p == 0x56 && p == 0x34 && p == 0x12)
std::cout << "Congratulations! Your machine is little endian!\n";
else if (p == 0x12 && p == 0x34 && p == 0x56 && p == 0x78)
std::cout << "Congratulations! Your machine is big endian!\n";
std::cout << "Weird. Your machine is neither little endian nor big endian.\n";