我正在使用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值?这个价值代表什么?
答案 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;
,则内容将是不确定的。事实上,当我删除初始化时,我得到1629542246
(0x6120D766
,您仍然可以看到LSB设置为0x66
或f
。
这意味着我的整数在scanf
调用之前看起来像这样:
+------+
| ?? |
+------+------+------+------+
| ?? | d7 | 20 | 61 |
+------+------+------+------+
且scanf
调用仅更改了??
位。
答案 1 :(得分:0)
在读取char之前是否正在初始化int?可能只是一个未初始化的价值。 你能展示代码吗?使用什么函数将字符读入int?
4096是十六进制的0x00001000。根据您用来阅读角色的内容,可以是角色之前或之后的标志或字符,或者读取的字符数。