zoukankan      html  css  js  c++  java
  • C语言中fgetc、fputc和getc、putc的区别是什么

      看书的时候,发现了这四个函数,想知道他们的不同。结果上网查发现很多人说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<stdio.h>
     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)这个函数的声明又是这样的:

      

      

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

  • 相关阅读:
    原生js实现Ajax请求,包含get和post
    JSP和Servlet的关系
    框架、框架模式和设计模式
    Java技术综述
    传输层和网络层区别(形象解释)
    Vue基本用法:过滤器、生命周期钩子函数和利用webpack 生成项目
    Vue基本用法:组件
    Vue基本用法:计算属性、监听器和表单输入绑定
    Vue基本用法:模板语法和指令系统
    win10想说爱你不容易——安装.net3.5也是一个坑(已有完美解决方法)
  • 原文地址:https://www.cnblogs.com/bwangel23/p/4159414.html
Copyright © 2011-2022 走看看