0

Playing around with C or C99, i'm trying to understand how casting, bitshifts, and Hex values work.

I have an issue with the following

char c[4];
c[0] = 0x41;
c[1] = 0x42;
c[2] = 0x43;
c[3] = 0x00;
printf("%s", c); //prints ABC
printf("%X", c); //prints 99B11760

Where does 99B11760 come from?

So similarly...

int main() {
    char a = 'a'; //ascii value is 0x41 (Mistake I made, 'a' is 0x61, 'A' is 0x41) 
    printf("%X\n",a); //outputs "61"? (THIS IS CORRECT OUTPUT, 'a' != 0x41)
}

I keep finding solutions to how to solve a similar problems of storing Hex values into char, but what I'm having trouble understanding is why or where some stored values do not correspond to it's ASCII values. Since it's neither the ASCII hex value, dec value, or octal Value, what value is being printed when using printf("%X\n", c);

Baconbitz
  • 139
  • 3
  • 12
  • 1
    This code is just buggy. You are lying to the compiler, telling it you are passing one thing when you actually pass something else. Stop doing senseless things and the mystery will go away. – David Schwartz Apr 09 '12 at 10:09
  • Couldn't agree more @DavidSchwartz , but the reason for me posting this question was to help me understand where buggy code, like this, went buggy. I do try to not post silly questions, most of the time I have been lucky to find the answers to, but this one did have me chasing my tail for a good while. – Baconbitz Apr 09 '12 at 11:26
  • possible duplicate of [printf the last Byte of a hex value in C](http://stackoverflow.com/questions/15296032/printf-the-last-byte-of-a-hex-value-in-c) – Dmitry Grigoryev May 26 '15 at 16:43

6 Answers6

1

an array variable in C is allowed to automatically convert into an address value (a.k.a a pointer value). The output you're seeing has absolutely no relation to the content of your array.

Perhaps you meant to do this?

char c[4];
c[0] = 0x41;
c[1] = 0x42;
c[2] = 0x43;
c[3] = 0x00;
printf("%X", *(unsigned int*)c );
Ben Cottrell
  • 5,741
  • 1
  • 27
  • 34
  • 1
    I hope not, since that's still undefined behavior. – David Schwartz Apr 09 '12 at 10:13
  • This does make alot more sense, I failed to notice that a de-reference was needed for printf statement to work with the proper types. 'printf("%d c[0] int value\n", *c); //prints 65' 'printf("%X c[0] hex value\n", *c); //prints 0x45' 'printf("%s c[0] str value\n", c); //prints "ABC"' Thank you again. – Baconbitz Apr 09 '12 at 10:32
1

Where does 99B11760 come from?

It's the value c happened to have after you forced it to decay into a pointer.

I keep finding solutions to how to solve this problem

What problem? Is there something you are trying to do that you don't know how to do? "I did something that made no sense and got a nonsense answer" isn't a problem. Just don't do that.

.. but what I'm having trouble with is understanding why or where 61 is being printed instead of the ASCII hex value 0x41. It's not the decimal value, nor the Octal value.

As you see, there is no particular value that it should be. But it has to be something. If you throw a die up in the air and it comes down with a 2, do you wonder why it's a 2? Of course not. You only have an issue when it should be one thing but is another. In this case, there's nothing it should be.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
0
 printf("%X", c); //prints 99B11760

This invokes undefined behavior. x conversion specifier expects an unsigned int but you are passing a char *.

In your second part of your question, you should cast a to unsigned int.

printf("%X\n", (unsigned int) a);

A ascii value is 0x41, but a ascii value is 0x61.

ouah
  • 142,963
  • 15
  • 272
  • 331
0

For the first question, when you print c using %X format it is printing the address of the array (address of first character). For the second question , this is because ASCII value of a is 97 (decimal) which converted to hex is 61. If you use A character then it will print 41 as the ASCII value of capital A is 65.

Naveen
  • 74,600
  • 47
  • 176
  • 233
0

c is a pointer so when you print it using anything but %s you will get the pointer address printed.

giorashc
  • 13,691
  • 3
  • 35
  • 71
0
int main() {
char a = 'a'; //ascii value is 0x41
printf("%X\n",a); //outputs "61"?
}

In this case, first you are storing 'a'(ascii value = 97) into character a, so character a contains 97, then you are printing 97 in hex form as "0x61"

char c[4];
c[0] = 0x41;
c[1] = 0x42;
c[2] = 0x43;
c[3] = 0x00;
printf("%s", c); //prints ABC
printf("%X", c); //prints 99B11760

in this case

         '0x41' in decimal value is 65 is 'A' in ASCII
         '0x42' in decimal value is 66 is 'B' in ASCII
         '0x43' in decimal value is 67 is 'C' in ASCII   
         '0x00' in decimal value is 00 is null in ASCII   

It will output 'ABC ' if format specifier is char/string type

Som
  • 950
  • 2
  • 16
  • 29
  • `printf("%X", c); //prints 99B11760`, for this line when i compiled and executed on cygwin i am getting **22CCEC**, but for the same when i compiled and executed on online compiler "codepad" i am getting **BF859328** value, check out this @http://codepad.org/8B2Fg9y5 – Som Apr 09 '12 at 11:35