零、代码
#include <stdio.h>
#define MAXLINE 1000 // 输入行的最大长度
int max; // 保存目前为止最长行的长度
char line[MAXLINE]; // 保存当前的输入行
char longest[MAXLINE]; // 保存最长的行
int get_line(void);
void copy_longest_line(void);
int main()
{
int cur_len; // 当前行的长度
extern int max;
extern char longest[];
max = 0;
while ((cur_len = get_line()) > 0)
{
printf("The current line's length is : %d\n", cur_len);
if (cur_len > max)
{
// 如果当前行的长度大于上次保存的最大长度,则最大长度要更新为当前长度
// 并且要把当前行的内容放到longest数组中,此时longest数组原先的内容会被覆盖掉
max = cur_len;
copy_longest_line();
}
}
if(max > 0)
{
printf("\nThe max length of the input lines is : %d\n", max);
printf("The longest line is : %s\n", longest);
}
return 0;
}
// 将当前输入行的内容保存到line数组中
int get_line(void)
{
int c=0, i=0;
extern char line[];
/**
* 继续循环需要三个条件:
* (1) i小于999,因为数组的最大长度为1000(即0~999),line[999]要放换行符'\n',所以输入字符只能放在line[0]~line[998]
* (2) 输入的字符不为文件结束符,Windows的文件结束符为ctrl+z,mac/linux/unix的文件结束符为ctrl+d
* (3) 输入的字符不为换行符'\n',因为一旦换符,那就是新的一行了
*/
for (; i < MAXLINE-1 && (c= getchar()) != EOF && c != '\n'; ++i)
{
line[i] = c;
}
if (c == '\n')
{
line[i] = c;
++i;
}
// 换行符的下一个字符是行结束符'\0','\0'不算在行长度内
line[i] = '\0';
return i;
}
void copy_longest_line(void)
{
int i = 0;
extern char line[], longest[];
// 先把line[i]赋值给longest[i],再判断longest[i]是不是行结束符'\0'
while ((longest[i] = line [i]) != '\0')
{
++i;
}
}
一、运行结果
输入
a
abc
ab
ctrl + z
二、分析
0 请先阅读关联博文http://blog.csdn.net/haishu_zheng/article/details/73478039
1 定义数组char c[10],可存放十个字符,从c[0]~c[9]。注意计算机是从0开始计数而不是从1开始计数,所以最后一个元素是c[9]而不是c[10]。
2 字符与数字是一一对应的。具体而言,就是每个字符都对应着一个ascii编码。
比如:
a对应97,b对应98,其它小写字母以此类推;
A对应65,B对应66,其它大写字母以此类推;
字符‘1’对应49,字符‘2’对应50,其它数字以此类推;
回车符‘\r’对应13,换行符‘\n’对应10;
行结束符‘\0’对应0。
具体可参考 http://blog.csdn.net/haishu_zheng/article/details/75221350
所以,整型数组既可以用来存放整型元素,也可以用来存放字符元素;
同理,字符数组既可以用来存放字符元素,也可以用来存放整型元素。
3 在C语言中,字符数组是以’\0’作为行结束符的,并且行结束符不算在字符数组的长度内。
例子:输入abc并换行,这在长度为10的字符数组c[10]中是这么放的
a | b | c | \n | \0 | 空 | 空 | 空 | 空 | 空 |
这里c[0] = ‘a’, c[1] = ‘b’, c[2] = ‘c’, c[3]= ‘\n’, c[4] = ‘\0’, c[5]~c[9]都为空。
其长度为4,行结束符’\0’不算在长度内。
4 get_line函数中有个句子
for (; i < MAXLINE-1 && (c=getchar()) != EOF && c != '\n'; ++i)
等价于
for (i = 0; i < MAXLINE-1 && (c=getchar()) != EOF && c != '\n'; ++i)
因为i = 0;上面已经出现过,所以这里不写也可以。
5 本程序的执行过程
(0)最开始max=0;
(1)第一次输入a并且换行,get_line()函数的执行顺序为
i = 0时; 输入‘a’,循环的三个条件都满足,先执行line[0] = ‘a’;
再执行i++,i的值变为1
i = 1时; 输入换行符’\n‘ ,循环条件有一个不满足,结束循环
继续执行if(c == ‘\n’),这个条件是成立的,所以line[1] = ‘\n’,i++,i的值变为2
继续执行line[2] = ‘\0’
继续执行return 2。返回的2就是当前行的长度。
此时main()函数中cur_len=2,max=0, cur_max > max成立,执行max = cur_len,即max由原先的0更新为 2。再执行copy_longest_line()函数。
copy_longest_line()函数中,
longest[0] = line[0] = ‘a’
longest[1] = line[1] = ‘\n’
longest[2] = line[2] = ‘\0’循环结束
(2)第二次输入abc并换行,get_line()函数的执行顺序为
while语句中,
i = 0时,line[0] = ‘a’,i++,i的值变为1;
i = 1时,line[1] = ‘b’,i++,i的值变为2;
i = 2时,line[2] = ‘c’,i++,i的值变为3;
i = 3时,line[3] = ‘\n’,循环结束;
if语句中
line[3] = ‘\n’, i++, i的值变为4
line[4] = ‘\0’;
return 4;
main()函数中,
cur_len的值为get_line()的返回值4,上次得到的max值为2,cur_len>max,max=cur_len=4,即max的值由原先的2更新为4,并执行copy_longest_line()函数。
copy_longest_line()函数中,
longest[0] = line[0] = ‘a’;
longest[1] = line[1] = ‘b’;
longest[2] = line[2] = ‘c’;
longest[3] = line[3] = ‘\n’;
longest[4] = line[4] = ‘\0’;
循环结束。
(3)第3次输入ab并换行,执行get_line()函数,
line[0] = ‘a’;
line[1] = ‘b’;
line[2] = ‘\n’;
line[3] = ‘\0’;
return 3;
因为cur_len=3, max=4, cur_len>max不成立,所以max仍为上次得到的4不作改变,并且copy_longest_line()函数不被执行。
6 本程序中,全局变量max,line[1000], longest[1000]的定义和使用都在同一个文件中,并且是先定义后使用,所以实际上所有的extern语句都可以去掉。
但是若全局变量的定义在一个文件内(比如test1.c),使用在另一个文件内(比如test2.c),那么extern语句不能省。
代码:
#include <stdio.h>
#define MAXLINE 1000 // 输入行的最大长度
int max; // 保存目前为止最长行的长度
char line[MAXLINE]; // 保存当前的输入行
char longest[MAXLINE]; // 保存最长的行
int get_line(void);
void copy_longest_line(void);
int main()
{
int cur_len; // 当前行的长度
max = 0;
while ((cur_len = get_line()) > 0)
{
printf("The current line's length is : %d\n", cur_len);
if (cur_len > max)
{
// 如果当前行的长度大于上次保存的最大长度,则最大长度要更新为当前长度
// 并且要把当前行的内容放到longest数组中,此时longest数组原先的内容会被覆盖掉
max = cur_len;
copy_longest_line();
}
}
if(max > 0)
{
printf("\nThe max length of the input lines is : %d\n", max);
printf("The longest line is : %s\n", longest);
}
return 0;
}
// 将当前输入行的内容保存到line数组中
int get_line(void)
{
int c=0, i=0;
/**
* 继续循环需要三个条件:
* (1) i小于999,因为数组的最大长度为1000(即0~999),line[999]要放换行符'\n',所以输入字符只能放在line[0]~line[998]
* (2) 输入的字符不为文件结束符,Windows的文件结束符为ctrl+z,mac/linux/unix的文件结束符为ctrl+d
* (3) 输入的字符不为换行符'\n',因为一旦换符,那就是新的一行了
*/
for (; i < MAXLINE-1 && (c= getchar()) != EOF && c != '\n'; ++i)
{
line[i] = c;
}
if (c == '\n')
{
line[i] = c;
++i;
}
// 换行符的下一个字符是行结束符'\0','\0'不算在行长度内
line[i] = '\0';
return i;
}
void copy_longest_line(void)
{
int i = 0;
// 先把line[i]赋值给longest[i],再判断longest[i]是不是行结束符'\0'
while ((longest[i] = line [i]) != '\0')
{
++i;
}
}
运行结果: