C和指针之auto和内存栈和register关键字

来源:互联网 发布:飞科剃须刀怎么样 知乎 编辑:程序博客网 时间:2024/05/22 07:30

1、auto

在C代码中每个函数都有其生命周期(也称作用域),在函数生命周期中声明的变量通常叫做局部变量,也叫自动变量。例如:
复制代码代码如下:
    int chenyu(){            int a = 10;      // auto int a = 10;             return 0;      }  
 
整型变量a在fun函数内声明,其作用域为chenyu函数内,在chenyu函数外面不能被引用,a变量为自动变量。也就是说编译器会有int a = 10之前会加上auto的关键字。
auto的出现意味着,当前变量的作用域为当前函数或代码段的局部变量,意味着当前变量会在内存栈上进行分配。







2、内存栈

栈(我们知道先进后出的特点



栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的,当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
然后理解函数里面的局部变量如下
一个程序中可能会有大量的变量声明,每个变量都会占有一定的内存空间,而内存空间对于计算机来说是宝贵的硬件资源,因此合理的利用内存是编译器要做的一个主要任务。有的变量是一次性使用的,如局部变量。有的变量要伴随着整个程序来使用的,如全局变量。为了节省内存空间,优化性能,编译器通常会将一次性使用的变量分配在栈上。也就是说,代码中声明一个一次性变量,就在栈上进行入栈操作。当该变量使用完了(生命周期结束),进行出栈操作。这样,在执行不同的函数的时候,就会在一个栈上进行出入栈操作,也就是说它们在频繁的使用一个相同的内存空间,从而可以更高效的利用内存


比如函数
#include <stdio.h>void f(){   int a = 1;   int b = 2;}void f1(){   int c = 3;   int d = 4;}int main(){    f();    f1();    return 0;}
执行f()函数的时候,变量a进入内存栈,然后b再进内存栈
1、执行f()函数,局部变量进栈
变量名b, 值是1
变量名a, 值是2
栈底

2、出栈,清空栈
3、执行f1()函数,局部变量进栈
变量d,值是4
变量c,值是3
栈底
4、出栈,清空栈




3、register关键字

先了解内存、寄存器、cpu他们3者之间的关系
程序代码保存在内存中,数据从他这拿出来。送到寄存器(这里先不考虑CPU 的高速缓存区)。数据从内存里拿出来先放到寄存器,然后CPU 再从寄存器里读取数据来处理,处理完后同样把数据通过寄存器存放到内存里,CPU 不直接和内存打交道,寄存器其实就是一块一块小的存储空间,只不过其存取速度要比内存快得多

我们可以使用register关键字修饰 经常容易使用的全局变量
register int a;

注意:
待声明为寄存器变量类型应该是CPU寄存器所能接受的类型,意味着寄存器变量是单个变量,变量长度应该小于等于寄存器长度,不能对寄存器变量使用取地址符“&”,因为该变量没有内存地址,尽量在大量频繁的操作时使用寄存器变量,且声明的变量个数应该尽量的少
 register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它累死也可能不能全部把这些变量放入寄存器吧,轮也可能轮不到你。





原创粉丝点击