#include "stdio.h"
void main()
{
char firstName[1] = "1";
char middleName[1] = "1";
char lastName[1] = "1";
printf("%p\t%s\n",firstName,firstName);
printf("%p\t%s\n",middleName,middleName);
printf("%p\t%s\n",lastName,lastName);
}
我使用gcc 4.8.2编译此代码,令我困惑的是它为什么打印:
> root @ ubuntu:〜#。/ main
0x7fff7124273d 111
0x7fff7124273e 11
0x7fff7124273f 1
我认为应该打印:
0x7fff7124273d 1
0x7fff7124273e 1
0x7fff7124273f 1
你能帮助我吗?
答案 0 :(得分:6)
char firstName[1] = "1";
像这样初始化char
数组是合法的,但它不是字符串,因为它不是以空值终止的。
"%s"
中的 printf
需要一个字符串,所以你所做的是未定义的行为。
我的猜测是,编译器将变量放在一起,它们之后的字节恰好是0
,这可以解释发生了什么。但同样,它的未定义行为,任何事情都可能发生。
'1' '1' '1' 0
^ ^ ^
firstName | |
middleName |
lastName
答案 1 :(得分:4)
因为数组的大小是1而你正在分配长度为2的数组(字符串文字在末尾也有空字符\0
)。因此,指针指向的字符串可能不是NULL终止字符串。你需要大小为2的数组。
char firstName[2] = "1";
char middleName[2] = "1";
char lastName[2] = "1";
或
char firstName[] = "1";
char middleName[] = "1";
char lastName[] = "1";
此外,请勿在C中使用void main
。使用int main
。
答案 2 :(得分:2)
"1"
实际上是两个字节大小 - '1', '\0'
- 您忘记了C字符串是以空字符结尾的。空字节被初始化破坏。您的数组需要足够大才能包含初始化程序中的所有数据以避免这种情况。
答案 3 :(得分:2)
请记住, C风格的字符串是以null结尾的数组,这意味着字符串后面应该有'\0'
。可能对您有用的注意事项:
char firstName[2] = "1";
- 自行添加'\0'
,注意2而不是1。char firstName[] = {'1'}
- 不添加'\0'
。char firstName[2] = {'1'}
- 添加 '\0'
。您正在获取此输出,因为可能将字符放在一起,这是未定义的行为。
答案 4 :(得分:2)
代码
printf("%p\t%s\n",firstName,firstName);
打印的第一件事是数组firstName的基地址,
第二件事实际上是未定义的行为。要将任何字符数组作为字符串,它必须在结尾处具有空字符\0
。你的数组只有1个字符长,并且包含'1'
。所以你不要使用%s
来打印它。
而不是%s使用%c来打印字符,例如\
printf("%p\t%c\n",firstName,firstName);
答案 5 :(得分:1)
在C中,字符串是NUL终止的,即字符串“1”是字符{'1',0}。你没有为终结者留出足够的空间,所以你的字符串被截断了,printf不知道它们的结束位置。
将它们定义为
会更好char firstName[2] = "1";
最好做
char firstName[] = "1";
所以如果你应该处理一些长度超过1个字符的名字,编译器会为你计算适量的内存。