开发者

When using and int to read character, why is the value 4096 + ascii

开发者 https://www.devze.com 2023-02-10 04:43 出处:网络
I was using gcc and was testing various ways to process characters using either integers or characters as the datatype.

I was using gcc and was testing various ways to process characters using either integers or characters as the datatype.

int main() {
    int i;      开发者_JAVA技巧
    printf("Enter a char: ");
    scanf(" %c", &i);
    printf("integer value= %d     char value=%c", i, i);
    return 0;
}

Output:

Enter a char: f    
integer value= 4198     char value=f

I am curious about the integer value that is stored. It looks like the value is equal to 4096 + ascii value of 'f'.

My question is why is 4096 added to the ascii value of the character? What does that value represent?


Type in the following program and you'll understand why:

#include <stdio.h>

int main (void) {
    int val = 4096;
    printf ("Enter your character: ");
    scanf ("%c",&val);
    printf ("integer val = %d, character val = %c\n", val, val);
    return 0;
}

Compiling this with gcc -Wall (all warnings), gives:

qq.c: In function 'main':
qq.c:6: warning: format '%c' expects type 'char *',
        but argument 2 has type 'int *'

(as good a reason as any for ensuring you enable all warnings when compiling) and running it gives the same results you found:

Enter your character: f
integer val = 4198, character val = f

The reason for this is the way scanf works combined with the way variables are laid out in memory.

That scanf will simply get a character and put it in memory. Because you've given it the address of an integer, and that integer is little-endian, it will only overwrite the least-significant byte (LSB) of that integer. Think of viewing that memory as an overlapped area and you'll see why:

    +--- The address passed to scanf.
    |
    V
+------+
| char |                       <-- Treated as char.
+------+------+------+------+
| lsb  |      |      | msb  |  <-- Treated as integer (assumes 32-bit).
+------+------+------+------+

Because scanf doesnt touch those rightmost bytes of the integer, they're left with whatever they held before the call. In my code, I explicitly force that to 4096 but, if your declaration is the uninitialised int val;, the contents will be indeterminate. In fact, when I remove the initialisation, I get 1629542246 (0x6120D766 and you can still see the LSB set to 0x66 or f).

That just means my integer looked like this before the scanf call:

+------+
|  ??  |
+------+------+------+------+
|  ??  |  d7  |  20  |  61  |
+------+------+------+------+

and the scanf call only changed the ?? bit.


Are you initializing the int before reading in the char? Could simply be an uninitialized value. Can you show the code? What function are using the read the character into the int?

4096 is 0x00001000 in hex. Could be a flag or something before or after the character, or the number of characters read, depending on what you are using to read the character.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号