wayne 我的陋室我做主

上善若水,大智若愚 视远为明,听德为聪

原创 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) 的讲解.)

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

发表于 @ 2005年06月15日 20:06:00|评论(loading...)

新一篇: c语言学习零碎整理(2):结构体对齐问题 | 旧一篇: 我的c学习心得(零碎收拢) 序:

用户操作
[即时聊天] [发私信] [加为好友]
温铭
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
温铭的公告

每日三省吾身:过得快乐吗?能帮助别人的事情我做了吗?为自己的目标和理想做了些什么?尽力了吗?今天是为自己而活的吗?

我的心情

饭否

网站推荐




Email2Me


文章分类
收藏
C#高手
chengking(RSS)
liyingju的专栏(C#资源收集)
愚翁(RSS)
秋枫(RSS)
Python Web 开发
CherryPyTutorial
cherrypy官方网站
CherryPy教程
Django Step by Step(limodou写的优秀中文教程)
Django 文档中文版目录
django官方网站
KarriGell 的一个实例教程
web.py 0.2 教程
Python高手
城市拓荒者(RSS)
balabalamerobert(Python源码剖析)(RSS)
Beylog(RSS)
hideto(Python&&Django)
limodou的学习记录(RSS)
ygao的网络日志(RSS)
动态感觉 静观其变(RSS)
小蟒蛇IronPython
追寻真理之美(RSS)
出行必备
中国铁路网
中央气象台
南方航空公司
快乐e行
旅游搜索引擎:qunar
易旅阳光
芒果网
关注的blog
阿蒙博客(RSS)
IT、网络版权律师——王杰
psytopic
Wayne's googlepage
上海的温铭
孙小小:Presentationtao(RSS)
工作为何(RSS)
旁观者(RSS)
梁振(RSS)
涂老鸦—小老爷们那点事儿
老徐
靠近我---刘润(RSS)
他山之石,可以攻玉
∮明天去要饭's Blog(RSS)
DotNet (RSS)
吴莹莹的心情驿站
周星星(RSS)
妖光linux编程(胡正)
歌谣在风中飘舞(RSS)
许式伟的专栏
同窗好友
Code Cattle(RSS)
glemir(RSS)
JeeWin's Blog
lyz_1983(RSS)
YJ胡说(RSS)
啤酒屋(RSS)
大师(RSS)
小刘ivy的BLOG(RSS)
尹毅
星星世界(RSS)
有一种自由叫开源(RSS)
王一楠(RSS)
茶煜路312号(RSS)
蒲公英(RSS)
虾米爬啊爬(RSS)
同事
Fengbo(XSJ)
LML(RSS)
后视跑步|tomostar’s blog
岛屿的停泊
虎皮蛋糕(RSS)
影响我很深的人
Dale Carnegie
李开复(RSS)
杨澜(RSS)
郑渊洁(RSS)
存档
Csdn Blog version 3.1a
Copyright © 温铭