12

一文弄懂C语言的全局变量和局部变量,它们会冲突吗

 4 years ago
source link: https://blog.popkx.com/does-a-text-conflict-with-global-variables-and-local-variables-in-c-language/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一文弄懂C语言的全局变量和局部变量,它们会冲突吗

发表于 2018-11-02 10:11:04   |   已被 访问: 559 次   |   分类于:   杂谈   |   暂无评论

不知道大家如何,反正我最开始接触 C 语言编程时,最让我觉得神奇的就是变量的使用了,“a=1”之后又可以“a=0”。事实上,不仅仅是 C 语言,无论哪一门编程语言,变量都是基石,离开变量啥都做不了。

3dcdb3f8f5f0b900ac7be4991d65fe19.png

变量和赋值

请看下面的例子,很容易明白,变量只是一个容器,真正具有使用意义的是它装载的数据。C 语言中的“=”可以改变变量装载的数值,程序员常常称这一过程为“赋值”。

#include <stdio.h>

int main()
{
    int a = 3;
    printf("the variable is %d\n", a);
    return 0;
}
// 程序输出 the variable is 3

变量就好像鞋柜一样,它可以装很多不同的鞋子。里面装了布鞋,你可以从中拿出布鞋穿。里面装了皮鞋,你可以从中拿出皮鞋穿。“=”就相当于往鞋柜放鞋子。

4e30624e4a1479a687915038d8f78b3c.png

局部变量和全局变量

14cf4ee69ec788edb0461c7663babe57.png

我们把函数中定义的变量称为局部变量,因此函数的形参也属于局部变量,这里的局部变量有两个含义:
1、某个函数中定义的变量,不能被另一个函数使用。请看下面的例子,我们在 print_int 函数中定义了变量 b,它是不能在 print_again 里使用的。所以下面这样写,就会报语法错误。关于语法错误可参考我之前的文章。《》

void print_int(int a)
{
    int b = 3;
    printf("%d, %d\n", a, b);
}
void print_again()
{
    printf("%d\n", b);
}

2、每次调用函数时,局部变量都表示不同的存储空间。局部变量实在每次函数调用时,才分配的存储空间,被调用函数返回时,这部分存储空间就被释放了。例如上面这个程序,调用 print_int(2) 时,分配给 a 的存储空间里存放的是 2。下一次调用 print_int(3) 时,分配给 a 的存储空间存放的就是 3 了。

9f9c003f0ebab54156e3250626e6224f.png

与局部变量相对应的就是全局变量了,全局变量在整个程序的所有函数中,都能访问。我们将上面的代码做一点点修改,即将 b 变为全局变量,请看如下代码:

int b = 1;
void print_int(int a)
{
    b = 3;
    printf("%d, %d\n", a, b);
}
void print_again()
{
    printf("%d\n", b);
}

这时再编译,就不会出现语法错误了。那执行 print_again 函数,会输出多少呢?答案是取决于函数的执行顺序。b 被初始化为 1,如果之前没有调用 print_int ,那调用 print_again 打印出的 b 的值就是 1。如果先调用 print_int,再调用 print_again,那打印出的就是 3。因为在 print_int 中,b 被修改为 3 了。

源代码的书写顺序并不代表函数的执行顺序。

792fbc49329be63ef68d2fed21900c5d.png

可以看出,全局变量使用起来虽然方便,但是一定要慎用。因为任意位置都可能会修改它,而对于大型规模的开发,理清调用顺序也是一件体力活,出现了 bug 可能就是因为某个不起眼的地方对全局变量的读写造成的。

全局变量的初始化只能用常量表达式初始化,例如,对 pi 全局变量初始化时合法的:

double pi = 3.14 + 0.0016;

但这样初始化是不合法的:

double pi = acos(-1.0);

下面这样的初始化也是不合法的:

int minute = 360;
int hour = minute / 60;

全局变量和局部变量同名

0bd5f386d5374b05bf15919c6242ef47.png

则第一次调用print_time打印的是全局变量的值,第二次直接调用printf打印的则是main函数的局部变量的值。在C语言中,每个标识符都有特定的作用域(Scope),全局变量是定义在所有函数体之外的标识符,它的作用域从定义的位置开始直到源文件结束,而main函数局部变量的作用域仅限于main函数之中。如上图所示,设想整个源文件是一张大纸,也就是全局变量的作用域,而main函数是贴在这张大纸上的一张小纸,也就是main函数局部变量的作用域。在小纸上用到标识符hour和minute时应该参考小纸上的定义,因为大纸(全局变量的作用域)被盖住了,如果在小纸上用到某个标识符却没有找到它的定义,那么再去翻看下面的大纸,例如上图中的变量x。

阅读更多:   杂谈


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK