2.4 可见度
本文讲的是C语言程序设计进阶教程一2.4 可见度,每当一个函数被调用的时候,一个新的栈帧就被压入调用栈。函数只能看到它自己的栈帧。考虑下面的两个例子:
这两个程序是完全相同的。把f1中的实参k和m重新命名为a和b不会起任何作用。调用栈是怎样的呢?以下是在第一个例子中当f1被调用时的调用栈:
第二个例子中的调用栈是相同的,只是栈帧f1中的实参有了不同的标志符而已。要注意地址是相同的。第二个例子强调了在f1中的a和b与f2中的a和b指代的是不同的地址–值对。下面是调用栈:
f1栈帧中的a和f2栈帧中的a没有任何关系。将a重命名为k对程序的行为不会造成什么不同。同样的规则也适用于b。要记住计算机不知道标志符。计算机只是使用地址和值。标志符只是对读代码的人有用,当程序被编译成机器可读格式的时候就被舍弃了。
这可能在学生中会造成困惑。凭直觉来看,似乎f1栈帧中的a和f2栈帧中的a是相关的。事实上,它们在栈内存中占据着不同的位置且是不相关的。下面的例子提供了进一步的解释:
下表显示的是当程序已经输入f1但是还未执行第3行时的栈内存:
在第3行被执行之后,调用栈将会像下表中那样。注意函数f1只是修改在它的栈帧中的变量a,因为一个函数只能看见它自己栈帧中的实参和变量。
下表显示了在程序运行第4行之后的栈内存:
函数f1返回a+b,即17+4=21。值21被写入在地址102(即值地址)的值。在f1返回之后,栈内存如下:
栈帧 标志符 地址 值
注意在f2中a和b的值没有改变。
虽然相同的标志符可能会出现在不同的栈帧中,但同样的名字却不能在相同的栈帧中被定义两次。下面的程序是无效的,因为a在一个函数中被同时用作实参和局部变量:
回顾一下,本章解释了栈内存的概念,它在函数被调用时会用到。栈内存为每一个函数存储返回位置、值地址、实参和局部变量。
原文标题:C语言程序设计进阶教程一2.4 可见度