Q: 如果想要统计一个函数被调用的次数, 那么如何做? 我们知道, 在程序中, 函数调用完了之后, 那么该function 的stack frame就会移走, 函数中的所有的变量, 参数等等都会消失(想想stack 出栈)。显然如果我们的计数变量不能再该函数内部声明。 因为一旦该函数执行结束, 那么所有的变量都消失了。 解决的办法就是使用全局变量。 英文全局变量不会随着函数的调用结束而消失。
具体程序参考如下:
#include <iostream>
using namespace std;
int numCalls = 0;
void foo() {
++numCalls;
}
int main() {
foo(); foo(); foo();
cout <<numCalls << endl;
return 0;
}
运行结果(调用了foo() 3次)如下:
变量的生存范围(Scope)
Scope的含义是:where a variable was declared , determines where it can be accessed from.
例如, 上面的numCalls 具有global scope, 所以我们可以在任何一个函数中存取它, 改变这个全局变量的值后, 当函数调用结束, 全局变量会记录下改变后的值。如下:
int numCalls = 0;
int raiseToPower(int base, int exponent) {
numCalls = numCalls + 1;
int result = 1;
for (int i = 0; i < exponent; i = i + 1) {
result = result * base;
}
return result;
}
int max(int num1, int num2) {
numCalls = numCalls + 1;
int result;
if (num1 > num2) {
result = num1;
}
else {
result = num2;
}
return result;
}
为了形象表示变量的scope, 参照如下两幅图:
NOTE: 除了函数以外, Loops 和if/else 语句也具有他们自己的scope。 对于Loops(例如for语句), for语句中的定义的计数变量(i 等)
和for语句体具有相同的scope.。 注意, 任何情况下不要跨越变量的scope 去存取(acces)它。
double squareRoot(double num) {
double low = 1.0;
double high = num;
for (int i = 0; i < 30; i = i + 1) { //迭代了30次求解num 的根号
double estimate = (high + low) / 2;
if (estimate*estimate > num) {
double newHigh = estimate;
high = newHigh;
}
else {
double newLow = estimate;
low = newLow;
}
}
// A
return estimate; // ERROR, access out of scope
}
上面的例子中, 在变量estimate的scope(即A)外存取它, 所以出错了。解决办法有两种:
sol1: Move the code,, 如下:
double squareRoot(double num) {
double low = 1.0;
double high = num;
for (int i = 0; i < 30; i = i + 1) {
double estimate = (high + low) / 2;
if (estimate*estimate > num) {
double newHigh = estimate;
high = newHigh;
}
else {
double newLow = estimate;
low = newLow;
}
if (i == 29) // okay, i 在for语句的scope 之内
return estimate;
}
return -1;
}
sol2:declare the variable in a higher scope, 如下:
double squareRoot(double num) {
double low = 1.0;
double high = num;
double estimate;
for (int i = 0; i < 30; i = i + 1) {
estimate = (high + low) / 2;
if (estimate*estimate > num) {
double newHigh = estimate;
high = newHigh;
}
else {
double newLow = estimate;
low = newLow;
}
}
return estimate;
}