变量的作用域与生存期

  • 一、变量的作用域
    • 1.基本概念
    • 2.代码分析
    • 3.总结
  • 二、变量的生存期
    • 1.基本概念
    • 2.C语言的内存分布
      • (1)基本概念
      • (2)数据在内存中的分布
    • 3.总结
    • 4.补充

一、变量的作用域

1.基本概念

作用域的域英文翻译为scope,作用域即作用范围。作用域关键在于域,作用域影响的是访问权限,出了作用域就无权访问了。
关于域:
(1)有基于整体项目的域,可以做到整个项目的全局特性,我们称之为全局变量;
(2)有基于文件的域,可以做到文件内全局特性,只能在文件内部访问,我们称之为静态全局变量;
(3)有基于函数的域,在函数内部访问,我们称之为局部变量、静态局部变量以及函数形参;
(4)有基于块的域,如if、while或者直接写{}包含的块域,在语句块内部访问,我们称之为局部变量或静态局部变量。

注意
其实全局变量也不是全域的,严谨的描述应该是全局变量的定义开始(包含作用域扩展定义)到其域结束。

2.代码分析

var_scope1.c

int global1 = 111;         //全局变量
static int global2 = 222;  //静态全局变量

var_scope2.c

#include <stdio.h>extern int global1;   //声明全局变量
extern int global2;   //声明静态全局变量void max(int *part1, int *part2)  //该函数形参可以跨函数访问,所以函数的形参(也是局部变量)的作用域是全域的。
{static int temp;        //静态局部变量temp = *part1;*part1 = *part2;*part2 = temp;
}int main()
{int part1 = 99;         //局部变量//part1 = part2;        //part2未定义static int part2 = 999;{int part3 = 100;}printf("global1 = %d\n", global1);//printf("global2 = %d\n", global2);  //global2未定义max(&part1, &part2);printf("part1 = %d, part2 = %d\n", part1, part2);//part1和part2的数值交换//printf("part3 = %d\n", part3);  //part3未定义//printf("temp = %d\n", temp);    //temp未定义return 0;
}

执行gcc var_scope1.c var_scope2.c -o var_scope
运行var_scope得到运算结果。

3.总结

(1)全局变量在其他文件中使用,需在使用之前用external修饰声明全局变量;
(2)static修饰全局变量,用于限定文件作用域;
(3)auto只能修饰局部变量,一般省略不做修饰;
(4)函数指针(即函数名)是全域的,但这个全域是相对的;
(5)变量的作用域,影响的是编译期。

二、变量的生存期

1.基本概念

生存期,关键在于生死期,和其定义的内存区域有关。
• 定义变量(变量诞生)->申请内存
• 释放内存(系统释放,手动释放)->变量死亡
(1)全局变量、静态全局变量、静态局部变量存放在静态存储区(即全局区),其生存期从定义开始一直到程序运行结束;
(2)局部变量、函数形参存放在栈区,生存期从定义开始一直到所在函数或语句块运行结束;
(3)动态分配的变量存放在堆区,生存期从手动分配开始一直到手动释放结束。
补充:
• 递归的过程并没有代表函数的结束,进去函数后,分配一个栈帧空间。在该函数中递归时,又分配了一个栈帧空间,原先产生栈帧空间不会死亡,这样一直递归一直分配栈帧空间,所以递归的最后会耗尽程序的内存,导致程序崩溃。递归的过程可以很好体现变量的生存期过程,递归的使用会占用程序内存空间,所以要谨慎使用。
test1.c

#include <stdio.h>void func()
{func();
}int main()
{func();return 0;
}

运行结果:
Segmentation fault (core dumped)
• 关于死循环,可以理解为不断刷新内存空间,只会让程序卡主。
test.2

#include <stdio.h>
#include <stdlib.h>void func()
{int a = 1;int *b = (int *)malloc(sizeof(int));printf("%p\t%p\n", &a, &b);//free(b);   //堆内存不释放,死循环也是不断刷新内存空间
}int main()
{while(1){func();}return 0;
}

