【发布时间】:2015-11-14 10:36:45
【问题描述】:
这是我的代码
#include <stdio.h>
#include <string.h>
int main(){
char pal[8] = "ciaooaic";
char pal1[7] = "ciaoaic";
int lenPal = strlen(pal);
int lenPal1 = strlen(pal1);
printf("strlen('%s'): %d\n", pal, lenPal);
printf("strlen('%s'): %d\n", pal1, lenPal1);
return 0;
}
问题是当我运行这段代码时,输出是:
strlen('ciaooaicP@'): 11
strlen('ciaoaic'): 7
第一个字符串在 P 和 @ 之间还有另一个不可打印的字符。我是菜鸟,所以也许我错过了一些明显的东西。有人可以帮我吗?
编辑:
只需多留一个空格,例如 char pal[9] = "ciaooaic"; char pal1[8] = "ciaoaic";
它有效,但为什么呢?我知道 \0 应该有一个空格,但是“ciaoaic”没有它也可以工作......
【问题讨论】:
-
只需多留一个空格,例如
char pal[9] = "ciaooaic"; char pal1[8] = "ciaoaic"; -
由于未定义的行为,您的代码可能会给出任何输出(甚至是正确的输出)。
-
当你初始化字符串时,例如
char pal[] = "ciaooaic";编译器将在末尾包含空终止符(注意:'\0'和0是等效的)。当您指定尺寸时,例如pal[8],您将数组的大小限制为该大小。如果您碰巧用字符填充它们并且没有为空值留出空间,编译器会很高兴,因为它相信您知道您的意思。如果碰巧,内存中char pal[8] = "ciaooaic";之后的下一个字符是0,那么您会意外地得到一个以空字符结尾的字符串。不要指望这种情况经常发生...... -
pal和pal1都不是 C11 §7.1.1 ¶1 定义的字符串:字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。术语多字节字符串有时用于强调对字符串中包含的多字节字符进行特殊处理或避免与宽字符串混淆。指向字符串的指针是指向其初始(最低地址)字符的指针。字符串的长度是空字符之前的字节数,字符串的值是所包含字符的值的顺序,按顺序排列。 -
关于允许非字符串初始化的措辞参见 C11 §6.7.9 Initialization ¶14: 字符类型的数组可以由字符串文字或 UTF-8 字符串文字进行初始化,可选地包含在大括号。字符串文字的连续字节(如果有空间或数组大小未知,则包括终止的空字符)初始化数组的元素。 ¶2 是一个约束:没有初始化器尝试为未包含在正在初始化的实体中的对象提供值。