《C和指针》学习笔记(2)
1.1 “hello world”程序不说了,codeblocks直接生成。
1.2 题目:从标准输入读取几行输入。每行输入都要打印到标准输出上,前面要加上行号。让程序能够处理的输入行没有长度限制。
/*我的程序*//* int main() { int ch; int line=1; while((ch=getchar())!=EOF) { printf("%d",line); if(ch!='\n') printf("%c",ch); else { printf("\n"); line++; } } return EXIT_SUCCESS; }*/ /*答案解析*/ #include <stdio.h> #include <stdlib.h> int main() { int ch,line=0,at_beginning=1;//书上甚至是分开初始化和赋值的,估计是为了照顾初学者吧。 while((ch=getchar())!=EOF) { if(at_beginning==1){ at_beginning=0; line+=1; printf("%d",line); } putchar(ch); if(ch=='\n') at_beginning=1; } return EXIT_SUCCESS; } /*看完答案真的明白自己的差距了,设置at_beginning没有想到, 感觉自己用习惯了scanf和printf,getchar和putchar感觉反而忘记了。 */
这道题错很不应该。至于为什么getchar函数,主要是为了让输入行没有长度限制,一个个字符读入。
1.3 题目:从标准输入读取一些字符,并把它们写到标准输出上。他同时应该计算checksum值,并写在字符的后面。checksum用一个signed char类型的变量计算,初始为-1.当每个字符从标准输入读取的时候,他就被加到checksum中。如果checksum变量产生了溢出,这些溢出就会被忽略。当所有的字符被写入后程序已十进制的整数的格式打印出checksum的值,他可能为负,注意要在它后面打一个换行符。
#include <stdio.h> #include <stdlib.h> int main() { signed char checksum=-1; int ch; while((ch=getchar())!=EOF) { putchar(ch); checksum+=ch; } printf("%d\n",checksum); return EXIT_SUCCESS; }
书上没有标准答案,但我运行的结果也正确了,因为题目要求在文件中运行,所以我就改造到了shell窗口,理解就好了。不必纠结这种细节。最重要的是,我发现《C和指针》很少用char 来定义一个字符型变量,例如char ch很少见,我看到书上的解释是这样的:EOF是一个整型,因而它的位数比字符型要多,把ch声明为整形可以防止从输入读取的字符被解释为EOF,而且ch要足够大足以容纳EOF,所以定义为int.
同时我一直以为只有char类型,这次才知道还有unsigned char(0~255) 和signed char(-128~127),至于我们的char类型默认的是signed还是unsigned,根据IDE而定都有区别。我的codeblocks是signed。其实想想也好理解不管哪种字符型都是8个字节,只不过后者最高位是符号位,所以范围只能到127.貌似这种细节自己总会在意。。。
1.4
一行行地读取输入行,直至达到文件尾。算出每行输入行的长度,然后把最长的那一行打出来,假定输入行不超过1000个字符。
#include <stdio.h> #include <stdlib.h> #define N 1000 //输入行的最大长度 #define M 20 //输入的行数最大值 int main() { char b[M][M]; int a[M]={0},i=0,j,k,max,flag=1; /*ch用来读取字符,a这个数组用来储存各个行的长度 i用来表示行号*/ for(i=0;i<M;i++) { for(j=0;j<N;j++) { b[i][j]=getchar(); a[i]++; if(b[i][j]==EOF) { flag=0; break; } if(b[i][j]=='\n') break; } if(!flag) break; } max=0; for(k=0;k<i;k++) { if(a[max]<a[k]) max=k; } j=0; do{ printf("%c",b[max][j]); j++; } while(b[max][j]!='\n'); return EXIT_SUCCESS; }
不得不说,这道题我觉得写的很不好,但是没有书上答案,我的程序也可以AC,但是作为强迫症我总感觉不美,给我一种类似使用goto语句的感觉。记得别人说过,使用goto语句的数目与这个人的编程能力成反比。首先,我觉得应该书上应该还是想要用int ch这种定义方式,但我最终还是采用了熟悉的二维数组方式。最让我感觉不好的地方,是因为CtrlZ的问题(貌似和键盘输入输出就有它的问题吧)。因为如果要结束输入就得单独在一行中CtrlZ,在一行有其他字符的末尾输入EOF是不管用的,程序输入不会结束。而如果你在下一行并不输入CtrlZ而是其他字符,IDE会把这两行以某种方式当做同一行输出。所以这里面其实是很有问题的。当然我们要结束输入的时候一般输入CtrlZ不会再输入其他字符的,所以在实际运用中应该没有这些问题。把题目也写出来了,如果有人能写出更好的,希望得到指点。因为我知道自己的并不好。还有两道练习题,明天再写吧。