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

问题描述:

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

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

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

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

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

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

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