C的自学(放弃)之路

第一篇

在师父的推荐下,我决定要写写博客来记录一下自己的菜鸡之路,我的菜那真的不是一般的菜。

0.1_HelloWorld遇到bug

我按照C他爹写的《The C Programming Langauge (第二版)》在vim上敲了程序

#include<stdio.h>
 main(){
        printf("hello!world!!");
}

是很简单的helloworld程序,很简单的报错
这里写图片描述
English太渣没有办法,复制粘贴一波去翻译得到这样的结果说是类型说明符丢失,默认为“int”
这是什么意思呢??
完全按照书上的来的啊,是不是过时了呢?与ISO c9x有关(不懂不懂)??
后来我改了代码

 #include<stdio.h>
int  main(){
    printf("hello!world!!");
}

然后就成功了
这里写图片描述
后来仔细了解了一波,其实也不知道真假,说是

  • main()形式c90允许,c99不允许,虽然一些编译器允许,但这不符合标准,最好别这么写。void main()还没有被任何标准接受,有些编译器允许这种形式,但有些不允许。只有int main(void)是最标准的,你把程序从一个编译器转移到另一个编译器的时候不用担心出问题.

  • 还得知了操作系统是根据main的返回值来判断该程序是否正常结束,返回值为0显示正常。

从这开始其实我已经知道了好好读提示的重要意义。这个程序是昨晚写的,报错的时候我就一直在想怎么回事,费了老大力气去复制粘贴百度搜索,其实人家已经提示的清清楚楚明明白白,我只要在箭头上方加上声明int就好了呀!你看菜鸟就是这么蠢

0.2_getchar函数的bug

按照C他爹的指示,我敲了以下的简单代码

#include<stdio.h>
int main(void){
        int c;
        while((c = getchar())!= EOF)
                putchar(c);
}       

编译运行
这里写图片描述
唉,这不对头啊
C他爹可不是这么说的啊
这里写图片描述
不说是一次只打印一个字符吗??
又废了不少时间,终于搞明白了几个关键点

  • EOF为End Of File的简写,这是一个宏定义,代表文件结束符,其值为-1,
    这是一个仅用于输入的概念,即没有输出EOF的说法。
    输入时,如果是读文件,当读到文件尾部,即已经读到了文件的最后一个字节,还尝试读操作,就会获得一个EOF错误。
    如果是从标准输入进行读取,那么在终端下输入指定组合键,可以实现输入EOF。
    在windows下,需要输入Ctrl+Z; 在其它系统下需要输入Ctrl+D。输入时不区分大小写。

  • 代码写的也很清楚,只有遇到了这个EOF才能停止

  • 如果我将EOF改为遇到字符‘a’,那么在敲do you like apple?时,在遇到‘a’就能跳出循环,输出就会是do you like ,接下来就写代码验证一下

#include<stdio.h>
int main(void){
        int c;
        while((c = getchar())!= 'a')
                putchar(c);
}
~  

成功了
这里写图片描述

从这里我就开始有点点感觉了,不要怕麻烦,遇到了问题解决了,接下来的路才会更好走一点。

0.3_使用getchar函数写的字符计数小代码

从这里开始我已经体验到了事事问为什么的好处(菜鸟总会自带一些满足感),好像经过上面的bug之后写起C他爹介绍的同类型的代码感觉有点爽。很快就搞定了。

代码如下所示,是一个非常简单的字符计数代码,将敲入的字符一个一个输出并且计数

#include<stdio.h>
int main(void){
        int c;
        int a;
        a = 0;
        while((c = getchar())!= EOF){
                putchar(c);
                a++;
                printf("\n");
                printf("%d\n",a);
}

}

效果如图
这里写图片描述

0.4_单词计数代码bug

这是我的第四个代码,花了半小时才搞明白,因为C他爹给的这个代码对我这个菜鸟来说是有难度的!我仔细读了几遍,没什么头绪,没办法,可能就是脑子不太灵光。所以我cpoy去编译了一遍,才有了点领悟

在这里我又学了一点,不要死啃代码,拿笔画什么的会浪费时间。拿到这个代码应该将它的功能了解了,去编译一下,看看打印出来的这个是个什么东西,然后对比着代码来看,这样的效率会高一点。

 #include <stdio.h>
   #define IN   1  /* inside a word */
   #define OUT  0  /* outside a word */
   /* count lines, words, and characters in input */
   main()

       int c, nl, nw, nc, state;
       state = OUT;
       nl = nw = nc = 0;
       while ((c = getchar()) != EOF) {
           ++nc;
           if (c == '\n')
               ++nl;
           if (c == ' ' || c == '\n' || c == '\t')
               state = OUT;
           else if (state == OUT) {
state = IN;
++nw; }
}
       printf("%d %d %d\n", nl, nw, nc);
   }
  • 不错我总算是有点头绪了
  • 如果把单词看作是一个个整齐排列的苹果矩阵,那我做的计数就是放一条小虫子,从光标首行的头个苹果开始啃洞,进去就是IN,当从这个苹果出来时遇到’\n’||’\t’||’ ‘时就是OUT,但是下一步就会进入另一个苹果,所以在这一步修改状态state为IN
  • 所以10+dd删掉了C他爹的代码,自己手码了一段
#include<stdio.h>
#define IN 1
#define OUT 0
int main(void)
{
int c,linenum,worldnum,state;
linenum = worldnum = 0;
state = OUT;
while((c = getchar()) != EOF){
    if(c == '\n')
        linenum++;
    if(c=='\n'||c==' '||c=='\t')
        state = OUT;
    else if(state == OUT){
        state = IN;
        worldnum++;
        }
    }
    printf("%d %d",linenum,worldnum);
}       

成功了
这里写图片描述

0.5_打印输入中单词长度bug(未解决)

这是一道课后练习小题,我尝试自己做出来,但是很快就遇到了bug

#include<stdio.h>
int main(void){
        int c,worldlength;
        worldlength = 0;
        while((c=getchar())!= EOF){
                if(c==' '||c=='\n'||c=='\t')
                        printf("\n\n");
                else {
                        printf("*");

                }

                        }
}

代码很简单,但是我却感觉到很奇怪的地方是,我在终端键入的单词只能是一行,然后就出*了,
这里写图片描述
是什么意思呢?
我应该敲成这样
apple orange banana
one two three
^D
然后返回效果如图
(由于*为markdown的敏感符号我将用©️将其代替)
©️©️©️©️©️
©️©️©️©️©️©️
©️©️©️©️©️©️
©️©️©️
©️©️©️
©️©️©️©️©️
但是实际上我却只能键入第一行apple orange banana,再敲回车时就开始执行了。
我知道回车就是执行程序的意思,仔细分析我的程序,只要我不渐入^D(EOF)就不会退出程序
但是奇怪的是我在0.4中的那个单词计数代码中,却可以实现多行输入,最后键入EOF就会出结果,这是为什么呢??我在这里疑惑很久,希望有大神可以告知


首篇博客就到这里,感觉菜鸟的鸟生才刚刚开始。。。下篇见

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值