温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C之变量属性(五)

发布时间:2020-07-04 11:47:01 来源:网络 阅读:790 作者:上帝之子521 栏目:编程语言

        我们知道以在 C 语言中的变量有自己的属性,只要在定义变量的时候加上“属性”关键字即可。“属性”关键字指明变量的特有意义。

        语法:property type var_name;比如:auto int i; register int j;extern float k;static double m;

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

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

        static 关键字:指明变量的“静态”属性,static 修饰的局部变量存储在程序静态区;它同时具有“作用域限定符”的意义,static 修饰的全局变量作用域只是声明的文件中,修饰的函数作用域只是在声明的文件中。

        下来我们做个实验分析下,代码如下:

#include <stdio.h>

int f1()
{
    int r = 0;
    
    r++;
    
    return r;
}

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\n", &i);
    printf("%p\n", &k);
    printf("%p\n", &j);   // error
    
    for(i=0; i<5; i++)
    {
        printf("%d\n", f1());
    }
    
    printf("\n");
    
    for(i=0; i<5; i++)
    {
        printf("%d\n", f2());
    }
    
    return 0;
}

         我们可以看出第 30 行代码会出错,因为不能用 &  运算符获取 register 变量的地址。编译如下:

C之变量属性(五)

        我们注释掉那行代码之后,再次编译,得到结果如下:

C之变量属性(五)

        我们发现虽然 i 和 k 是挨着定义的,但是因为属性不同,所以他俩的地址也差的好大。再接着看 f1() 和 f2() 基本上都差不多,但是打印结果却差别很大呢?仔细看看在 f2() 中,我们加了 static 关键字。也就是说 f1() 中的 r 是局部变量,在每次执行循环的时候都要进行初始化为0,所以打印五次结果都为 0;但 f2() 不同,r 前面加有 static,所以其相当于全局变量,在循环时只进行一次的初始化,后面的循环便依次加一了。

        接下来我们来介绍 extern 关键字:它是用于声明“外部”定义的变量和函数,extern 变量在文件的其他地方分配空间extern 函数在其他地方定义;它用于“告诉”编译器用 C 的方式进行编译,C++ 编译器和一些变种 C  编译器默认会按“自己”的方式编译函数和变量,通过 extern C 关键字可以命令编译器“以标准 C 方式进行编译”。

        下来我们就来验证下,代码如下:

#include <stdio.h>

extern int getI();

int main()
{
    printf("%d\n", getI());
       
    return 0;
}

        g.c 代码如下:

static int g_i;

int getI()
{
    return g_i;
}

        我们编译得到结果如下:

C之变量属性(五)

        虽然我们没在 test.c 文件中定义 getI(),但是我们在 main() 之前进行 extern 声明,编译器在编译到这时会先向下编译然后再 g.c 文件中进行寻找。最后成功执行 getI(),getI() 返回的是一个 static 修饰的全局变量,默认为 0。所以最后结果为 0。

        那么我们本次学习了变量的属性,auto 变量存储在程序的栈中,默认属性;static 变量存储在程序静态区中;register 变量请求存储于 CPU 寄存器中;extern 变量在文件的其他地方分配空间,extern 能够指示其他编译器按照标准 C 方式编译程序。


        欢迎大家一起来学习 C 语言,可以加我QQ:243343083

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI