1. 变量的的作用域、局部变量、全局变量:
问题: 局部变量、全局变量作用域的范围是什么?
[举例1(局部变量的作用域)]编程求解1+2+...+10的值.
#include<stdio.h>
/* */
int main()
{
int Sum = 0;
/* 计算 1+2+...+10的值 */
for(short i = 1; i <= 10; i ++)
{
/* short变量 i的作用域仅限于 for()语句块内 */
Sum += i;
}
printf("1+2+...+10=%d\n", Sum);
/* */
return 0;
}
[举例2(语句块内外变量名相同)]
#include<stdio.h>
/* */
int main()
{
int x = 1, y = 1;
{
/* 此处定义的变量 y仅在该语句块内起作用 */
int y = 2;
/* 此处的变量 x就是外层语句定义的变量 x */
x = 3;
/* 输出应为 x = 3, y = 2 */
printf("x = %d, y = %d.\n", x, y);
}
/* x 的值已在上面的语句块内被修改, 所以此处 x = 3 */
/* y的值保持不变 */
/* 输出应为 x = 3, y = 1. */
printf("x = %d, y = %d.\n", x, y);
/* */
return 0;
}
[举例3(全局变量的作用域)]
#include<stdio.h>
/* 函数原型 */
void f();
int x = 1;
int y = 2;
int main()
{
f();
printf("x = %d, y = %d.\n", x, y);
/* */
return 0;
}
void f()
{
int a, b;
a = 2;
b = 1;
printf("a = %d, b = %d.\n", a, b);
}
问题: 当局部变量和全局变量重名时, 编译器如何处理?
#include<stdio.h>
/* 函数原型 */
void f();
/* 全局变量 */
int x = 1;
int y = 2;
/* */
int main()
{
f();
printf("x = %d, y = %d.\n", x, y);
/* */
return 0;
}
void f()
{
/* 此处的 x和 y与全局变量重名 */
/* 全局变量 x和 y在此不起作用 */
int x = 2;
int y = 1;
printf("x = %d, y = %d.\n", x, y);
}
问题: 当形参与全局变量重名时, 编译器如何处理?
#include<stdio.h>
/* 函数原型 */
void f(int x, int y);
/* 全局变量 */
int x = 1;
int y = 2;
/* */
int main()
{
f(x, y);
printf("x = %d, y = %d.\n", x, y);
/* */
return 0;
}
void f(int x, int y)
{
/* 此处的 x和 y与全局变量重名 */
/* 全局变量 x和 y在此不起作用 */
x = 2;
y = 1;
printf("x = %d, y = %d.\n", x, y);
}
问题: 如果并列语句块内的局部变量同名, 编译器如何处理?
#include<stdio.h>
/* 函数原型 */
void f(int x, int y);
/* */
int main()
{
int x = 1;
int y = 2;
f(x, y);
printf("x = %d, y = %d.\n", x, y);
/* */
return 0;
}
void f(int x, int y)
{
x = 2;
y = 1;
printf("x = %d, y = %d.\n", x, y);
}
/* 输出结果为 x = 2, y = 1<换行>x = 1, y = 2 */
[结论]
问题: 编译器如何区分不同作用域中的同名变量
[注]全局变量存储在静态存储区中.
2. 全局变量的利与弊:
[举例]
如果我们想计算递归求解斐波那契数列时递归函数执行的次数, 这时可以使用一个全局变量 count来记录函数运行的次数.
#include<stdio.h>
/* 函数原型 */
long Fib(int n);
/* 全局变量 */
unsigned int Count = 0;
/* */
long Fib(int n)//斐波那契数列递归函数
{
Count ++;
/* 数列首项下标为0 */
if(n == 0)
{
return 0;
}
else if(n == 1)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
/* */
int main()
{
int n;
/* 输入项数 n */
scanf("%d", &n);
/* n >= 0时为合法项数 */
if(n >= 0)
{
printf("%ld\n", Fib(n));
printf("Count = %u.\n", Count);
}
else
{
printf("data error!\n");
}
/* */
return 0;
}
[举例(计算输出斐波那契数列每一项时递归函数执行的次数)]
#include<stdio.h>
/* 函数原型 */
long Fib(int n);
/* 全局变量 */
unsigned int Count;
/* */
long Fib(int n)//斐波那契数列递归函数
{
Count ++;
/* 数列首项下标为0 */
if(n == 0)
{
return 0;
}
else if(n == 1)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
/* */
int main()
{
int n;
/* 输入项数 n */
int i;
/* 计数变量 */
long temp;
/* 记录Fib()函数的返回值 */
scanf("%d", &n);
/* n >= 0时为合法项数 */
if(n >= 0)
{
i = 0;
while(i <= n)
{
Count = 0;
temp = Fib(i);
/* 如果写成 printf("Fib(%d) = %ld, Count = %u.\n", i, Fib(i), Count); */
/* 输出时每一次Count都为0 */
printf("Fib(%d) = %ld, Count = %u.\n", i, temp, Count);
i ++;
}
}
else
{
printf("data error!\n");
}
/* */
return 0;
}
[运行结果]
问题: 使用全局变量有何利弊?
任何事物都有其两面性, 全局变量也不例外. 由于全局变量可在任何函数中被访问, 所以函数间的数据交换因此变得方便, 但这也会给程序带来一些副作用.
[注]虽然全局变量和 goto语句一样不是什么洪水猛兽, 但在使用其时要多加小心.