S t a r . 2019-02-14 22:06 采纳率: 100%
浏览 795
已采纳

函数原型与函数首行与函数声明三者的区别与联系

为什么谭浩强的书上前面说,函数首行称为函数原型,而后面说函数声明是函数原型?函数原型到底指的是什么?另外,函数原型中包含函数的存储类别吗?

  • 写回答

1条回答 默认 最新

  • threenewbee 2019-02-14 22:55
    关注

    谭浩强都七老八十了,你和他较什么真呢。
    所谓函数声明、原型,就是指函数名、参数和返回值类型。
    所谓函数定义,就是函数的实现的代码。
    “函数的存储类别”是什么鬼。

    C语言是一种原始而简陋的语言,你可能无法想象的是,在C语言设计的时候(1970s),计算机往往只有不到1MB的字节的内存,还要同时为很多人服务。你现在手机的内存可能都有几个GB,是那时候计算机的成千上万倍,而现在普通家用计算机的内存,都是16GB 32GB或者更多。

    如果你明白了这一点,你就可以理解为什么C语言为了追求编译效率而做出的很多在今天看来非常变态的限制,比如说一个函数的调用必须放在申明的后面。
    因为编译器在编译一个函数调用的时候,它需要生成一系列指令将函数参数放入堆栈、跳转指令和返回清理堆栈的代码(如果你对这方面不理解,可以自己搜google调用约定,calling convention)。

    函数的申明包含了函数的入口地址、参数的个数和类型,返回值类型这些信息,它们是调用的代码生成所必须知道的信息。而C语言的先申明后使用的规定,使得编译器只需要一趟扫描,并且可以边生成代码边建立符号表,而节约了非常可怜的那么一点点内存。

    为什么函数申明就可以而不需要函数定义呢,因为对于调用者来说,只要知道堆栈和跳转就可以了,函数怎么实现的其实根本不需要关心。所以编译器可以先用符号占位符占住跳转的地址,然后再编译函数的代码,最后把这些符号连接起来,而外部函数,则可以通过链接程序去连接。

    你所谓的函数的存储,属于函数自身代码的一部分。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3