当使用和int来读取字符时,为什么值为4096 + ascii

时间:2011-02-11 19:22:42

标签: c scanf

我正在使用gcc,正在测试使用整数或字符作为数据类型处理字符的各种方法。

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

输出:

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

我很好奇存储的整数值。看起来该值等于'f'的4096 + ascii值。

我的问题是为什么将4096添加到角色的ascii值?这个价值代表什么?

2 个答案:

答案 0 :(得分:4)

输入以下程序,您就会明白原因:

#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;
}

使用gcc -Wall(所有警告)进行编译,得出:

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

(作为确保在编译时启用所有警告的任何理由)并运行它会得到与您找到的相同的结果:

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

原因scanf的工作方式与变量在内存中的布局方式相结合。

scanf只会获得一个角色并将其放入内存中。因为你已经给它一个整数的地址,并且该整数是little-endian,它只会覆盖该整数的最低有效字节(LSB)。考虑将内存视为重叠区域,您将看到原因:

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

因为scanf没有触及整数的最右边的字节,所以它们留在调用之前的任何内容中。在我的代码中,我明确强制转到4096但是,如果您的声明是未初始化的int val;,则内容将是不确定的。事实上,当我删除初始化时,我得到16295422460x6120D766,您仍然可以看到LSB设置为0x66f

这意味着我的整数在scanf调用之前看起来像这样:

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

scanf调用仅更改了??位。

答案 1 :(得分:0)

在读取char之前是否正在初始化int?可能只是一个未初始化的价值。 你能展示代码吗?使用什么函数将字符读入int?

4096是十六进制的0x00001000。根据您用来阅读角色的内容,可以是角色之前或之后的标志或字符,或者读取的字符数。