【C语言必经之路——第1节】自动变量(auto)外部变量(extern)静态变量(static)寄存器变量(register)

目录

一、auto变量

二、extern变量

三、static变量

static的作用为:

1.修饰全局变量

2.修饰局部变量

3.修饰函数

四、register变量

1、寄存器的认识

2、寄存器存在的本质

3、什么变量可以放在寄存器中(什么变量可以被register修饰)

4、register变量要注意什么

5、笔者建议


一、auto变量

若定义一个局部变量为自动变量,这意味着每次执行到定义该变量都回产生一个新变量,并对他重新初始化。这里的auto可以省略,如果不特定指明,局部变量的存储方式默认为自动的。

int fun(int a)
{
    auto int b,c;
    /*    此处省略内容     */
}

这个函数中a为形参,b,c为自动变量,执行fun函数后,自动释放a,b,c所占的存储单元。

二、extern变量

如果某全局变量(注意只有全局变量才可以在外部使用)或函数在同时编译的其他源文件中已经定义,当在当前源文件中这个变量或函数被extern修饰,则表明从声明开始就可以合法的在当前源文件中使用该变量或函数了。

例:

/*file1.c */


int x = 1;
int fun();

int fun()
{
    /*此处省略函数内容*/
}





/* file2.c */



extern int x;        /*该变量是已经在file1.c文件中定义,这里只需声明*/
extern int fun();   /*该函数是已经在file1.c文件中定义,这里只需声明*/

int main()
{
    printf("x = %d",x);
    fun();
    return 0;
}

三、static变量

可以想成static变量就是“专一”的,当用static声明变量后,该变量的始终保持他的值,初始化操作只在第一次起作用。

static的作用为:

1.修饰全局变量

全局变量是具有外部链接属性的,static修饰全局变量后,将外部链接属性变成了内部链接属性,此时的全局变量只能在自己所在的.c文件中使用,其他文件中无法链接使用,这样给我们的感觉是影响了变量的作用域。(代码演示如下)

 

2.修饰局部变量

static修饰局部变量的时候改变了这个变量的生命周期。但是,不影响作用域
static修饰局部变量,是改变了变量的存储类型本来局部变量是放在栈区的,被static修饰后存放内存的静态区了,因为存储类型的改变,从而导致生命周期变长。

  上述两图不同的是a变量有没有被static修饰,如果修饰了,则a就被改变到存放在静态区,使得a变量的生命周期改变。

3.修饰函数

函数是具有外部链接属性的,static修饰全局变量后,将外部链接属性变成了内部链接属性,此时的该函数只能在自己所在的.c文件中使用,其他文件中无法链接使用(下面两个代码对比如下) 

 

这里补充一下内存中的变量存储方式,内存分三块区域,栈区,堆区,静态区。对应的存储数据类型如下图所示。

特殊说明:如果在定义局部变量时不赋初值的话,则对于静态局部变量来说编译时自动赋初值0(对数值型变量)或空字符(对字符变量)

四、register变量

1、寄存器的认识

计算机中CPU主要是负责进行计算的硬件单元,但是为了方便运算,一般第一步需要先把数据从内存读取到CPU内,那么也就需要CPU具有一定的数据临时存储能力。注意:CPU并不是当前要计算了,才把特定数据读到CPU里面。所以现代CPU内,都集成了一组叫做寄存器的硬件,用来做临时数据的保存。计算机中的存储硬件,离CPU越近速度越快。在计算机运算中为了提高效率,允许将变量的值放在CPU中的寄存器中,这种变量叫“寄存器变量”,用关键字register来声明。

总结一句就是寄存器是集成在CPU内部的存储硬件

2、寄存器存在的本质

由于不需要从内存读取数据,这样在硬件层面提高了计算机的运算效率。

3、什么变量可以放在寄存器中(什么变量可以被register修饰)

1.局部变量(全局变量会导致CPU寄存器被长时间占用)
2.不会被写入的变量(当变量需要写入就要写回内存,后续还要读取,这样就没必要了)
3.高频被读取的(这样可以提高效率)

4、register变量要注意什么

1.如果要使用,不要大量使用,因为寄存器数量有限
2.register修饰的变量,不能取地址(因为已经放在寄存器中了,寄存器中式不存在地址的,地址是内存相关的概念)

 可以看到当想要计算register修饰的变量的地址时,出现了一个报错。

5、笔者建议

虽然寄存器的速度非常快,但是使用register修饰符也有些限制的,所修饰的变量必须是能被CPU寄存器所接受的类型。这意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度。而且之前都是需要人为指定register,来进行手动优化,现在的编译器远远比之前的编译器智能化,能够进行很多代码优化。几乎可以不理睬“register”这一关键字。

在日常工作学习中一般不会定义寄存器变量,这是因为一些变量需要多次参加计算而编译器却把这个变量转化成寄存器变量,从而程序员无法对寄存器变量的地址进行操作。register变量对于初学者来说仅作了解即可。

  • 24
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故里♡9513

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值