c语言学习零碎整理(1):缓冲区

觉得学习一门语言有三个方面:一是语言本身的学习:语法,函数,特性等等;二是系统或计算机底层方面的了解:计算机的组成原理,操作系统额概念等等;三是算法和数据结构的学习.我想如果这三个方面学到融会贯通的话,就可以称为高手了吧.

我的整理中主要是第一和第二个方面,至于算法和数据结构,等到大三有时间的时候再去深入学习一下.(买了<算法导论>半年了,还没看多少,惭愧ing).

1,为什么要用缓冲区?
如:
  int c;
  FILE *istream,ostream;
  while( (c = getc(istream)) != EOF)
      putc(c,ostream);
getc和putc时以单个字节为单位的.
 而一次读一个字节,效率很低。大部分的效率提高是通过减少系统调用的次数得到的。当进行一个系统调用时,程序和内核之间模式切换的代价时相当大的,通常来说,如果需要获得非常高的效率,就要小心翼翼的减少程序中系统的调用次数。

2,什么是缓冲区?
标准I/O库针对这一情况实现了一个完美的缓冲区机制来避免效率的降低。首先,第一次getc调用将导致系统调用read将BUFSIZ个字符读入缓冲区(BUFSIZ是在<stdio.h>中定义的常量),该缓冲区是由标准I/O库创建的(缓冲区依然处于用户地址空间中)。但是getc只返回第一个字符,接着getc实际上是从缓冲区读入的字符。putc的机制一样。

3.关于getchar的缓冲区

举个例子吧.

#include<stdio.h>//原意是显示输入的两个字符
main()
{
int c;
c=getchar();
printf("%c/n", c);
c=getchar();
printf("%c/n", c);
return 0;
}
这个程序并不能得到正确的输出.因为getchar的缓冲区问题。
为了说明这一点,请看下面的程序。

#include<stdio.h>
main()
{
int c;
c=getchar();//这时,缓冲区中有c和回车符
printf("%c/n", c);//输出c
printf("%d/n",getchar()); // 这里将输出回车的ASCII的值,是10
c=getchar();
printf("%c/n", c);
printf("%d/n",getchar());//输出10

}
问题是在与:在输入一个字符后我们有敲了一个回车,问题出来了,在第一个程序中,第二个printf语句输出的不是是回车。

改为这样就可以了
#include<stdio.h>
main()
{
int c;
c=getchar();
printf("%c/n", c);
getchar(); //把回车符清掉
c=getchar();
printf("%c/n", c);
return 0;
}

这样做更可以说明问题,更好理解。
#include<stdio.h>
main()
{
int c;
c=getchar();
printf("%c/n",c);
c=getchar();
printf("%d/n",c);
printf("%c/n",getchar());
return 0;
}//对于这种问题,最好的方法是把输入的字符(包括回车符)写在纸上这样就容易出错。

4,linux里面的一个程序

学操作系统的时候,编了一个关于进程的小程序,不想也遇到了缓冲区的问题.

程序如下:

#include<stdio.h>
void createprocess(){
        int t;
        printf("123");
        t = fork();
        if(t != -1){
                if(t == 0)  printf("b");
                if(t > 0)    printf("a");
        }
}
                                                                               
int main(){
        createprocess();
}
结果是123a123b
为什么123会打印两次呢?
fork在打印123的语句下面啊. 

这就是我当初的疑问.后来再csdn上面发了个帖子问了一下,才明白,是缓冲区的问题.

printf出现在fork前,似乎应该出现一次,但由于没有换行符,或者用fflush将缓冲区内容输出,所以在fork时,“123”没有输出,还在缓冲区内,它的内容也被子进程所复制。父进程和子进程的缓冲区内,都有“123”。(谢谢 nichotilikai(lk) 的讲解.)

我是初学者,上面的内容也许会有错误或写的不清楚的地方,希望大家多多给我提意见,谢谢!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值