一、auto关键字
在缺省情况下,编译默认的所有变量都是auto。
二、register关键字
使用该关键字是让编译器尽可能把变量存在CPU的内部寄存器中,而不是内存寻址访问,从而提高了效率。之所以说是尽可能,是因为CPU的寄存器是有限的,如果用register修饰的变量超过了CPU的寄存器,CPU也不能把全部的变量都放在寄存器中。那什么是寄存器?寄存器就是一块一块的存储空间,它能直接和CPU打交道,内存却不行,因此寄存器的存取速率要大于内存。
三、static关键字
1、static
修饰变量,包括全局变量和局部变量,且修饰的变量都是存在内存的静态存储区。
(1)、static
修饰全局变量:用static
修饰的全局变量只能在变量被定义的文件中使用,其它文件不能使用,而且在变量定义的地方前面的代码是不能使用该变量的,只有后面的代码才能使用。
(2)、static
修饰局部变量:用static修饰的局部变量是存储在静态存储区的,因此即使是函数运行结束,这个静态变量值也不会被销毁,函数下次使用时会继续使用该值。
#include <stdio.h>
#include <stdlib.h>
void test_fun1(void)
{
int value1 = 0;
value1++;
printf("value1:%d\n", value1);
}
void test_fun2(void)
{
static int value2 = 0;
value2++;
printf("value2:%d\n", value2);
}
void test_fun3(void)
{
int i = 0;
for (i=0; i<10; i++)
{
test_fun1();
test_fun2();
}
}
int main(void)
{
test_fun3();
return 0;
}
结果:
value1:1
value2:1
value1:1
value2:2
value1:1
value2:3
value1:1
value2:4
value1:1
value2:5
value1:1
value2:6
value1:1
value2:7
value1:1
value2:8
value1:1
value2:9
value1:1
value2:10
2、static
修饰函数,用static
修饰的函数并不是指存储形式,而是指修饰的函数只能在本文件中使用,这样做的好处是当多人合作时,不用担心自己写得函数会和别人写的函数同名而有冲突。
四、基本数据类型
1、short
:在32位系统上,short
的内存大小是2字节。
2、int
:在32位系统上,int
的内存大小是4字节。
3、long
:在32位系统上,long
的内存大小是4字节。
4、float
:在32位系统上,float
的内存大小是4字节。
5、double
:在32位系统上,double
的内存大小是8字节。
6、char
:在32位系统上,char
的内存大小是1字节。
五、sizeof关键字
1、一般情况一下sizeof
是在编译的时候求值,而在C99
中计算柔性数组所占用的空间是,sizeof
是在运行时求值的。(C语言柔性数组讲解)。
2、sizeof
不是函数。
3、举例:
int a = 0;
sizeof(int); //计算结果为4
sizeof(a); //计算结果为4
sizeof int; //编译出错
sizeof a; //计算结果为4
六、signed、unsigned
1、负数存储方法:把数据类型的最高位用来存储符合,如果最高位为1
,则表示这个数是负数;如果最高位为0
,则表示这个数是正数。
七、if、else组合
1、else
始终与统一括号内最近为匹配的if
匹配。
2、在编程时,将正常情况放在if
后面处理,将异常情况放在else
后面处理。
八、switch、case组合
1、if、else
一般在嵌套比较少的分支使用,如果分支多使用switch、case
能提高效率。
2、case
语句结果要用break
结束,否则会导致分支重叠。
3、最后必须使用default
分支,即使不需要在defalut
里面处理,也应该保留:
defalut:
break;
4、switch、case
组合中禁止使用return
。
5、case
后面只能是整型或者字符型的常量或者常量表达式。
九、do、while、for
1、while
循环:先判断while
括号里面的值是否为真,如果为真则执行后面的代码。
2、do-while
循环:先执行一遍do
里面的代码,再判断while
括号的值是否为真,如果为真则继续执行do
里面的代码。
3、for
循环:用于实现知道循环次数的循环,且循环次数可控制。
4、break
和continue
的区别:break
表示终止本层循环,continue
表示结束本次循环,进入下一次循环。
例如:
int i = 0;
bool bFlag = FALSE;
for (i=0; i<10;i++)
{
if (5 == i) //i等于5的时候,结束for循环,循环执行了5次,打印了5次“Hello World”
{
break;
}
printf("Hello World\n");
}
for (i=0; i<10;i++)
{
if (5 == i)//i等于5时,结束本次循环,不结束for循环,且i等于5的时候,不执行打印“Hello World”,i不等于5的时候才执行打印"Hello World",循环执行了10次
{
continue;
}
printf("Hello World\n");
}
5、在多重for
循环中,如果可能,应该将最长的循环放在最内层,最短的循环放在最外层,减少CPU切换循环层的次数。
例如:
//效率高
for (col=0; col<5; col++)
{
for (row=0; row<100; row++)
{
sum = sum + a[row][col]
}
}
//效率低
for (row=0; row<100; row++)
{
for (col=0; col<5; col++)
{
sum = sum + a[row][col]
}
}
6、在for
循环,建议使用半开半闭区间写法。
例如:
//半开半闭区间写法
for (n=0; n<10; n++)
{
}
//闭区间写法
for (n=0; n<=9; n++)
{
}
7、for
循环控制表达式不能包含任何浮点类型的对象。控制表达式一般会包含一个计数器,检测计数器的值来判断是否终止循环,而浮点变量在舍入和截取误差的时候会通过循环迭代过程传播,导致循环变量的显著误差,从而在检测的时候可能导致不可预期的结果。
十、goto关键字
goto
语句虽然可以灵活跳转,但是如果不加以限制,会破坏结构化设计风格,存在很大的隐患,因此在程序设计的时候,应该尽量不用goto
。
十一、return关键字
1、return
用来终止终止一个函数并返回其后面跟着的值。
2、return
不可返回指向栈内存
的指针,因为栈内存
在函数接收的时候就被自动回收销毁了。
例如:
char * fun(void)
{
char str[30];
...
return str;
}
3、return;
的作用:用于返回值类型是void
的函数,强制结束当前函数。
例如:
只打印“Hello”,不打印“World”。
void fun(void)
{
printf("Hello");
return;
printf("World");
}
十二、const关键字
1、const
修饰的变量必须在定义的时候初始化。
2、case
后面不能是const
修饰的只读变量。因为case
后面只能跟整形或者字符型的常量或常量表达式;而C语言中const
修饰的是只读变量,具有不可变型,而且const
修饰的只读变量只能在定义的时候初始化,不能定义后再赋值。
3、编译器通常不为普通const
变量分配存储空间,而是将它们保存在符合表中,这样使它成为一个编译期间的值,没有了存储和读内存的操作。
例如:
#define M 3 //宏常量
const int N = 5; //此时未将N放入内存中
int i = N; //此时为N分配内存,以后不再分配
int I = M; //预编译期间进行宏替换,分配内存
int j = N; //没有内存分配
int J = M; //再进行宏替换,再进行一次内存分配
4、const
修饰指针
const int *p; //p可变,p指向的对象不可变
int const *p; //p可变,p指向的对象不可变
int *const p; //p不可变,p指向的对象可变
const int *const p; //p不可变,p指向的对象不可变
5、const
修饰函数的参数
//*p在函数体内不能被修改。
void fun(const int *p)
十三、volatile关键字
1、volatile的作用是“告诉编译器,i是随时可能发生变化的,每次
使用它的时候必须从内存中取出i的值”。
十四、union关键字
1、大小端模式端union
类型数据的影响。
大端模式:字数据的高字节存在低地址中,低字节存在高地址中。
小端模式:字数据的高字节存在高地址中,低字节存在低地址中。
union
所占的空间大小等于其最大成员空间大小。
2、编写程序,判断处理器是大端模式还是小端模式。
//返回1则是小端模式
//返回0这是大端模式
int checkCPU(void)
{
union check
{
int a;
char b;
}ucheck;
ucheck.a = 1;
return (ucheck.b == 1);
}
参考文献
《C语言深度解剖》