11.1 存储类别

这一章(12章)的概念比较多.

内容在书12.1章.

1.作用域

对于变量来说,它起作用的范围是有规律的.如果在一个大括号里面被创建,那它的作用域就是这一对大括号内.

想一想下面的代码运行结果是什么.

# include <stdio.h>

int print(void);    
int number = 10;    //====================================1 -> 6
int main(void) {
    int number = 100; //==================================2 -> 5
    int i = 0;
    for(; i < 1; i++) {
        int number = 1000;  //============================3 -> 6
        printf("for循环中的number: %d\n", number); //=====4
    }
    printf("main函数中的number: %d\n", number); //========5
    print();
    return 0;
}

int print(void) {
    printf("print函数: %d\n", number);//=================6 
    return 0;
}

运行结果

for循环中的number: 1000
main函数中的number: 100
print函数: 10

分别解释一下

1 -> 4 这个number在所有函数的前面,所以所有的函数都可以访问到.
       main()中有新定义的number,所以这个number被"覆盖了".
       而print()中没有定义新的number,所以输出的是这个number.
2 -> 5  main()函数中有一个新定义的number,而for循环中的number的作用域仅限for循环范围内.
3 -> 6 这个number的作用域仅限于for循环内.

 

2.链接

2.1 外部链接

 非static,非局部变量,所有文件都可见.

int number = 10; // 外部链接

int main(void) {...}

2.2 内部链接

static,非局部变量,只在本文件可见.

static int number = 10; // 内部链接

int main(void) {...}

2.3 无链接 

 局部变量,只在作用域可见.

int main(void) {
    int number = 100; //无链接
    ...
}

 

3.存储期

存储期描述了通过这些标识符访问的对象的生存周期.

3.1 静态存储期

如果对象具有静态存储期,那它在程序的执行期间一直存在.文件作用域变量具有静态存储期.

对于文件作用域变量,static表示其链接属性而不是存储期.

不论内部链接还是外部链接,所有的文件作用域变量都具有静态存储期.

//均具有静态存储期
int i = 100;
static float f = 2.7;

int main(void) {...}

3.2 线程存储期

用于并发程序设计,程序执行可以被分为多个线程.

被声明线程结束一直存在.

3.3 自动存储期

块作用域变量具有自动存储期.

程序进入这个块时,为这个变量分配内存,这个块运行结束,内存被释放.

而变长数组有些不同.它是从声明到块运行结束.

int main(void) {
    int i = 100; //自动存储期
    return 0;
}

 

4. 自动变量

属于自动存储类别的变量自动存储期,块作用域,无链接.默认情况下,声明在函数头中的任何变量都属于自动存储类别.

 

5. 寄存器变量

存储在CPU寄存器中,速度最快.

与普通变量不同的地方在于,由于是存储在寄存器中,所以寄存器变量无法获取地址.

可以用register修饰,需注意,这只是请求放入寄存器,并不是一定会被放入寄存器.如果未被放入寄存器,就会变成普通的自动变量.但是即使变为普通变量,仍无法对它使用地址运算符.

CPU寄存器空间可能不能容纳过大的数据.

6. 静态变量

"静态"在这里的意思是"变量在内存中原地不动,并不是值不变"(382页).具有文件作用域的变量自动具有静态存储期.

6.1 块作用域静态变量

可以创建具有静态存储期,块作用域局部变量.和自动变量具有相同的作用域,但是程序离开它所在的函数之后,这些变量不会消失.意思就是,这些变量具有块作用域,无链接,但是具有静态存储期.

块中以存储类别说明符static(提供静态存储期)声明这种变量.

下面的number就是这样的变量.

# include <stdio.h>

int print(void);
int main(void) {
    print();
    print();
    print();
    return 0;
}

int print(void) {
    int normal = 5; 
    static int number = 10;
    printf("块作用域的静态变量number: %d\n", number++);
    printf("普通局部变量normal: %d\n", normal++); 
    return 0;
}

运行结果

块作用域的静态变量number: 10
普通局部变量normal: 5
块作用域的静态变量number: 11
普通局部变量normal: 5
块作用域的静态变量number: 12
普通局部变量normal: 5

可以看到,以static修饰的变量number每次调用都会自增1,而普通的变量normal每次都是5,并没有自增.

说明以static修饰的变量整个程序运行期间只会被初始化一次,而普通的变量每次都会被初始化.

 

6.2 外部链接的静态变量

这种静态变量具有文件作用域,外部链接静态存储期.

把变量的定义性声明放在所有函数外面就创建了一个外部变量.

为了指出函数中使用了外部变量,可以使用extern再次声明.

如果一个源代码文件使用的外部变量定义在另一个源代码文件中,则必须使用extern在该文件中再次声明.

int out;      //外部变量,对所有函数可见
int arr[32];  //外部变量,对所有函数可见
extern int o; //如果o被定义在另一个文件中,则extern是必需的.

int main(void) {
    int out;  //局部变量,只在main()可见
    extern int arr[];//extern可选,使用的是外部变量,不必再写数组大小
    return 0;
}

int print(void){...}

 

6.3 内部链接的静态变量

这种变量具有静态存储期,文件作用域内部链接.声明在所有函数的外部.下面代码中的number就是这种变量.

static int number = 10;

int main(void) {...}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值