变量和作用域与全局变量的利与弊

本文探讨了C语言中变量的作用域,包括局部变量和全局变量的范围。通过举例说明了局部变量在语句块内的限制,以及全局变量的广泛作用域。当同名变量出现在不同作用域时,编译器如何处理。同时,讨论了全局变量在数据交换上的便利及其可能带来的副作用,特别是在递归函数中的应用。强调在使用全局变量时需谨慎,以避免程序复杂性和错误风险的增加。
摘要由CSDN通过智能技术生成

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语句一样不是什么洪水猛兽, 但在使用其时要多加小心.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好梦成真Kevin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值