• 变量类型,变量作用域,变量存储空间,变量生命周期


    变量类型

    常量是不可变的值,可以用宏来定义,比如 #define PI 3.14

    变量的值是可以变化的,由于编程的不同需求,对变量有各种要求,

      比如:变量的生命周期,变量的初始状态,变量的有效区域(作用域),变量的存储地和存储区域的大小。

    为了满足这些不同的编程需求,C语言发明者设置了以下变量:

      1 不同数据类型的变量。比如 char,int,float等。(变量在内存中占用地址大小由数据类型决定)

      2 全局变量

      3 局部变量

      4 静态变量:包括静态全局变量和静态局部变量

      5 寄存器变量

      6 外部变量 

    C语言中,除了基本类型外,开发者可以通过typedef来定义自己需要的数据类型。比如:

      typedef int INT;

      typedef unsigned int UINT;

      typedef struct student

      {

        char *name;

        int age;

      }STUDENT;  

      如果结构体student不用typedef重定义的话,定义结构体变量时:struct student stu1;  

      使用typedef重定义以后,我们只需要STUDENT stu1;即可。

      1 全局变量。在函数外定义,可被所有函数使用。但是在多线程访问时,需要注意多线程安全问题。

      2 局部变量。在函数内部声明。只有在函数执行时,局部变量才存在,函数执行完局部变量就消失。

      3 静态变量。分配在内存中的数据段中,在C程序运行的整个过程中一直保留,静态变量可以定义成静态全局变量和静态局部变量。

        ①静态全局变量在程序的整个运行期间都存储且内存地址不会改变。

        ②静态局部变量只在声明它的函数内有效,且在下一次调用时还保留上次调用结束时的值(只初始化一次)。

      4 寄存器变量。 寄存器变量存放在CPU的寄存器中,使用寄存器变量比内存变量操作速度快得多。

        只有整型和字符型变量可以定义为寄存器变量。比如:

        register int i;

        register char c;

        ①由于CPU中寄存器有限,尽量减少使用寄存器的数量和占用时间,用完马上释放。

        ②寄存器变量不能定义为全局变量,也不能定义在结构体和类中。

        ③如果寄存器已经无可用资源,寄存器变量将转化为普通局部变量。

    extern:

      在大型程序中,会将一个大型的程序分成多个独立的模块和文件分别编译,然后统一链接在一起。为了解决全局变量和函数的共用问题,

    引入了extern关键字。只需要在一个文件中定义全局变量和函数,在另一个文件中要用到这些变量和函数时,只需要将那个文件中的变量和

    函数说明复制过来,然后在前面加上extern就可以。这样就等于告诉编译器,这些变量和函数已经在别的文件中定义。

    变量的存储空间

      代码和数据,都要加载到内存中,才能被运行和访问。X86系统中,内存的有效范围为4GB。

      ①高2GB内存地址为内核空间,用来存放内核的代码和数据

      ②低2GB为用户空间,运行进程的用户态代码,且低2GB的内存是进程私有空间,一个进程不能跨进程访问别的进程空间的用户态地址。

    如图所示,程序在内存中分为如下几部分:

    1 .text 代码段,这段是存放代码的

    2 .rdata 只读数据段,不能修改,存放常量,字符常量,const常量。

    3 .data 数据段 存放已经初始化好的全局变量和静态变量

    4  .bss 存放未初始化的全局变量和静态变量

      PS:.rdata,.data,.bss都是存放数据的段。.rdata段和.data段的值都在编译的时候就确定了,并且将值编译进了

      可执行文件,经过反汇编就可以找到。已初始化的全局变量放在.data段,未初始化的变量放在bss段。

    5 .stack 栈段,栈中存放普通的局部变量(非静态局部变量),形参,返回地址等。栈的大小有限制:

      windows应用层栈大小默认为1MB;普通内核栈的大小是固定的,由系统根据CPU架构决定,X86系统上12KB,X64系统24KB,安腾系统32KB

      Linux应用层栈大小默认为10MB,内核栈大小4KB或8KB

    6 堆: 可以存放任意数据

    综上:

    ①全局初始化变量存放在静态存储区的.data段

    ②全局未初始化变量存放在静态存储区的.bss段

    ③局部变量存放在栈

    ④全局静态变量和局部静态变量存放在静态存储区的.data段和.bss段

    ⑤常量存放在静态区的.rdata段。.rdata区域是只读内存,不能修改

    ⑥寄存器变量存放在寄存器中 (如果寄存器资源不够,还是放在内存中)

    变量的作用域

    变量的作用域指变量能在代码什么地方可以被访问到。

    1 全局变量: 所有程序中的代码都能访问。

      如果全局变量在一个源文件中定义,在另一个源文件中访问,需要用extern关键字导入。多线程访问全局变量注意安全问题

    2 静态全局变量: 在同一个源文件中可以访问,不同源文件不可访问,也不能用extern来导入。

    3 局部变量:只能在函数内部访问

    4 静态局部变量:只能函数内部访问

    5 寄存器变量:只能在函数内部访问

    变量的生命周期

    变量的生命周期是指变量在程序运行期间的有效时间

    1 全局变量:整个程序运行期间有效

    2 静态全局变量:整个程序运行期间有效

    3 局部变量:函数范围内或代码块范围内有效

    4 静态局部变量:整个程序运行期间有效

    5 寄存器变量:函数范围内或代码块范围内有效

      

    习题:分析下列程序中每个变量的存储位置,作用域,与生命周期 
    int a = 0; 
    char *p1; 
    static int x = 10; 
    void main(void) 

        int b = 0; 
        char s[] = "123"; 
        char *p2; 
        char *p3 = "hello, world"; 
        static int c =0; 
        p1 = (char *)malloc(128); 
        p2 = (char *)malloc(256); 
        free(p1); 
        free(p2); 


    分析与解答:下面给出了上面各变量的类型,存储,作用域和生命周期的详细的归纳:
    int a = 0; //全局初始化变量 
    char *p1; //全局未初始化变量 
    static int x = 10;//全局初始化静态变量 
    void main(void) 

        int b = 0; //局部变量 
        char s[] = "123"; //s局部变量,字符数组,用"123"字符串常量进行初始化 
        char *p2; //局部变量 
        char *p3 = "hello, world"; //p3局部变量,字符指针,指向"hello, world"字符串常量 
        static int c =0; //静态局部变量,已初始化 
        p1 = (char *)malloc(128); //p1,p2指向堆 
        p2 = (char *)malloc(256); 
        free(p1); //显示释放p1,p2指向的堆内存 
        free(p2); 

      

  • 相关阅读:
    Windows Intune, 让企业 IT 如履平地
    如何利用 WinDbg 进行双机调试
    微软 Windows Intune 云托管服务试用
    如何安装从 Windows Update 目录下载的驱动程序
    启用特殊池解读 0x000000c5 蓝屏
    C# 配置文件修改的新方法
    Ribbon默认服务器功能区自定义位置
    Update list item using Linq to SharePoint
    TroubleShoot:分配对象查询的问题
    TroubleShoot:C#操作Excel的几个问题
  • 原文地址:https://www.cnblogs.com/fengxing999/p/10956274.html
Copyright © 2020-2023  润新知