如何辨别Ç字符数组的结束的时候有没有空终止? [英] How does C identify end of character array when there's no null terminator?

查看:159
本文介绍了如何辨别Ç字符数组的结束的时候有没有空终止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于一个C字符数组需要一个空终止,下面code打印4的的S和一些垃圾字符。

Since a C character array requires a null terminator, the following code prints four a s and some garbage characters.

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

输出:

y = aaaa�

但是,下面的code不产生乱码。

However, the following code produces no garbage characters.

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 的第四个字符会自动用空终止初始化。此外,我想这以Z 获得内存彼此相邻分配。

I understand that the fourth character of z is automatically initialized with a null terminator. Also I guess that y and z get allocated next to each other in the memory.

但如何c正确打印仅4的的S IN这种情况下,而不是前?是否确定下一个字节已经被分配到另一个变量,所以应该停止了打印?

But how does C correctly print just 4 a s in this case and not in the former? Does it identify that the next byte is already allocated to another variable, so it should stop printing anymore?

推荐答案

的printf(Y =%s的\\ n,Y); ,在这种情况下, 未定义行为即可。换句话说,你很幸运 - 也许你打印创下了NUL之前的一些不可见字符,也许是因为栈对齐的阵列后,是一个零,也许是明星们正确

printf("y = %s\n", y); is, in this case, undefined behaviour. In other words, you got lucky -- maybe you printed some invisible characters before hitting a NUL, maybe there's a zero after the array because of stack alignment, maybe the stars are right.

我通常不细说这是UB,请勿触摸,但我觉得奇怪的是被迫。

I don't usually elaborate on "it's UB, don't touch", but I feel oddly compelled to.

你看,这里是你的程序:

Look, here's your program:

#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);
}

而现在我会用我特殊的编译标志编译:

And now I'm going to compile it with my special compiler flags:

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

和运行它:

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

哎呦,哈哈,这就是垃圾总量。更妙的是,这是因为堆栈保护的随机垃圾,所以它甚至没有(简单)确定性。活泉!

Whoops, haha, that's total garbage. Better yet, it's randomized garbage because of the stack protector, so it's not even (simply) deterministic. Woot!

还是不相信?是特殊的编译器标志太奇怪了吗?尝试

Still not convinced? Were the special compiler flags too weird for you? Try

#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作品。这就是不确定的行为非常清晰。

Still total garbage! Just remember -- these examples are all illustrative. Of course this is undefined behaviour, so you might get some totally different result, and come back here and tell me "but XYZ works". That's the very definition of undefined behaviour.

这篇关于如何辨别Ç字符数组的结束的时候有没有空终止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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