文档库 最新最全的文档下载
当前位置:文档库 › C语言中fgetc、fputc和getc、putc的区别是什么?

C语言中fgetc、fputc和getc、putc的区别是什么?

C语言中fgetc、fputc和getc、putc的区别是什么,getcputc

看书的时候,发现了这四个函数,想知道他们的不同。结果上网查发现很多人说fgetc、fputc的f代表的是file,就是这两个函数是和文件有关的!但是一看他们的函数声明,如下图:

发现他们的参数里面都有文件指针啊!后来又去翻了翻APUE,发现那个f代表的其实是function,这是怎么一回事呢,且听我慢慢道来!

fgetc和getc他们的区别并不是在他们的使用上,而是在他们的实现上!具体来说,就是带f的(fgetc、fputc)实现的时候是通过函数来实现的,而不带f(putc、getc)的,实现的时候是通过宏定义来实现的!关于他们的不同点,就拿getc和fgetc来说,APUE(p115)上是这么写的:

<1>.getc的参数不应当是具有副作用的表达式。

<2>.因为fgetc一定是一个函数,所以可以得到其地址。这就允许将fgetc的地址作为一个参数传送给另一个函数。

<3>.调用fgetc所需时间很可能长于调用getc,因为调用函数通常所需的时间长于调用宏。

首先说第一点应该怎么理解呢,这个是因为宏这个东西坑蛮多,这里举个经典的例子。

在这个程序中,z2我想算8*8,但是传入的参数是5+3,6+2,宏替换之后就变成了5+3*6+2,最后结果就成了25。

那么第二点又是什么意思呢,这个其实就是一个函数指针,一个函数的地址能够传递给一个函数指针,让其来调用,但是宏就不行了!比如说下面这段代码:

由于MAX是个宏,所以就不能赋值给函数指针了!

关于第三点,这就涉及到一点汇编的知识了,在汇编语言中,函数的调用是通过栈来实现的!就是调用的时候压栈,调用完了再弹栈(关于汇编我也不是很清楚,所以叙述的有点粗糙,还望见谅!),比如下面这段代码:

1 #include

2 void func3()

3 {

4 printf("Hello,World!");

5 }

6 void func2()

7 {

8 func3();

9 }

10 void func1()

11 {

12 func2();

13 }

14 int main(int argc,char *argv[])

15 {

16 func1();

17 return 0;

18 }

我用gdb调试,在第4行设置了一个断点,查看它的函数调用栈如下:

而通过宏调用是不用压栈的,所以getc的速度就比fgetc快那么一点。

不过,关于这个是有一点例外,就是有时候调用函数并不是通过栈来实现的,所以作者用了一个很可能的词汇。关于这个问题,这个帖子讲的非常好(fgetc和getc,哪个速度快?)。

OK,上面就是fgetc和getc的不同了!不过需要补充一点的是关于GNU C下这两个函数其实是一样的,他们都是通过函数来实现的,然后getc再简单粗暴地增加了一个宏的声明。具体如下:

在stdio.h这个文件中getc的声明是这样的:

而在libio.h里面那个_IO_getc (_fp)这个函数的声明又是这样的:

所以,最后,各位亲们,我想说的是,不要再纠结了,这两个函数敞开了用吧,区别不是很大,一般不会出啥问题的!

相关文档