C语言 存储类型关键字详解 | 您所在的位置:网站首页 › c语言存储区域有哪些类型和特点 › C语言 存储类型关键字详解 |
今天我们重点说下auto,register,typedef,extern,和static。 让我们进入今天的学习吧!(今天也要加油哦) 1. auto(自动变量)auto作为比较老的关键字,在C语言中使用的有限,简单说下语法吧。 auto:它很宽宏大量的,你就当它不存在吧,在缺省的情况下所有局部变量都是 auto 的。auto被叫做自动变量,就是变量空间自动申请释放,就是自动变量。 2 . static(静态变量)static修饰的变量时,放在了静态数据区。 在上上篇博客中很详细说了,就不在赘述了。 static常考点 3.register(寄存器变量) 3.1 register语法这个关键字请求编译器尽可能的将变量存在 CPU 内部寄存器中而不是通过内 存寻址访问以提高效率。注意是尽可能,不是绝对。你想想,一个 CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多 register 变量,没有那么多的寄存器让register用。 3.2 寄存器变量可以取地址吗?各位读者大人,想一个问题,那么可以对寄存器变量进行取地址操作吗? 例 1: register a = 10; printf("%p\n", &a); //error C2103 : 寄存器变量上的“&” return 0;这个例子就证明了,register变量不可被取地址,为什么不可以被取地址呢? 因为地址是内存相关的概念,你要取地址也要在内存上取吧,不在内存怎么取地址呢? 举个例子帮助理解下: 这就像一个人开车闯红灯要扣6分,但是人家就没有驾照你咋扣分呢? 3.3什么情况下使用register修饰变量的?1.局部变量,(全局变量会占据寄存器) 2.不会被写入的(一旦写入,就要返回内存,然后再被检测) 3.被高频读写的(高频读写的放入寄存器中,会更容易的让CPU拿到) 3.4 register的变量的细节寄存器变量是可以被赋值的。 例 2: int main() { register a = 10; a = 100; printf("%d\n", a);//100 return 0; }寄存器变量的默认数据类型是int 也可以定义其他类型 例 3: int main() { register char a = 10; a = 100; printf("%d\n", a);//a的类型是 char return 0; } 4.extern(外部存储变量) 4.1 extern作用extern变量称为外部存储变量。extern声明了程序中将要用到但尚未定义的外部变量。通常,在C语言中extern主要负责的再头文件中的全局变量的声明,函数的声明。 4.2 extern的注意事项首先extern声明外部符号的,在头文件中声明函数和全局变量的。 例 4: extern int a; extern void fan();那么再声明时可以初始化吗? 首先声明并非定义,定义时开辟的有空间,而声明中没有空间,所以声明不可以初始化。 声明时可以省略extern吗? 语法上不管是变量还是函数,不加extern好像都不会出错,但是就变量而言定义不初始化和声明是一样的写法 例 5: int a;//声明 int a;//定义但不初始化没有注释,各位读者能分清楚声明和初始化吗?我想不能吧。所以在声明变量时,必须要带上extern。 那么函数呢,是不是可以不带extern呢? 例 6: void fan();//声明 void fan()//定义从直观上是看可以看出来的,以分号结束的是声明,但是还是推荐大家声明函数时也带上extern。 声明可以多次吗? 可以多次声明,但是不可以多次定义。 举个例子: 你买彩票中奖了,你可以说很多次,但是就彩票中奖来说,你只中了一次,同理,声明可以多次,但定义只有一次。 5.typedef(特殊的存储类型) 5.1 typedef解释typedef 的真正意思是给一个已经存在的数据类型(注意:是类型不是变量)取一个别名,而非定义一个新的数据类型。 5.2 typedef的使用5.2.1 对结构体进行typedef 下面是结构体进行重命名之后的类型查看,来进一步判断是否typedef创建了新的类型。 例 7: struct str//定义结构体 { int a; }; typedef struct str _str;//对结构体进行重命名 int main() { struct str ret = { 0 };//创建结构体变量 _str val = { 0 };//用typedef定义类型创建变量 struct str * p = &val;//把typedef的变量地址存进结构体指针中 return 0; }调试查看类型可以看出类型是一样的。 5.2.2 对数组进行typedef 例 8: typedef int a[10];//定义一个类型 int[10] 名字是a int main() { int b[10] = { 0 };//定义一个数组,数组类型是 int[10] a c = { 0 };//用a定义一个数组,数组类型是a return 0; }调试,查看类型,看出,a和b数组类型一样。 5.2.3 typedef对unsigned int重命名。 例9 : typedef unsigned int _int; int main() { unsigned int a = 0; _int b = 0; return 0; }调试看出,a,b类型一样 综上所述,可以看出typedef只是换了个名字,但是最终类型不变,有种换汤不换药的感觉。 5.3 typedef 和 define做比较看个例子加深下理解 例 10: typedef int* ptr_t; int main() { ptr_t a, b;//没初始化,不推荐大家写,只做研究 return 0; }这里看出typedef定义两者的类型是一样的。 例 10: #define PTR_T int* int main() { PTR_T a, b;//不推荐这样写,只做研究 return 0; }define定义的可以看出不是一个类型,a是int*的,b是默认的int型。 得出结论 define 是定义一个宏来进行替换。 而typedef是把一个变量的名字换了。 6.总结存储类型关键字这些存储类型关键字,上述也都说过了,他们或多或少的对一些变量或者函数的说呢过命周期和作用域,以及变量开辟空间相关,还有一个比较特殊的关键字typedef也归结到了存储类型关键字了。 重点来了 这些存储类型关键字不可以同时修饰一个变量 这是不可以的,数据只有一个存储类型,一个以上出现是不可以的。 下期预告下期讲下volatile和sizeof,各位看官明天见 都看到这里了,给个三连吧 |
CopyRight 2018-2019 实验室设备网 版权所有 |