C语言重点难点精讲第一部分关键字:第一节-关键字分类细讲
Posted 快乐江湖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言重点难点精讲第一部分关键字:第一节-关键字分类细讲相关的知识,希望对你有一定的参考价值。
文章目录
一般来讲,C语言一共有32个关键字(C90
标准),当然C99
后又新增了5个关键字,不过我们还是重点讨论这32个关键字
关键字 | 说明 |
---|---|
auto | 声明自动变量 |
short | 声明短整型变量或函数 |
int | 声明整形变量或函数 |
long | 声明长整形变量或函数 |
float | 声明浮点型变量或函数 |
double | 声明双精度变量或函数 |
char | 声明字符型变量或函数 |
struct | 声明结构体变量或函数 |
union | 声明共用数据类型 |
enum | 声明枚举类型 |
typedef | 用以给数据类型取别名 |
const | 声明只读变量 |
unsigned | 声明无符号类型变量或函数 |
signed | 声明有符号类型变量或函数 |
extern | 声明变量是在其它文件中正声明 |
register | 声明寄存器变量 |
static | 声明静态变量 |
volatile | 说明变量在程序执行过程中可以被隐含地改变 |
void | 声明函数无返回值或无参数,声明无类型指针 |
if | 条件语句 |
else | 条件语句否定分支(与if连用) |
switch | 用于开关语句 |
case | 开关语句分支 |
for | 一种循环语句 |
do | 循环语句的循环体 |
while | 循环语句的循环条件 |
goto | 无条件跳转语句 |
continue | 结束当前循环,开始下一轮循环 |
break | 跳出当前循环 |
default | 开关语句中的“其它”分支 |
sizeof | 计算数据类型长度 |
return | 子程序返回语句,循环条件 |
一:auto关键字
一般来说,在代码块中定义的变量(也即局部变量),默认都是auto修饰的,不过会省略。但是一定要注意:不是说默认的所有变量都是auto的,它只是一般用来修饰局部变量
当然在C语言中,我们已经不再使用auto了,或者称其为过时了,但是在C++中却赋予了auto新的功能,它变得更加强大了。有兴趣请点击2-6:C++快速入门之内联函数,auto关键字,C++11基于范围的for循环和nullptr
二:register关键字
register意味寄存器
(1)存储器分级
这个概念我们在计算机组成原理中讲得已经非常详细了,请点击:(计算机组成原理)第三章存储系统-第一节:存储器分类、多级存储系统和存储器性能指标
(2)register修饰变量
可以看出,如果将变量放到寄存器中,那么效率就会提高。可以用register修饰的变量有以下几种
- 局部的(全局变量会导致CPU寄存器长时间被占用)
- 不会被写入的(写入的话就需要被写回内存,要是这样的话register就没有意义的)
- 高频需要被读取的
如果要使用,不要大量使用,因为寄存器的数量有限。
另外还需要注意的一点是:被register修饰的变量,是不能取地址的,因为它已经放在了寄存器中,地址会涉及到内存,但是可以被写入
当然这个register关键字现在也基本不会用了,因为如今的编译器优化已经很智能了,不需要你自己手动优化
三:static关键字
(1)修饰全局变量和函数
我们知道全局变量(加入关键字extern
声明)和函数都可以跨文件使用的
但是有一些应用场景中,我们不想让全局变量或函数跨文件访问应该怎么办呢?那么就可以使用static
关键字
static int g_value=100;//修饰staic后全局变量将不能跨文件使用
可以看出被static
修饰的全局变量是不能被外部其他文件直接访问的,而只能在本文件内使用
- 需要注意这里说的是直接访问,那意味着可以间接访问,比如通过函数的方式实现
同样,被static
修饰的函数只能在本文件内访问,而不能在外部其它文件中直接访问
- 还是需要注意,这里是不能直接访问,并不是不能访问,比如可以通过函数嵌套的方式
static这种功能本质为了封装,因为我们可以把一些不需要或者不想要暴露的细节保护起来了,只提供一个功能函数个,该函数在内部调用它们即可,这样的话代码安全性也比较高
(2)修饰局部变量
我们知道全局变量仅在当前代码块内有效,代码块结束之后局部变量会自动释放空间,因此下面代码的结果就会是这样
如果使用static
修饰局部变量,会更改其生命周期,但其作用域不变,如下当用static修饰后,变量i地址不变,且结果累加
static
为什么可以更改局部变量的生命周期呢?因为被static修饰的变量会将其从栈区移动到数据段,当然这就涉及到了C/C++地址空间的问题了
查看实际地址
#include <stdio.h>
#include <stdlib.h>
int gobal_val=100;//全局变量已经初始化
int gobal_unval;//全局变量未初始化
int main(int argc,char* argv[],char* env[])
{
printf("main函数处于代码段,地址为:%p,十进制为:%d\\n",main,main);
printf("\\n");
printf("全局变量gobal_val,地址为:%p,十进制为:%d\\n",&gobal_val,&gobal_val);
printf("\\n");
printf("全局变量未初始化gobal_unval,地址为:%p,十进制为:%d\\n",&gobal_unval,&gobal_unval);
printf("\\n");
char* mem=(char*)malloc(10);
printf("mem开辟的堆空间,mem是堆的起始地址,是%p,十进制为:%d\\n",mem,mem);
printf("\\n");
printf("mem是指针变量,指针变量在栈上开采,其地址为%p,十进制为:%d\\n",&mem,&mem);
printf("\\n");
printf("命令行参数起始地址:%p,十进制为:%d\\n",argv[0],argv[0]);
printf("\\n");
printf("命令行参数结束地址:%p,十进制为:%d\\n",argv[argc-1],argv[argc-1]);
printf("\\n");
printf("第一个环境变量的地址:%p,十进制为:%d\\n",env[0],env[0]);
printf("\\n");
}
四:sizeof关键字
sizeof
用于确定一种类型对应在开辟空间的时候的大小,注意它是关键字而不是函数
它的基本用法就是下面这样,这我就不再多说了(注意Windows32位平台)
int main()
{
cout <<"char:" <<sizeof(char) << endl;
cout << "short:" << sizeof(short) << endl;
cout << "int:" << sizeof(int) << endl;
cout << "long:" << sizeof(long) << endl;
cout << "long long:" << sizeof(long long) << endl;
cout << "float:" << sizeof(float) << endl;
cout << "double:" << sizeof(double) << endl;
}
特别注意,sizeof
求一种类型大小的写法共有三种,特别第三种很多人认为是错误的,而考试就爱给你整这些犄角旮旯的东西
int main()
{
int a = 10;
第一种:cout << sizeof(a) << endl;
第二种:cout << sizeof(int) << endl;
第三种:cout << sizeof a << endl;//这种写法其实也证明了sizeof不是函数
cout << sizeof int << endl;//注意这种写法是错误的
}
五:signed、unsigned关键字
这一部分需要涉及数据存储及原码反码等基础概念,请参照以下章节
第一点: 需要深刻理解signed
和unsigned
只是对数据的一种解读方式,其中signed
会把首位数据解读为符号位,符号位用于标识其正负,unsigned
的首位也算作数据位,也就是说类型决定了其读写的时候的解释方式
因此像下面的这样一句代码,看似不合适,但是它是没有问题的,因为存储时对于变量a它只关心我所开辟的空间上的二进制数据放进了没有,并不关心你之前是怎么样的
unsigned int b=-10;
-10的原码:1000 0000 0000 0000 0000 0000 0000 1010
-10的反码:1111 1111 1111 1111 1111 1111 1111 0101
-10的补码:1111 1111 1111 1111 1111 1111 1111 0110
也就是说b里面的存储的内容会按照不同的解释方式而变化
以上是关于C语言重点难点精讲第一部分关键字:第一节-关键字分类细讲的主要内容,如果未能解决你的问题,请参考以下文章