zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    error: device not found
    xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Deve
    联想X系列服务器
    华为服务器
    linux db2升级
    aix6.1升级openssh&&openssl
    upgrading mysql: error: 1102: Incorrect database name
    linux7配置yum网络源
    How to install fixpack on DB2
    mysql 表空间管理
  • 原文地址:https://www.cnblogs.com/Guard9/p/12905118.html
Copyright © 2011-2022 走看看