【问题标题】:When using and int to read character, why is the value 4096 + ascii使用and int读取字符时,为什么值为4096 + ascii
【发布时间】:2011-02-11 19:22:42
【问题描述】:

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

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

输出:

输入一个字符:f 整数值= 4198 字符值=f

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

我的问题是为什么要在字符的 ascii 值中加上 4096?该值代表什么?

【问题讨论】:

  • 你能提供一些示例代码吗?准确了解您在做什么很重要。
  • 您需要链接代码,但我猜您在调用 scanf 并读取字符之前没有将整数设置为零。因此,您有一些垃圾未定义数据。发布一些代码,我们会看到...

标签: c scanf


【解决方案1】:

输入下面的程序,你就会明白为什么了:

#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 将简单地获取一个字符并将其放入内存中。因为你给了它一个整数的地址,而且这个整数是小端的,它只会覆盖那个整数的最低有效字节(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 调用仅更改了?? 位。

【讨论】:

  • 感谢 paxdiablo 的解释。我没有初始化我的变量,当我看到附加值是 4096 时,我就贸然下结论了。我在另一台机器上试了一下,得到了不同的值。
【解决方案2】:

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

4096 是十六进制的 0x00001000。可能是标志或字符之前或之后的内容,或者读取的字符数,具体取决于您用于读取字符的内容。

【讨论】:

  • 我没有初始化 int。 4096 是一个机会值,我匆忙下结论,认为它除了是内存中的旧垃圾数据之外可能还有某种意义。
猜你喜欢
  • 2013-11-20
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2023-03-24
  • 2014-08-19
  • 2016-03-28
  • 1970-01-01
相关资源
最近更新 更多