我有一个像这样的简单程序:
#include <stdio.h>
int main(void)
{
int numbers[] = {1, 2, 3, 4, 5};
char chars[] = {'a', 'i'};
char name[] = "Max";
name[1] = chars[1];
printf("name (before) = %s\n", name);
name[1] = numbers[1];
printf("name (after) = %s\n", name);
return 0;
}
编译并运行给出:
$ gcc -std=c11 -pedantic -Wall -Werror ex8_simple.c $ ./a.out $ name (before) = Mix $ name (after) = Mx
这不是我想要的。然后我挖出了问题将整数值存储在C中的字符数组中并更改了程序,如下所示:
name[1] = '0' + numbers[1]; //replacing >> name[1] = numbers[1];
然后它就如我所期望的那样工作了:
$ gcc -std=c11 -pedantic -Wall -Werror ex8_simple.c $ ./a.out $ name (before) = Mix $ name (after) = M2x
我不明白幕后发生了什么,尤其是没有
'0' + …
的版本真的很奇怪。为什么字符串会以那种“奇怪”的方式被截断为 Mx
?
作为参考,这是《Learn C The Hard Way》练习 8 的简化版本。
(来源:asciitable.com)
name[1] = numbers[1];
中,您将
name[1]
分配给
2
,它等于上面 ASCII 表中的符号
STX
,它不是可打印字符,这就是您得到错误输出的原因。当您将
'0'
添加到
name[1]
时,它等于
add 48 to 2
,因此带有数字
50
的符号是
'2'
,这就是您获得正确输出的原因。
但是,您只为此编写了代码。让我解释一下这两种情况。这不是我想要的。
name[1] = chars[1];
name[1]
或
a
被
chars[1]
或
i
取代。所以,o/p 是
Mix
。
name[1] = numbers[1];
name[1]
或
a
被替换为
numbers[1]
或 2(不是
'2'
),这是不可打印的。(#note) 所以,输出是
Mx
。但是,在第二种方法中,
name[1] = '0' + numbers[1];
您通过添加
'2'
来存储
'0'
的 ASCII 等效值。因此,打印在输出中包含
character
的
'2'
表示。
替代方法:
如果您修改int
数组来存储
char
表示数字
0-9
的十进制等价物,那么您不需要添加
'0'
,如
int numbers[] = {'1', '2', '3', '4', '5'};
和
name[1] = numbers[1];
会给你想要的o/p。
C
中的数组索引是基于
0
的。# 注意:请参阅此
ASCII 表 以供参考。
name[1] = numbers[1];
中,您将
int
值分配给
char name[1]
,因此
numbers[1]
中的 int 值被视为某个 char 的 Ascii 代码,并且该 char 存储在
name[1]
中。
name[1] = '0' + numbers[1];
时,数字(2)将被添加到数字
0
的 ascii 代码中,因此你得到了实际的数字。
0
的Ascii码是48,加2就是
50
,这就是
2
的ascii码。以前,当您仅分配
name[1] = numbers[1];
而没有分配
0
时,会打印带有 ascii 代码
0
的字符。由于它不是一个正确的可打印字符,因此没有显示任何内容(在我的机器中,它显示为一些奇怪的表情符号)。