05-变量属性

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:ubuntu 14.04

GCC版本:4.8.4

 

一、C语言的变量属性

* C语言中的变量可以有自己的属性

* 在定义变量的时候可以加上“属性”关键字

* “属性”关键字指明变量的特有意义

语法:
    property type var_name;
示例:
    int main()
    {
        auto char i;
        register int j;
        static long k;
        extern double m;

        return 0;
    }

 

二、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;
    printf("0x%08X\n", &var);    //error,不能取地址

    return 0;
}

    

         register为了最大限度提高代码速率,被register修饰的变量不能用&运算符获取地址。

 

四、static关键字

* static关键字指明变量的“静态”属性

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

* static关键字同时具有“作用域限定符”的意义

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

   - static修饰的函数作用域只是声明的文件中

#include <stdio.h>
int g_v;    //全局变量,程序的任意地方均能访问
static int g_vs;    //静态全局变量,只有当前文件中可访问

int main()
{
    int var;            //局部变量,在栈上分配空间
    static int svar;    //静态局部变量,在静态数据区分配空间

    return 0;
}

 

实例分析
auto,register,static对比分析
5-1.c
#include <stdio.h>

int f1()
{
    int r = 0;    //r为局部变量,被分配在栈上,当函数执行完毕后,栈会弹出局部变量r,因此每次函数运行结束r=1
    r++;            

    return r;
}

int f2()
{
    static int r = 0;    //static修饰的变量被存储在静态存储区,因此函数退出时,在此运行时r++会累加
    r++;    
    
    return r;
}

int main()
{
    auto int i = 0; //显示声明auto属性,i为栈变量
    static int k = 0;    //局部变量k的存储区位于静态区
    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());
    }

    for(i=0; i<5; i++)
    {
        printf("%d\n", f2());
    }

    return 0;
}

操作:

a.gcc 5-1.c -o 5-1.out编译报错,提示:

5-1.c:27:2: error: address of register variable ‘j’ requested
  printf("%p\n", &j);
错误:获取寄存器变量“i”地址

b.注释掉main()函数中:

//printf("%p\n", &j);   // error

编译通过,打印:

0x0027F934
0x00318158
1
1
1
1
1
1
2
3
4
5

分析:

        局部变量出栈后会被销毁,静态变量声明周期是整个程序运行周期。

 

五、extern关键字

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

  - extern变量在文件的其它地方分配空间

  - extern函数在文件的其它地方定义

 

* extern用于“告诉”编译器用C方式编译

        C++编译器和一些变种C编译器默认会按“自己”的方式编译函数和变量,通过extern关键字

可以命令编译器“以标准C方式进行编译”。

extern "C"
{
    int f(int a, int b)
    {
        return a + b;
    }
}

 

编程实验
static和extern的使用
5-2.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;
}

操作:

a. gcc 5-2.c g.c -o 5-2.out编译正确,打印结果:

0

 

小结:

* auto变量存储在程序的栈中,默认属性

* static变量存储在程序静态区中,使用完毕后数据不销毁

* register变量请求存储于CPU寄存器中

* extern变量在文件的其它地方分配空间

* extern能够指示编译器按照标准C方式编译程序

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值