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; }}
运行结果:
- K&R《C程序设计语言》p23:打印最长的输入行
- K&R《C程序设计语言》p21:打印最长的输入行
- K&R-C程序设计语言+Emacs
- C程序设计语言(K&R)笔记
- K&R的名著:<C程序设计语言>小程序总结1
- K&R的名著:<C程序设计语言>小程序总结2
- K&R的名著:<C程序设计语言>小程序总结3
- K&R的名著:<C程序设计语言>小程序总结4
- K&R的名著:<C程序设计语言>小程序总结5
- K&R的名著:<C程序设计语言>小程序总结6
- K&R的名著:<C程序设计语言>自引用结构
- K&R《C程序设计语言》p17:求m的n次方
- C程序设计语言练习1-16 修改打印最长文本行的程序的主程序main,使之可以打印任意长度的输入行的长度,并尽可能多的打印文本
- C程序设计语言(K&R)第一章学习笔记
- 2011-10-4+【K&R+】+1-16+打印那个最长的那行!
- K&R的名著:<C程序设计语言>小程序总结7指针
- K&R的名著:<C程序设计语言>小程序总结8结构体
- K&R的名著:<C程序设计语言>小程序总结p117统计关键字
- activemq点对点以及发布订阅模式代码(参考前一篇jms学习理解)
- 统计学习方法笔记之十----隐马尔科夫模型(一)
- spring加载xsd文件时报错
- 1061. 判断题(15)
- Unity3D 官方文档 UGUI的总览 Canvas和EventSystem的认识
- K&R《C程序设计语言》p23:打印最长的输入行
- ejs模板引擎
- CFgym:Memory Manager(dp & 单调队列优化)
- 文章标题
- VMware虚拟机linux系统时间同步的解决办法
- mysql 开启远程连接
- 终生学习者,永远劳苦命!
- learning之桥接模式
- 欢迎使用CSDN-markdown编辑器