gpt4 book ai didi

c - 具有明显完美代码的 C 程序中的段错误

转载 作者:太空宇宙 更新时间:2023-11-04 07:23:50 25 4
gpt4 key购买 nike

我最近向一位想学习C的 friend 推荐了K&R,他在第一章中遇到了一个练习,给他带来了各种错误。我在我的 Ubuntu 安装上编译它,在 C90 选项和默认选项之间交替。我已经查看了各个角度,但它似乎是完美的代码……但每次运行它时它总是给我一个段错误。我不是棚子里最聪明的程序员,但这让我很沮丧。

究竟是什么导致了这样的错误?

代码如下:

#include <stdio.h>
#define MAXLINE 1000

void reverse(char s[]);

/* A program that reverses its input a line at a time */
main()
{
int c, i;
char line[MAXLINE];

for (i = 0; (c = getchar()) != EOF; ++i) {
line[i] = c;

if (c == '\n') { /* Upon encountering a newline */
line[i] = '\0'; /* replace newline with null terminator */
i = 0;
reverse(line);
printf("\n%s\n", line);
}
}
return 0;
}

/* A function that reverses the character string */
void reverse(char s[])
{
int a, z;
char x;

for (z = 0; s[z]; ++z) /* Figure out where null terminator is */
;
--z;
for (a = 0; a != z; ++a) { /* Reverse array usinng x as placeholder */
x = s[a];
s[a] = s[z];
s[z] = x;
--z;
}
}

最佳答案

这里你少了一个分号:

for (z = 0; s[z]; ++z);     /* Figure out where null terminator is */
// ^

这个循环应该一直运行到找到空终止符为止。如果你省略这个分号,那么在每次迭代中它都会执行 ++z--z ,这意味着它永远循环。你想要 --z在这个循环完成之后发生,因为这将设置z等于字符串空终止符之前的最后一个字符。

对于偶数长度的字符串,az将在第二个循环中相互交叉(它们永远不会相等)。例如,如果 z=5a=4 ,然后在下一次迭代中 a=5z=4 .如果您检查 a<z而不是 a!=z那么你就避免了那个问题。由于您正在检查 !=而不是 < ,这将导致循环几乎无限地运行。但是,您最终会得到一个 SEGFAULT 作为 a长得太大了 z变得太小,因为它们都将用于索引缓冲区外的内存。

for (a = 0; a != z; ++a) {  /* Reverse array usinng x as placeholder */
// ^ should be <, not !=

最后,main 也有一个错误.当你找到换行符时,你设置 i=0 .这在打印字符串时工作正常,但当 i 时在循环结束时递增,你最终得到 i=1当您开始阅读下一个字符串时。这意味着您将在字符串的开头有一个额外的字符。您需要做一些事情才能正确重置 i以确保不会发生这种情况。

K&R在3.5节有一个字符串反转函数。在我的副本中,它位于第 62 页。看起来你的 friend 决定迭代字符串而不是调用 strlen (这实际上是函数调用所做的所有事情),并认为 a<z应该等同于 a!=z .

关于c - 具有明显完美代码的 C 程序中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19781781/

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