gpt4 book ai didi

c - 当没有空终止符时,C 如何识别字符数组的结尾?

转载 作者:行者123 更新时间:2023-11-30 21:14:30 26 4
gpt4 key购买 nike

由于 C 字符数组需要空终止符,因此以下代码会打印四个 a 和一些垃圾字符。

char y[4] = {'a', 'a', 'a', 'a'};
printf("y = %s\n", y);

输出:

y = aaaa�

但是,以下代码不会产生垃圾字符。

char y[4] = {'a', 'a', 'a', 'a'};
char z[4] = {'b', 'b', 'b'};

printf("y = %s\n", y);
printf("z = %s\n", z);

输出:

y = aaaa
z = bbb

我理解z的第四个字符自动用空终止符初始化。我也猜想 yz在内存中彼此相邻地分配。

但是 C 如何在这种情况下正确打印 4 个 a ,而不是在前者呢?它是否确定下一个字节已经分配给另一个变量,因此它应该停止打印?

最佳答案

printf("y = %s\n", y); 在这种情况下是未定义的行为。换句话说,你很幸运——也许你在命中 NUL 之前打印了一些不可见的字符,也许由于堆栈对齐而在数组后面有一个零,也许星星是对的。

<小时/>

我通常不会详细说明“这是 UB,不要碰”,但我觉得奇怪的是我不得不这么做。

看,这是你的程序:

#include <stdio.h>
int main() {
char y[4] = {'a', 'a', 'a', 'a'};
char z[4] = {'b', 'b', 'b'};

printf("y = %s\n", y);
printf("z = %s\n", z);
}

现在我将使用我的特殊编译器标志来编译它:

$ cc -O3 so15727258.c -o so15727258 -fstack-protector-all -Wall

并运行它:

$ ./so15727258
y = aaaa?>A??0F
z = bbb

哎呀,哈哈,这完全是垃圾。更好的是,由于堆栈保护器,它是随机垃圾,因此它甚至(简单地)不是确定性的。哇!

<小时/>

还是不相信?特殊的编译器标志对您来说太奇怪了吗?尝试一下

#include <stdio.h>

int bar() {
char x[4096];
}

int foo() {
char y[4] = {'a', 'a', 'a', 'a'};
char z[4] = {'b', 'b', 'b'};
printf("y = %s\n", y);
printf("z = %s\n", z);
}

int main() {
bar();
foo();
}

编译:

$ cc so15727258.c -o so15727258 -Wall

并运行它:

$ ./so15727258
y = aaaa?????ic?
z = bbb

还是垃圾!请记住——这些例子都是说明性的。当然,这是未定义的行为,因此您可能会得到一些完全不同的结果,然后回到这里告诉我“但是 XYZ 有效”。这就是未定义行为的定义。

关于c - 当没有空终止符时,C 如何识别字符数组的结尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15727258/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com