• C语言变量属性


    变量属性

    C语言中的变量可以有自己的属性,在定义变量的时候可以加上"属性"关键字。

    属性关键字指明变量的特殊意义。

    auto关键字

    • auto是C语言中局部变量的默认属性。
    • auto表明将被修饰的变量存储于栈上
    • 编译器默认所有的局部变量都是auto的。

    代码示例

    void f()
    {
        int i; // 局部变量默认属性为auto
        auto int j; // 显示声明auto属性
    }
    

    register关键字

    • register关键字指明将局部变量存储于寄存器中
    • register只是请求寄存器变量,但是不一定请求成功。
    • register变量必须是CPU寄存器可以接受的值。
    • 不能用&运算符获取register变量的地址。

    代码示例

    #include <stdio.h>
    register int g_v; // error
    int main()
    {
        register char var;
        print("8x%88x", &var) // error
        return 0;
    }
    

    static关键字

    1、static关键字指明变量的静态属性。

    static修饰的局部变量存储在程序静态区。
    

    2、static关键字同时具有作用域限定符的意义。

    static修饰的全局变量作用域只是声明的文件中。
    static修饰的函数作用域只是声明的文件中。
    

    代码示例

    #include <stdio.h>
    int g_v; // 全局变量,程序的任意地方均能访问
    static int g_vs; // 静态全局变量,只有当前文件中可以访问。
    
    int main()
    {
        int var; // 局部变量,在栈上分配空间。
        static int var; // 静态局部变量,在静态数据区分配空间。
        
        return 0;
    }
    

    实例分析

    #include <stdio.h>
    
    // 定义f1函数
    int f1()
    {
        int r = 0;
        
        r++;
        return r;
    }
    
    // 定义f2函数
    int f2()
    {
        static int r = 0;
        r++;
        return r;
    }
    
    
    int main()
    {
        auto int i = 0;       // 显示声明 auto 属性,i 为栈变量
        static int k = 0;     // 局部变量 k 的存储区位于静态区,作用域位于 main 中
        register int j = 0;   // 向编译器申请将 j 存储于寄存器中
    
        printf("%p
    ", &i);
        printf("%p
    ", &k);
        printf("%p
    ", &j);   // error
        
        for(i=0; i<5; i++)
        {
            printf("%d
    ", f1());
        }
        
        for(i=0; i<5; i++)
        {
            printf("%d
    ", f2());
        }
        
        return 0;
    }
    

    图示:

    extern关键字

    extern用于声明“外部”定义的变量和函数。

    • extern变量在文件的其他地方分配空间。
    • extern函数在文件的其他地方定义。

    代码示例

    #include <stdio.h>
    
    extern int getI();
    
    int main()
    {
        printf("%d
    ", getI());
           
        return 0;
    }
    
    static int g_i;
    
    int getI()
    {
        return g_i;
    }
    

    const关键字

    const只读变量

    • const修饰变量是只读的,本质上还是变量。
    • const修饰的局部变量在栈上分配空间。
    • const修饰的全局变量在全局数据区分配空间
    • const只是在编译期有用,在运行其无效果。

    注意

    const修饰的变量不是真正的常量,他只是告诉编译器该变量不能出现在赋值符号的左边。
    

    const全局变量的分歧

    1、在现代C语言编译器中,修改const全局变量将导致程序崩溃。

    2、标准C语言编译器不会将const修饰的全局变量存储于只读存储区中,而是存储于可修改的全局数据区,其值依然可以改变。

    代码示例

    #include <stdio.h>
    
    // 定义全局变量
    const int g_cc = 2;
    
    int main()
    {
        const int cc = 1;
    
        printf("cc = %d
    ", cc);
    
        // 通过指针修改内存空间的地址
        int* p = (int*)&cc;
        
        *p = 3;
        
        printf("cc = %d
    ", cc);
    
        
        p = (int*)&g_cc;
        
        printf("g_cc = %d
    ", g_cc);
    
        // 修改内存空间
        *p = 4;
        
        printf("g_cc = %d
    ", g_cc);
        
        return 0;
    }
    

    const的本质

    • C语言中的const使得变量具有只读属性。
    • 现代C编译器中的const将具有全局生命周期的变量存储于只读存储区。
    • const不能定义真正意义上的常量。

    代码示例

    #include <stdio.h>
    
    // 定义一个const类型的全局数组
    const int g_array[5] = {0};
    
    // 定义modify函数
    void modify(int* p, int v)
    {
        *p = v;
    }
    
    int main()
    {
        int const i = 0;
        const static int j = 0;
        int const array[5] = {0};
        
        modify((int*)&i, 1);           // ok
        modify((int*)&j, 2);           // error
        modify((int*)&array[0], 3);    // ok
        modify((int*)&g_array[0], 4);  // error
        
        printf("i = %d
    ", i);
        printf("j = %d
    ", j);
        printf("array[0] = %d
    ", array[0]);
        printf("g_array[0] = %d
    ", g_array[0]);
        
        return 0;
    }
    
  • 相关阅读:
    JS 删除web sql 数据表
    JS 新建web sql 数据表
    JS 更新web sql 数据表的数据
    JS 删除一行web sql 数据表的数据
    JS 向web sql数据表插入数据
    JS 打开or连接web sql数据库
    JS 获取表单数据存入数组
    JS 限制小数点位数
    JS 通过id获取DOM对象--减少代码
    mvc “System.NullReferenceException”类型的异常在 App_Web_zo44wdaq.dll 中发生,但未在用户代码中进行处理 其他信息: 未将对象引用设置到对象的实例。
  • 原文地址:https://www.cnblogs.com/Guard9/p/12905118.html
Copyright © 2020-2023  润新知