5_变量属性

作者: 编程半岛 | 来源:发表于2018-03-01 20:23 被阅读0次

关键词:C语言的变量属性、auto关键字、 register关键字、 static关键字、extern关键字

1. C语言的变量属性

  • C语言中的变量可以有自己的属性,在定义变量的时候可以加上属性关键字属性关键字指明变量的特有意义。
  • 语法:property type var_name;
  • 示例:
int main()
{
  auto char i;
  register int j;
  static long k;
  extern double m;

  return o;
}

2. auto关键字

  • auto即C语言中局部变量的默认属性
  • auto表明将被修饰的变量存储于栈上
  • 编译器默认所有的局部变量都是auto
    示例:
void f()
{
  int i;  // 局部变量默认属性为 auto

  auto int j;  // 显示声明 auto 属性 
}

3. register关键字

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

示例:


#include <stdio.h>

   register int g_v; // error: register name not specified for ‘g_v’

int main()
{
    register char var;
    
    printf("0x%08x\n", &var);   // error: address of register variable ‘var’ requested

    return 0;
}

4. static关键字

  • static关键字指明变量的静态属性
    static修饰的局部变量存储在程序静态区,即局部变量未被static修饰时,变量位于栈空间,局部变量被static修饰后,变量位于静态区这个局部变量的生命周期和全局变量的生命周期相同,作用域只在局部区域

  • static关键字同时具有作用域限定符的意义
    static修饰的全局变量作用域仅在声明的文件中
    static修饰的函数作用域仅在声明的文件中

#include <stdio.h>

int g_v;            // 全局变量, 程序的任意地方均能访问

static int g_sv;    // 静态全局变量, 只有当前文件中可访问

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

    return 0;
}

5. autoregisterstatic对比分析

#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: address of register variable ‘j’ requested 
    
    for(i=0; i<5; i++)
    {
        printf("%d\n", f1());   
    }
    
    for(i=0; i<5; i++)
    {
        printf("%d\n", f2());   
    }
    
    return 0;
}

输出结果:

0xbfdeb84c
0x804a01c
1
1
1
1
1
1
2
3
4
5

总结:
auto修饰的变量i的地址值为:0xbfdeb84c,static修饰的变量j的地址值为:0x804a01c。两地址值相差较大的原因是因为变量i位于栈空间,变量j位于常量区
f1()中的变量r位于栈空间,每次调用时被初始化为0,f2()中的变量r位于静态区,只被初始化一次,r的生命周期为程序的运行周期,每次对它的改动都会被保留下来。

6. extern关键字

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

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

7. staticextern的使用

test.c

#include <stdio.h>

extern int g_v; // 告诉编译器变量g_v在其他地方已经定义

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

g.c

int g_v = 10;   // 定义全局变量 g_v
输出结果:
  • g.c中用static修饰后,源代码如下:
static int g_v = 10;    // 定义全局变量 g_v
输出结果:

错误原因:static修饰的全局变量作用域仅在声明的文件中,其它文件访问不到,因此在test.c中编译器会提示g_v没有定义。解决方法:
test.c

#include <stdio.h>

extern int getV();  // 告诉编译器函数getV()在其他地方已经定义

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

g.c

static int g_v = 10;    // 定义全局变量 g_v

int getV()
{
    return g_v;
}
输出结果:

8. 小结

  • auto变量存储在程序的中,为默认属性
  • static变量存储在程序静态区
  • register变量请求存储于CPU寄存器
  • extern变量在文件的其它地方分配空间
  • extern能够指示编译器按照C方式编译程序

声明:此文章为本人在学习狄泰软件学院《C语言深度解析》所做的笔记,文章中包含狄泰软件资料内容一切版权归狄泰软件所有!

相关文章

  • 5_变量属性

    关键词:C语言的变量属性、auto关键字、 register关键字、 static关键字、extern关键字 1....

  • swift - 属性

    /*• 存储属性• 计算属性• 属性观察器• 全局变量和局部变量• 类型属性*/

  • 属性

    属性 存储属性 计算属性 属性观察器 全局变量和局部变量 类型属性 存储属性 FixedLengthRange的实...

  • 2020-04-05 KVC

    课程引入:成员变量、实例变量、属性,区别是什么?---分类不能添加实例变量 成员变量 -- 实例变量 -- 属性 ...

  • iOS 基础知识总结 更新中...

    属性 属性与成员变量之间的关系 属性对成员变量扩充了存储方法 属性默认会生成带下划线的成员变量 声明了成员变量不会...

  • 变量、属性

    一、数字加单引号和不加单引号结果都一样 var a=12; var a=‘12’...

  • 面向对象

    对象:某一个具体的东西 类:类别,一类东西 变量和属性变量就是属性,属性就是变量,只是叫法不同变量是自由的属性是属...

  • Python实例变量和类变量

    Python实例变量和类变量 类变量(类属性): 类变量属于类所有,所有实例共享一个变量 实例变量(实例属性) 实...

  • 开发问题笔记(十八)

    目录 1.iOS中各种变量的区别(成员变量、属性变量、局部变量..) 1.iOS中各种变量的区别(成员变量、属性变...

  • JavaScript01

    CSS变量 用法: --变量名 引用变量var(--变量名)变量只能用作属性值,不能用作属性名.:root 伪类 ...

网友评论

    本文标题:5_变量属性

    本文链接:https://www.haomeiwen.com/subject/dnzgxftx.html