drdot
drdot

Reputation: 3347

Confusion on printing strings as integers in C

I would like to know how the string is represented in integer, so I wrote the following program.

#include <stdio.h>

int main(int argc, char *argv[]){
  char name[4] = {"@"};  
  printf("integer name %d\n", *(int*)name);  
  return 0;
}

The output is:

integer name 64

This is understandable because @ is 64 in integer, i.e., 0x40 in hex.

Now I change the program into:

#include <stdio.h>

int main(int argc, char *argv[]){
  char name[4] = {"@@"};  
  printf("integer name %d\n", *(int*)name);  
  return 0;
}

The output is:

integer name 16448

I dont understand this. Since @@ is 0x4040 in hex. So it should be 2^12+2^6 = 4160
If I count the '\0' at the end of the string, then it should be 2^16+2^10 = 66560

Could someone explain where 16448 comes from?

Upvotes: 2

Views: 110

Answers (3)

Ali Akber
Ali Akber

Reputation: 3800

This is how 16448 comes :

0x4040 can be written like this in binary :

   4    0    4    0   -> Hex
 0100 0000 0100 0000  -> Binary
 2^14      2^6        =  16448

Because here 6th and 14th bit are set.
Hope you got it :)

Upvotes: 2

5gon12eder
5gon12eder

Reputation: 25419

Your code actually invokes undefined behavior because you must not alias a char * with an int *. This is known as the strict aliasing rule. To see just one reason why this should be disallowed, consider what would otherwise have to happen if the code is run on a little and a big endian machine.

If you want to see the hex pattern of the string, you should simply loop over its bytes and print out each byte.

void
print_string(const char * strp)
{
  printf("0x");
  do
    printf("%02X", (unsigned char) *strp);
  while (*strp++);
  printf("\n");
}

Of course, instead of printing the bytes, you can shift them into an integer (that will very soon overflow) and only finally output that integer. While doing this, you'll be forced to take a stand on “your” endianness.

/* Interpreting as big endian. */
unsigned long
int_string(const char * strp)
{
  unsigned long value = 0UL;
  do
    value = (value << 8) | (unsigned char) *strp;
  while (*strp++);
  return value;
}

Upvotes: 2

user3629476
user3629476

Reputation: 170

Your math is wrong: 0x4040 == 16448. The two fours are the 6th and 14th bits respectively.

Upvotes: 2

Related Questions