码迷,mamicode.com
首页 > 其他好文 > 详细

C之变量属性(五)

时间:2018-04-06 00:16:02      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:C语言   auto   static   register   extern   

        我们知道以在 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 变量的地址。编译如下:

技术分享图片

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

技术分享图片

        我们发现虽然 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;
}

        我们编译得到结果如下:

技术分享图片

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

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


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

C之变量属性(五)

标签:C语言   auto   static   register   extern   

原文地址:http://blog.51cto.com/12810168/2095148

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!