觉得学习一门语言有三个方面:一是语言本身的学习:语法,函数,特性等等;二是系统或计算机底层方面的了解:计算机的组成原理,操作系统额概念等等;三是算法和数据结构的学习.我想如果这三个方面学到融会贯通的话,就可以称为高手了吧. 我的整理中主要是第一和第二个方面,至于算法和数据结构,等到大三有时间的时候再去深入学习一下.(买了<算法导论>半年了,还没看多少,惭愧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() { char c; c=getchar(); printf("%c\n", c); c=getchar(); printf("%c\n", c); return 0; } 这个程序并不能得到正确的输出.因为getchar的缓冲区问题。 为了说明这一点,请看下面的程序。 #include<stdio.h> main() { char 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() { char c; c=getchar(); printf("%c\n", c); getchar(); //把回车符清掉 c=getchar(); printf("%c\n", c); return 0; } 这样做更可以说明问题,更好理解。 #include<stdio.h> main() { char 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) 的讲解.) 我是初学者,上面的内容也许会有错误或写的不清楚的地方,希望大家多多给我提意见,谢谢!
|