Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Treating a character array as an integer - Learn C the Hard Way Extra credit

Tags:

arrays

c

pointers

In Zed Shaw's "Learn C the Hard Way", exercise 9 (http://c.learncodethehardway.org/book/ex9.html) there is an extra credit question that I find interesting. He defines a 4-character array and asks the reader to figure out how to use the array as a 4-byte integer.

At this point I know just enough to be dangerous, and I was thinking the answer is something along these lines:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char name[4] = {'A'};

    int *name_int;
    name_int = &name;
    printf("%d", *name_int);

    return 0;
}

My thoughts being that if I created an int pointer with a value being the address of the array that the int type would use the byte of data in that address, followed by the next 3 bytes of data available. In my limited understanding, I am under the impression that both an int and an array would use memory in the same way: starting at an arbitrary memory address than using the next address in sequence, and so on.

However, the output of this isn't what I expected: I get the ascii value of 'A'. Which to me seems to indicate that my solution is incorrect, my understanding how memory is handled is incorrect, or both.

How can this little hack be accomplished and where is it I am going wrong? I am hoping to walk away from this with a better understanding of how pointers and references work, and how memory is stored and used.

Thank you!

like image 385
upgrayedd Avatar asked Apr 11 '14 00:04

upgrayedd


1 Answers

You are running into little-endian vs big-endian representation of numbers.

Let's take a look at the values of 4-btyes used to represent a 4-byte integer.

+----+----+----+----+
| N1 | N2 | N3 | N4 |
+----+----+----+----+

In a big-endian representation, these 4 bytes represent:

N1*2^24 + N2*2^16 + N3*2^8 + N4

In a little-endian representation, those 4 bytes represent:

N1 + N2*2^8 + N3*2^16 + N4*2^24

In your case.

N1 = 'A' (65 decimal)
N2 = 0
N3 = 0
N4 = 0

Since the value of integer you are getting is 65, you have a little endian representation. If you want to treat those numbers like a big-endian representation, you can use the following:

#include <stdio.h>

int main(int argc, char *argv[])
{
   int i;
   char nameString[4] = {'A'};
   int name = 0;

   for ( i = 0; i < 4; ++i )
   {
      name = (name << 8) + nameString[i];
   }

   printf("%d\n", name);
   printf("%X\n", name);

   return 0;
}

The output I get with the above code:

1090519040
41000000
like image 185
R Sahu Avatar answered Sep 28 '22 02:09

R Sahu