来自:华章出版社 2017-09-04 1010
本文讲的是C语言程序设计进阶教程一2.3.4 值地址,目前为止,我们所有函数的返回类型都是void,即函数什么都没有返回。函数可以返回值。考虑下面的例子:局部变量u在f2中,所以它是在f2的栈帧中。u的值是未被定义的,因为它还未被赋值。记住C不初始化变量,所以未初始化的变量可以存储任何值(即未占用)。f2的栈帧包含值还未被定义的变量u。u的地址是在f1被调用之前存储在调用栈的。这个地址叫作值地址,因为它是函数f1存储返回值的地址。因此,当f1的栈帧建立之后,就要为值地址再加上一行,它的值是u的地址。当函数f1执行的时候,它把k和m的值加在一起,产生的值为9。数字9之后被写入(即代替)在地址100处的初始未占用的值。在f1结束之后,它的帧出栈,调用栈就会像下面这样:这条规则可以合并到之前的调用栈规则中:如果一个函数返回了一个值,这个值就会被写到调用函数栈帧的一个局部变量中。这个变量的地址(叫作值地址)存储在调用栈中。如果函数有局部变量,那么局部变量被存储在实参之上。如果函数有实参,那么实参是存储在返回位置上的。实参和返回位置共同构成了被调用函数的栈帧。当一个函数被调用时,这条调用之后的行编号就被压入调用栈。这个行编号就是“返回位置”(RL)。这是在被调用函数结束(即返回)之后程序继续执行的地方。如果相同的函数在不同行处被调用,那么每个调用都有一个相应的返回位置(每个函数调用之后的那行)。当一个函数结束之后,程序将从存储在调用栈顶部的行编号处继续执行。调用栈顶部的内容就会被弹出。要注意调用函数(f2)没有被强制去存储被调用函数(f1)的返回值,上例中的第9行可以写作:在这种情况下,函数f1被调用,但是返回值被舍弃了。因为没必要去存储返回值,值地址没有压入调用栈。关键词return可以出于两种不同的目的被使用:如果void位于函数名前面,此函数不返回任何值。单词return使此函数停止,程序从调用函数中的返回地址继续。如果函数不是void型,单词return会为在调用栈中由值地址给出的变量赋值。请记住如果一个函数执行了return声明,在return之后的任何内容都会被忽略且不会被执行。执行return声明会使函数停止,且它的栈帧会出栈。之后程序会从返回地址继续执行。
原文标题:C语言程序设计进阶教程一2.3.4 值地址
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。