6

为什么以下内容会产生效果 - 它打印一个充满随机字符的终端,然后退出,留下一个命令提示符,当您输入它时会产生垃圾。(我尝试过是因为我认为它会产生段错误)。

http://oi38.tinypic.com/r9qxbt.jpg

#include <stdio.h>

int main(){
    char* s = "lololololololol";
    while(1){
        printf("%c", *s);
        s++;
    }
}

它是用以下方式编译的:

gcc -std=c99 hello.c
4

7 回答 7

20

It will eventually seg fault, but before that it'll print out whatever bytes are in the same page. That's why you see random chars on the screen.

Those may well include escape sequences to change (say) the character encoding of the console. That's why you end up with gibberish when you type on the console after it's exited, too.

于 2008-11-13T17:31:14.617 回答
7

You are just printing out what is in memory because your loop doesn't stop at the end of the string. Each random byte is interpreted as a character. It will seg fault when you reach the end of the memory page (and get into unreadable territory).

于 2008-11-13T17:28:11.487 回答
7

Because you have an infinite loop (while(1)), and you keep getting the current value of pointer (*s), and then moving the pointer one char forward (s++). This has the effect of marching well past the end of the string into "garbage" (uninitialized memory), which gets printed to the console as a result.

于 2008-11-13T17:29:11.610 回答
7

In addition to what everyone else said in regards to you ignoring the string terminal character and just printing willy-nilly what's in memory past the string, the reason why your command prompt is also "garbage" is that by printing a particular "unprintable" character, your terminal session was left in a strange character mode. (I don't know which character it is or what mode change it does, but maybe someone else can pipe in about it that knows better than I.)

于 2008-11-13T17:37:52.950 回答
2

在此处给出的答案上略微扩展(都非常好)......当我刚开始使用 C 时,我自己不止一次遇到过这个问题,这是一个容易犯的错误。

快速调整您的while循环将解决它。其他人都给了你为什么,我会告诉你如何:

#include <stdio.h>

int main() {
    char *s = "lolololololololol";
    while (*s != '\0') {
        printf("%c", *s);
        s++;
    }
}

请注意,我们正在执行循环检查而不是无限循环 ( while(1)),以确保我们拉出的指针不是字符串的空终止符,从而避免您遇到的溢出。

如果您完全需要while(1)(例如,如果这是家庭作业并且教师希望您使用它),请使用break关键字退出循环。以下代码闻起来很臭,至少对我来说,但它有效:

#include <stdio.h>

int main() {
    char *s = "lolololololololol";
    while (1) {
        if (*s == '\0')
            break;
        printf("%c", *s);
        s++;
    }
}

两者都产生相同的控制台输出,最后没有换行符:

洛洛洛洛洛洛

于 2008-11-13T18:43:30.463 回答
1

您的循环不会终止,因此 println 在您编写的文本之后打印内存中的任何内容;最终它将访问不允许读取的内存,导致它出现段错误。

您可以按照其他人的建议更改循环,或者您可以利用在 c 中,零为假且 null(终止所有字符串)也为零的事实,因此您可以将循环构造为:

while (*s) {

而不是:

while (*s != '\0')

第一个可能更难理解,但它确实具有简洁的优点,因此通常用于节省一些打字。

于 2008-11-18T21:04:53.420 回答
0

此外,您通常可以使用“重置”命令返回命令提示符,当然是盲目输入。(输入、重置、回车)

于 2008-12-02T21:16:02.037 回答