K&R《C程序设计语言》p23:打印最长的输入行

来源:互联网 发布:ug怎么编程 编辑:程序博客网 时间:2024/05/29 18:03

零、代码

#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;    }}

运行结果:


 

阅读全文
0 0
原创粉丝点击