C语言——关键字
宗旨:技术的学习是有限的,分享的精神是无限的。
【谨记:尽量不要用printf函数,要去看变量的值,内存的值。】
auto,int,double,long,char,float,short,signed,unsigned,struct,union,enum,static,switch,case,default,break,register,const,volatile,typedef,extern,return,void,continue,do,while,if,else,for,goto,sizeof。
【定义和声明:定义创建了对象并为这个对象分配了内存,声明没有分配内存。】
auto //声明自动变量,缺省时编译器一般默认为auto
int //声明整型变量double //声明双精度变量long //声明长整型变量char //声明字符变量float //声明浮点型变量short //声明短整型变量signed //声明有符号类型变量unsigned //声明无符号类型变量struct //声明结构体变量union //声明联合类型数据enum //声明枚举类型static //声明静态变量switch //用于开关语句case //开关语句分支default //开关语句中的其他分支break //跳出当前循环register //声明寄存器变量const //声明只读变量volatile //说明变量在程序执行中可被隐含地改变typedef //用以给数据类型取别名extern //声明变量是在其他文件正声明(也可以看做是引用变量)
return //子程序返回语句(可以带参数,也可不带参数)
void //声明函数无返回值或无参数,声明空类型指针continue //结束当前循环,开始下一轮循环do //循环语句的循环体while //循环语句的循环条件if //条件语句else //条件语句否定分支(与if连用)
for //一种循环语句goto //无条件跳转语句,尽量少用或者不用sizeof //计算对象所占内存空间大小,这不是个函数
我在这儿只说一些比较常用而且比较重要的关键字
1. register:
请求编译器尽可能的将变量存到CPU内部寄存器中而不是通过内存寻址访问以提高效率。。对这种变量不可以使用取址运算符来获取其地址,因为它不再内存中。寄存器变量用的不算多,但是还是得知道是什么意思。
2. static:---修饰变量和函数(限定作用域)
1.修饰变量
//变量又分为局部和全局变量,但它们都存在于内存的静态区。
//静态全局变量,作用域仅限于变量被定义的文件中,其他文件即使用extern声明也没法使用。
准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的代码行也不可以使用。
//静态局部变量,在函数体里面定义的,就只能在这个函数里用,同一个文档中的其他函数也用不了。
由于被static修饰的变量松狮存在内存的静态区,所以即使这个函数运行结束,
这个静态变量的值还是不会被销毁,函数下次使用时仍然能用。
2.修饰函数
//函数前加static使得函数成为静态函数。
但此处static的含义不是指存储方式,而使指对函数的作用域仅局限于本文件(所以又称内部函数)。
使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其他文件的函数同名。
//在C中引入关键字static是为了表示退出一个块后仍然存在的局部变量。
//随后,static在C中有了第二种含义:用来表示不能被其他文件访问的全局变量和函数。
为了避免引入新的关键字,所以仍然使用static关键字来表示这第二种含义。
3.基本数据类型:short、long、int、char、float、double(共6种)
构造数据类型:数组、结构体struct、公用体union、枚举类型enum
空类型void
【short为2个字节,int为4个字节,long为4个字节,float为4个字节、
double为8个字节,char为1个字节(一般情况下)】
【隐式类型转换:short,char → int →unsigned int → long → double(主干道) ←float】
4. sizeof关键字:计算变量所占空间 – 数组做函数参数时,退化为指针,4字节
sizeof (int)*p ----- sizeof(int) * p = 4p
再次强调,sizeof不是函数,而是关键字。
5. signed和unsigned关键字:
//32位的signedint类型整数其值表示范围为:-2^31~2^31-1
//8位的signed char类型其值表示范围为:-2^7~2^7-1
//32位的unsigned int类型整数其值表示范围为:0~2^32-1
//8位的unsigned char类型其值表示范围为:0~2^8-1
在计算机中,数值是以补码的形式存储:使用补码,可以将符号位与其他位统一处理,同时减法也可以按加法处理。
6. if和else关键字:
写if语句时,一般情况下先处理正常情况再处理异常情况,以便提高效率,可读性也较好;bool一般初始化为false比较好;int,float,指针变量 与0的比较问题(整形可以直接与0比较;float是实型,不能精确到0;指针变量与NULL)
if(flag) --- bool
if(0 == i) --- int
if(i > -0.000001 && i <0.000001) --- float
if(NULL == p) --- 指针变量
7. switch/case关键字:【解决多分支的问题】
每个case语句结尾加break;最后必须使用default分支。
case后面只能是整形或者字符型的常量或常量表达式。
8. do/while/for关键字:(3种循环结构)
while:先判断while后面括号里的值,如果为真则执行其后面的代码;否则不执行
do-while:先执行do后面的代码,然后再判断while后面括号里的值,如果为真,循环开始;否则,循环不开始。用法和while没有区别,但相对较少用。--- 至少执行一次
for:可以很容易的控制循环次数,多用于事先知道循环次数的情况。
【多重循环时,最长的循环放在最内层,最短的放在最外层,以提高执行效率;循环不要超过3层嵌套】
9. break终止本层循环;continue终止本次循环,开始下一次循环;return终止函数。
10. void关键字:“空即是色”---很强大
--- 函数返回值的限定;函数参数的限定。
任何指针类型都可以直接赋给void *类型,反过来就不行;不能定义一个void变量。
//void *memcpy(void *dest, const void *src, size_tlen);
//void *memset(void *buffer, int c, size_t num);
能说的比较少,但是void关键字真的是很强大,这点毋庸置疑。
11. return关键字:
--- 终止一个函数并返回其后跟的值
【别返回栈内存的的指针,因为该内存在函数体结束时被自动销毁,会导致程序错误】
12. const关键字:----不是“常量”,而是“只读变量”;用得好的话大大提高程序的效率
const修饰的是只读的变量,其值在编译时不能被使用,因为编译器在编译时不知道其存储的内容。
const推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。
const和define的区别:const修饰的只读变量,并且在定义的同时进行初始化;const可以节省空间,避免不必要的内存分配,同时提高效率;修饰一般变量,一般变量是指简单类型的只读变量;修饰数组;修饰指针;修饰函数的参数,当不希望这个参数值被函数体内意外改变时使用;修饰函数的返回值,表示返回值不可被改变;在另一连接文件中引用const只读变量。
【编译器通常不为普通const只读变量分配存储空间,而使将它们保存在符号表中,这使得它成为一个编译器件的值,没有了存储与读内存的操作,使得它的效率也很高;const定义的只读变量从汇编的角度看,只是给出了对应的内存地址,而不是像define一样给出的立即数】
const M = 3; int a[M]; --- 错误的,数组里面不能是变量,即使是只读
#define M 3 int a[M]; --- 正确的,预处理的时候做宏替换
const int *p;//p可变,p指向的对象不可变
int const *p;//p可变,p指向的对象不可变
int *const p;//p不可变,p指向的对象可变
const int *const p;//指针p和p指向的对象都不可变
13. volatile关键字:---判别普通工程师和嵌入式工程师
防止编译器优化,做嵌入式这行的不认识这个关键字,就要回家多修炼修炼啦!
14. extern关键字:
extern修饰变量或者函数,以表示变量或者函数的定义在别的文件中。从而提示编译器遇到此变量和函数时在其他模块中寻找其定义。
15. struct关键字:---写程序的时候尽量别使用全局变量,而是打包成结构体
将相关联的数据打包成一个整体;空结构体的大小不是0,而是1;
柔性数组:结构体最后的数组大小未知,内核链表中用柔性数组较多。
Type *p=( Type*)malloc(sizeof(Type)+100*sizeof(int));
【柔性数组与结构体没关系,算不上结构体的正式成员。】
struct和class:默认属性不同,struct是public,class是private。
16. union关键字:
大小是联合体中最大的成员的大小,而不是所有成员的大小和,此点和结构体不同;同一时间联合体只能访问数据成员中的一个,不能访问多个。
用联合体可以判断大小端模式的问题:
void check(void)
{
union
{
inti;
intj;
} stu;
stu.i= 5;
return(5 == stu.j):1,0;
}
17. enum关键字:
--- 枚举定义的是一堆常量,比如星期,颜色等
18. typedef关键字:---起别名,注意与define的区别,个人认为比define好用
typedef unsigned char uchar;
#define uchar unsigned char
(typedef结尾加分号,define不需要)
推荐使用typedef,因为在给指针进行替换的时候,define往往达不到效果;
#define char* PPP
PPP a,b;//只有a是char*的,b不是,用typedef就不同