运行结果:

2.C语言的内存分布

(1)基本概念

对于C语言程序而言,内存空间主要由四个部分组成,有代码段(.text)、全局段(分为DATA段(.data分为.rodata和.rwdata)和BSS段(.bss))、堆和栈。
其中:
• 全局段又称为静态存储段,有时候也称为静态存储区
• 代码段、DATA段、BSS段是编译的时候由编译器分配
• 堆是由程序员手动分配,栈是由系统自动分配。

(2)数据在内存中的分布



• 局部变量、函数形参、函数的返回值分为存放在栈中
• 动态分配的变量都在堆中
• 未初始化的全局变量、静态全局变量、全局变量都存放在静态存储区的BSS段
• 初始化的的全局变量、静态全局变量、全局变量都存放在在静态存储区的DATA段
• 字符串常量存放在在静态存储区的DATA段(.rodata)
• 可执行程序(指令和常量)存放在代码区
代码分析:

int a = 0; //全局初始化区,a的值为0
char *p1;  //全局未初始化区(初始化为NULL)
int main()
{   int b;                  //b分配在栈上,整型  char s[] = "abc";       //s分配在栈上,char *类型;"abc\0"分配在栈上,运行时赋值,函数结束销毁  char *p2;               //p2分配在栈上,未初始化   char *p3 = "123456";    //p3指向"123456"分配在字符串常量存储区的地址,编译时确定 static int c = 0;       //c在全局(静态)初始化区,可以多次跨函数调用而保持原值   p1 = (char *)malloc(10); //p1在全局未初始化区,指向分配得来得10字节的堆区地址   p2 = (char *)malloc(20); //p2指向分配得来得20字节的堆区地址  strcpy(p1, "123456");    //"123456"放在字符串常量存储区,编译器可能会将它与p3所指向的"123456"优化成一块 return 0;
}

注意】现代编译器中关键字const修饰的全局变量、静态局部变量变量和静态全局变量就是存放在DATA段中的只读段,所以这些变量为只读属性,其值通过指针也不可改变。而const修饰的局部变量存放在栈中,可以通过指针改变其值。
想进一步了解const修饰变量概念,点击下面链接:
const定义常量和#define定义常量的区别

3.总结

(1)变量的生存期与变量所处内存区域有关,如存储在静态存储区的变量,生存期期就是从定义开始一直到程序结束;
(2)变量的生存期,本质上就是从变量诞生(变量所处内存分配)到变量死亡(变量所处内存的释放)的整个过程;
(3)变量的生存期,影响的是运行期;

4.补充

(1)光申请不释放->内存泄漏(生存期相关)
(2)已释放再访问->非法访问(比如让关公再给你耍个大刀)
(3)释放已经释放的空间(注意这是通过原有访问方式,其实还是第二个问题)->多重释放(比如我已经有一个房子,卖给了张三,我又把这个房子卖给李四,出错了,但是张三卖给李四不会出错)

