《Linux C一站式学习》第三章 简单的函数

系统 1336 0
4. 全局变量、局部变量和作用域
全局变量定义在所有的函数体之外,它们在程序开始运行时分配存储空间,在程序结束时释放存储空间,在任何函数中都可以访问全局变量。
如果全局变量和局部变量重名了会怎么样呢?

例3.6.作用域

则第一次调用 print_time 打印的是全局变量的值,第二次直接调用 printf 打印的则是 main 函数局部变量的值。
设想整个源文件是一张大纸,也就是全局变量的作用域,而 main 函数是盖在这张大纸上的一张小纸,也就是 main 函数局部变量的作用域。在小纸上用到标识符 hour minute 时应该参考小纸上的定义,因为大纸(全局变量的作用域)被盖住了,如果在小纸上用到某个标识符却没有找到它的定义,那么再去翻看下面的大纸上有没有定义,例如上图中的变量 x

局部变量可以用类型相符的任意表达式来初始化,而全局变量只能用常量表达式(Constant Expression)初始化 。例如,全局变量 pi 这样初始化是合法的:

      double pi = 3.14 + 0.0016;
    

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

      double pi = acos(-1.0);
    

然而局部变量这样初始化却是可以的。程序开始运行时要用适当的值来初始化全局变量,所以初始值必须保存在编译生成的可执行文件中,因此初始值在 编译时 就要计算出来,然而上面第二种Initializer的值必须在程序 运行时 调用 acos 函数才能得到,所以不能用来初始化全局变量。请注意区分编译时和运行时这两个概念。为了简化编译器的实现,C语言从语法上规定全局变量只能用常量表达式来初始化,因此下面这种全局变量初始化是不合法的:

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

虽然在编译时计算出 hour 的初始值是可能的,但是 minute / 60 不是常量表达式,不符合语法规定,所以编译器不必想办法去算这个初始值。

如果全局变量在定义时不初始化则初始值是0,如果局部变量在定义时不初始化则初始值是不确定的。所以, 局部变量在使用之前一定要先赋值 ,如果基于一个不确定的值做后续计算肯定会引入Bug。

例3.7.验证局部变量存储空间的分配和释放

          #include <stdio.h> void foo(void) { int i; printf("%d\n", i); i = 777; } int main(void) { foo(); foo(); return 0; }
        

结果是:

      134518128 777
    
修改一下
      int main(void) { foo(); printf("hello\n"); foo(); return 0; }
    

结果是:

      134518200 hello 0
    

非定义的函数声明也可以写在局部作用域中,例如:

      int main(void) { void print_time(int, int); print_time(23, 59); return 0; }
    

这样声明的标识符 print_time 具有局部作用域,只在 main 函数中是有效的函数名,出了 main 函数就不存在 print_time 这个标识符了。

虽然在一个函数体中可以声明另一个函数,但不能定义另一个函数,C语言不允许嵌套定义函数。

《Linux C一站式学习》第三章 简单的函数


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论