使用和int读取字符时,为什么值为4096 + ascii [英] When using and int to read character, why is the value 4096 + ascii

查看:82
本文介绍了使用和int读取字符时,为什么值为4096 + ascii的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

int main() {国际我;printf("请输入一个字符:");scanf(" %c", &i);printf("整数值= %d 字符值=%c", i, i);返回0;}

输出:

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

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

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

解决方案

输入以下程序,你就会明白为什么:

#include int main (void) {int val = 4096;printf("请输入您的角色:");scanf ("%c",&val);printf ("整数 val = %d, 字符 val = %c\n", val, val);返回0;}

使用 gcc -Wall(所有警告)编译它,给出:

qq.c:在函数'main'中:qq.c:6: 警告:格式 '%c' 需要类型 'char *',但参数 2 的类型为 'int *'

(与确保在编译时启用所有警告的任何理由一样充分)并运行它会给出与您发现的相同的结果:

输入你的角色:f整数 val = 4198,字符 val = f

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

那个 scanf 将简单地获取一个字符并将其放入内存中.因为你给了它一个整数的地址,而且这个整数是小端的,它只会覆盖那个整数的最低有效字节(LSB).把这段记忆看作是一个重叠的区域,你就会明白为什么:

 +--- 传递给 scanf 的地址.|伏+------+|字符 |<-- 作为字符处理.+------+------+------+------+|lsb |||msb |<-- 视为整数(假设为 32 位).+------+------+------+------+

因为 scanf 不接触整数最右边的字节,所以它们保留了调用前的所有内容.在我的代码中,我明确地将其强制为 4096 但是,如果您的声明是未初始化的 int val;,则内容将是不确定的.事实上,当我删除初始化时,我得到 1629542246 (0x6120D766 并且你仍然可以看到 LSB 设置为 0x66f).

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

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

scanf 调用只改变了 ?? 位.

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

int main() {
    int i;      
    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.

这篇关于使用和int读取字符时,为什么值为4096 + ascii的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