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

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

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

输出:

输入char:f    
整数值= 4198 char值= f 

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

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

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

 #include  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调用只改变了?? 位。

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

4096是hex的0x00001000。 可以是字符之前或之后的标志或字符,或读取的字符数,具体取决于您用于阅读字符的内容。