《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不会再输入其他字符的,所以在实际运用中应该没有这些问题。把题目也写出来了,如果有人能写出更好的,希望得到指点。因为我知道自己的并不好。还有两道练习题,明天再写吧。

posted @ 2015-12-11 23:40  小白酷狗  阅读(437)  评论(0编辑  收藏  举报