K&R中 宏可以节省运行时函数调用的开销。这句话如何理解呢?

C语言 码拜 10年前 (2015-05-11) 984次浏览 0个评论
 

The C programming language K&R 书中有这么一段话:

Nonetheless, macros are valuable. One practical example comes from <stdio.h> , in which
getchar and putchar are often defined as macros to avoid the run-time overhead of a
function call per character processed. 

我的拙见理解是这样的:
   宏还是有一定的价值的,从stdio.h中举一个例子,在这个头文件中  getchar和putchar通常被定义成宏,每当
处理一个字符的时候,可以节省函数调用的运行时开销。

因为函数调用涉及到返回地址压栈,ebp保存等等开销,所以直接将其定义成宏,然后预处理的时候将其展开,这样每次
处理字符的时候就节省了上面的开销。是这个意思吗?

我比较笨,所以,就以为是这样意思的,然后我就下载了glibc,找到了stdio.h以及getchar.c中的函数定义,但是没有发现什么宏之类的东西,不知道我哪里想错了,求大神指导?

stdio.h:  extern int getchar (void);

getchar.c:
int
getchar ()
{
  int result;
  _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, stdin);
  _IO_flockfile (_IO_stdin);
  result = _IO_getc_unlocked (stdin);
  _IO_funlockfile (_IO_stdin);
  _IO_cleanup_region_end (0);
  return result;
}

1分
不是所有的函数都会定义成宏
1分
谁说getchar一定要定义为宏?
引用 1 楼 zhangxiangDavaid 的回复:

不是所有的函数都会定义成宏

这个我肯定知道,我的意思是为啥K&R说的  和我查看源码不一样

引用 2 楼 wangzuxi 的回复:

谁说getchar一定要定义为宏?

我的意思是为啥K&R说的  和我查看源码不一样

2分
引用 3 楼 A1174770492 的回复:
Quote: 引用 1 楼 zhangxiangDavaid 的回复:

不是所有的函数都会定义成宏

这个我肯定知道,我的意思是为啥K&R说的  和我查看源码不一样

C标准只规定了函数接口,没有规定实现,具体实现得靠各大平台,不一样正常

1分
引用 4 楼 A1174770492 的回复:
Quote: 引用 2 楼 wangzuxi 的回复:

谁说getchar一定要定义为宏?

我的意思是为啥K&R说的  和我查看源码不一样

人家说也只是说通常,并没说一定,C语言的实现有很多版本,glibc只是其中之一

4分
“函数调用的开销”主要是指函数调用前将函数参数、返回地址压栈,函数调用完从栈中取出返回地址并跳到该地址继续执行使用的若干条汇编指令。
8分
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

请问楼主,同样的语句是用过程的速度快,还是用函数的速度快呢?
引用 9 楼 u013163178 的回复:

请问楼主,同样的语句是用过程的速度快,还是用函数的速度快呢?

比较弱,,,,,,过程调用和函数调用的区别是?

引用 8 楼 zhao4zhong1 的回复:

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)

赵老师,
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
这两句话如何理解?求指导

2分
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
引用 12 楼 zhao4zhong1 的回复:

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

谢谢您的耐心指导 谢谢

K&R是在八十年代写着的,被称为“圣经”。但科学技术领域里,没有一成不变的东西,不能将他们说过的认为成永远正确、后人必须严格遵守照办的“圣旨”
1分
崇敬先贤,但不要迷信,更不要神圣化

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明K&R中 宏可以节省运行时函数调用的开销。这句话如何理解呢?
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!