c - K&R 上的代码损坏?

标签 c

在 K&R 的“C 编程语言”(第二版)第 29 页,我读到了一个我认为已损坏的过程。由于我是初学者,所以我认为我错了,尽管我无法解释原因。

代码如下:

#include <stdio.h>
#define MAXLINE 1000 // Maximum input line size

int get1line(char line[], int maxline);
void copy(char to[], char from[]);

// Print longest input line
int
main()
{
  int len;                // Current line lenght
  int max;                // Maximum lenght seen so far
  char line[MAXLINE];     // Current input line
  char longest[MAXLINE];  // Longest line saved here

  max = 0;
  while ((len = get1line(line, MAXLINE)) > 0)
    if (len > max) {
      max = len;
      copy(longest, line);
    }

  if (max > 0)            // There was a line to read
    printf("Longest string read is: %s", longest);

  return 0;
}

// `get1line()` : save a line from stdin into `s`, return `lenght`
int
get1line(char s[], int lim)
{
  int c, i;

  for (i = 0; i < lim -1 && (c = getchar()) != EOF && c != '\n'; ++i)
    s[i] = c;

  if (c == '\n') {
    s[i] = c;
    ++i;
  }

  s[i] = '\0';

  return i;
}


// `copy()` : copy `from` into `to`; assuming
// `to` is big enough.
void
copy(char to[], char from[])
{
  int i;

  i = 0;
  while ((to[i] = from[i]) != '\0')
    ++i;
}

我的困惑是:我们正在使用函数 get1line 并假设在 for 循环的末尾 i 设置为lim -1。然后,以下 if 语句将在 lim 处更新 i,从而引发下一条指令(将 NULL字符串末尾的 > 字符)会破坏堆栈(因为在这种情况下,s[lim] 未分配)。

代码有问题吗?

最佳答案

总结:i == lim-1c == '\n'都不可能退出循环,所以你担心的情况永远不会出现。

详细来说:我们可以重写 for 循环(同时保留其含义)以使事件的顺序清晰。

i = 0;
for (;;) {
    if (i >= lim-1) break;      /* (1) */
    c = getchar();
    if (c == EOF) break;        /* (2) */
    if (c == '\n') break;       /* (3) */
    s[i] = c;
    ++i;
}

在循环退出 (1) 时,不可能出现 c == '\n' 的情况,因为如果是这种情况,则循环将在上一次的 (3) 处退出大约。*

在循环退出 (2) 和 (3) 时,不可能出现 i == lim-1 的情况,因为如果是这种情况,则循环将在 (1) 退出.

* 这取决于 lim 至少为 2,因此实际上循环中存在先前的时间。该程序仅调用 get1linelim 等于 MAXLINE,因此情况总是如此。**

** 当 lim 小于 2 时,您可以通过将 c 初始化为 '\n' 以外的值来使函数安全> 循环开始之前。但如果您担心这种可能性,那么您可能还需要担心 limINT_MIN 的可能性,因此 lim-1 由于整数溢出导致未定义的行为。

关于c - K&R 上的代码损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19084203/

相关文章:

C - 在文件的第二行写入

c - 使用 rpmlib 将标签添加到 header

c - %.s 的 sprintf 用法

c - 输入一个字符打印错误,但c中输入0时不打印

c - 与静态库的弱链接

c - 反转c中弹出的优先级队列的顺序

c - 释放部分动态分配的 block ?

c - 如何获取 ffmpeg 链接到的库列表(静态 ffmpeg 库)?

c - 分配给指针的指针和 free() 如何协同工作?

c - 尝试使用 OpenCV 在 C 中编译时遇到的问题