阅读练习1-16的参考答案时,对其中的一点有些迷惑
原代码如下
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int maxline);
void copy(char to[], char from[]);
int main()
{
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = getline(line, MAXLINE)) > 0)
{
printf("%d,%s", len, line);
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0)
printf("%s", longest);
return 0;
}
int getline(char s[], int lim)
{
int c, i, j;
j = 0;
for (i = 0; (c = getchar()) != EOF && c != '\n'; ++i)
{
if (i < lim - 2)
{
s[j] = c;
++j;
}
}
if (c == '\n')
{
s[j] = c;
++j;
++i;
}
s[j] = '\0';
return i;
}
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
其中,定义getline()函数时,作者在for循环中,将if的条件设为if(i < lim-2)
对这一安排,我很是不解,为何不设置成if(i < lim-1)呢?
作者的解释是,
之所以要进行这样的修改,是因为数组s的最后一个下标是
lim-1
而这又是因为数组s中有lim个元素且我们已经读取了输入字符。所以
i<lim-2
将在数组s里给换行符留出一个位置,即
s[lim-2] = '\n'
还要给字符串结束符留出一个位置,即
s[lim-1] = '\0'
字符串的长度将通过变量i返回;而变量j则记录着被复制到字符串s中的字符的个数。
然而,读完之后,我仍然不太理解。
假设i<lim-1,则
s[lim-1]='\n'
s[lim]='\0'
也没有溢出,而且充分利用了字符串的空间。按照原文的操作,s[lim]不是反而被浪费掉了么?
此外,题目的要求是尽可能多地打印文本。理论上能打印的最多的文本数即MAXLINE-1,如果写为i<lim-2,则能打印的最多的文本数仅为MAXLINE-2,私认为也不是最优解。
因此,我将lim-2改为lim-1,同时
#define MAXLINE 2
以验证自己的想法
将代码作为输入,运行结果如下
当i<lim-1时,
![](https://i-blog.csdnimg.cn/blog_migrate/ede6dfad7f2de2866304a18359db5b43.png)
当i<lim-2时,
![](https://i-blog.csdnimg.cn/blog_migrate/804eabc032475db353f32f7a9f4867e0.png)
理论上,MAXLINE为2时,程序应打印首个字符。
综上,lim-1应该是更符合要求的,而且程序正常运行,也没有溢出。
自此,作为初学者,不敢武断地认为是书上写错了,但还是不理解作者安排i<lim-2的用意。
如果有大神加以解答,感激不尽!!