C语言中变量的作用域和生存期的区别相关推荐

  1. C语言中变量的作用域和生存期

    几个基本概念 静态存储区: 程序运行期间系统分配的固定的存储空间. 动态存储区: 程序运行期间根据需要进行动态分配的内存空间. 静态存储区和动态存储区都在内存中. 作用域:变量可被使用的范围. 生存期 ...

  2. C语言中变量的作用域

    C语言中变量的作用域 C语言中所有变量都有自己的作用域,申明变量的类型不同,其作用域也不同.C语言中的变量,按照作用域的范围可分为两种, 即局部变量和全局变量. 一.局部变量 局部变量也称为内部变量. ...

  3. c语言变量作用域生命周期,C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期...

    谭浩强书: 从存储模型可以看到,谭浩强和钱能的模型有一定的对应关系: 静态存储区  ->  全局数据区 动态存储区  ->  栈(stack) 变量的类型: 1. 局部变量和全局变量 局部 ...

  4. c语言函数变量的作用域与生存期

    目录 一.作用域与生存期的概念 1.变量的作用域 2.变量的生存期 二.全局变量与局部变量 1.局部变量的作用域与生存期 2.全局变量的作用域与生存期 一.作用域与生存期的概念 1.变量的作用域 在c ...

  5. C语言中变量的作用域和生命周期

    一.作用域和生命周期: 1.作用域: 通常来说,一段程序代码中所用到的名字并不总是有效 / 可用 的.而限定这个名字的可用性的代码范围就是这个名字的作用域.俗话说的好,"能力越大,责任也就越 ...

  6. python中变量的作用域有几种_Python中变量的作用域(variable scope)

    http://www.crifan.com/summary_python_variable_effective_scope/ 解释python中变量的作用域 示例: 1.代码版 #!/usr/bin/ ...

  7. C语言中变量的储存类别

    C语言中变量的储存类别 C语言中变量的储存类别 1.动态存储方式与静态动态存储方式: 从变量值存在的作时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式. 静态存储方式:是指在程序运行期间分 ...

  8. 在c语言中 使用变量的要求,关于C语言中变量的探讨

    摘 要: 在所有的计算机高级语言中,都存在着变量这样一个重要的概念.变量是计算机高级语言程序的重要成分之一.与其他语言中的变量相比,C语言中的变量所包含的内容更为丰富,包括变量的定义.数据类型.变量数 ...

  9. 变量的作用域和生存期

    1.局部变量&全局变量的定义和声明 对于局部变量的定义和声明可以不加区分.对于全局变量,其定义必须在所有函数之外,且只能定义一次,其一般形式为: [extern ] 类型说明符  变量名.. ...

最新文章

  1. php codeigniter 语言,php – codeigniter模板引擎,包括语言解析器
  2. 工程介绍好处费性质_水运工程造价工程师继续教育课件上新丨海外水运工程造价编制介绍课程发布...
  3. python 写文件 换行_Python学习16:读写文件
  4. 具有Overlord的WildFly 8.1中的API管理
  5. java cxf 双向通讯_CXF 在spring boot 2 发布多个服务
  6. AsyncTask理解- Day36or37
  7. 被开除的Roadstar合伙人决定暂不回应,“报销大保健”也能忍?
  8. 把页面分成左右两个,如何实现在左侧点击,链接一个页面到右边的页面
  9. phpcms的增删改查操作整理
  10. 【图像增强】基于matlab区域相似变换函数和蜻蜓算法灰度图像增强【含Matlab源码 089期】
  11. 用C语言读把SGY地震数据读成txt
  12. 实验七:散点图和折线图绘制
  13. Presto查询出现error executing query异常
  14. DataGrip使用技巧
  15. 【AI视野·今日CV 计算机视觉论文速览 第225期】Wed, 23 Jun 2021
  16. 315来了,跨境卖家们赶紧自检容易被维权举报的问题
  17. 斐乐第五家高尔夫独立店东莞开业;康莱德酒店及度假村签约西安、南京和成都三家酒店 | 美通企业日报...
  18. java虚拟机的CAS_Java虚拟机学习(二)
  19. 计算机房况控制功能是,从实际出发加强计算机房的管理和维护-文档资料.docx
  20. 明德学院计算机专业,贵州大学明德学院计算机科学与技术专业2016年在河南理科高考录取最低分数线...

热门文章

  1. 你在用哪种编程字体?
  2. Spring @Retryable 和 @Recover
  3. EDSAC计算机之父——Maurice Wilkes
  4. 计算机专业毕业设计致谢,那些笑哭的毕业论文致谢
  5. 在Ubuntu中使用Tomcat的小tips_codestorm_新浪博客
  6. JSP学生奖学金系统JSP学生评奖评优系统JSP奖学金管理系统 JSP奖学金评定系统
  7. 怎么看apache443端口是否打开_win7如何打开443端口
  8. mysql dbms是什么_DBMS体系结构的三种类型分别是什么
  9. 怎样在word中画横线
  10. 传播动力学--SIR模型及其应用