C语言|C语言 用数组的绝对值替换它的,C语言深度解剖 -- 关键字(一)

一、定义和声明的区别
1、定义:(编译器)创建一个对象,为这个对象分配一块内存并给它取上一 个名字,这个名字就是我们常说的变量名或对象名。
2、声明:告诉编译器,这个名字(变量名或对象名)已经匹配到一块内 存上了,下面的代码用到变量或对象是在别的地方定义的。声明可以多次。告诉编译器,这个名字(变量名或对象名)已被预订,别的地方再也不能用它来作为变量名或对象名。
二、最宽宏大量的关键字——auto
1、auto : 在缺省的情况下,编译器默认所有变量都是auto的。
三、最快的关键字——register
1、register : 这个关键字请求编译器尽可能地将变量存在CPU内部寄存器中,而不是通过内存寻址访问以提高效率。CPU——寄存器——内存(寄存器相当于一个中转站,数据从内存里取,将变量存在CPU内存寄存器里,方便CPU直接取出数据,不需要从内存里再取了)
2、优点是:速度快
3、注意点:(1)register变量必须是能被CPU寄存器所接受的类型(必须是一个单个的值,并且长度应小于或等于整形的长度)
(2)register变量可能不存放在内存中,所以不能用取址“&”来获取register变量的地址
四、最名不符实的关键字——static
1、修饰变量:
(1)静态全局变量: 作用域仅限于变量被定义的文件中(从定义之处开始,到文件结尾处结束),定义之前的代码如果要使用,就要在前面加extern***。
(2)静态局部变量:在函数体里面定义的,就只能在这个函数里用了。由于被static修饰的变量总是存在内存的静态区,所以即使这个函数运行结束了,这个静态变量的值也不会被销毁,函数下次使用时任然能用到这个值。
2、修饰函数:
(1)函数前加static使得函数成为静态函数。但,static的含义是指对函数的作用域仅局限于本文件(又称内部函数)。使用内部函数的好处:不同的人编写不同的函数时,不用担心自己定义的函数是否会与其他文件中的函数同名。
3、static的两种含义:a、表示退出一个块后仍然存在的局部变量。b、表示不能被其他文件访问的全局变量和函数。
五、基本数据类型
1、基本类型:
(1)数值类型:
整型:短整型 short(2)、int(4)、long(4)
浮点型:float(4)、double(8)
(2)字符类型:char(1)
2、构造类型:
数组、结构体struct、共用体union、枚举类型enum
3、指针类型
4、空类型void
5、变量的命名规则:
(1)一般规则:
规则1:命名应当直观且可以拼读,可忘文知意,便于记忆和阅读。
规则2:命名的长度应当符合“min ——length&&max——information”原则。
规则3:当标识符由多个词组成时,每个词的第一个字母大写,其余全部小写。
规则4:尽量避免名字中出现数字编号,除非逻辑上的确需要编号,
比如驱动开发时为引脚命名,非编号名字反而不好。
规则5:对在多个文件之间共同使用的全局变量或函数要加范围限定符。
(2)标识符的命名规则:
规则6:标识符名分为两部分:规范标识符前缀(后缀)+ 含义标识。
非全局变量可以不使用范围限定符前缀。
规则7:作用域前缀命名规则
规则8:数据类型前缀命名规则
规则9:含义标识命名规则,变量命名使用名词性词组,函数命名使用动词性词组
规则10:程序中不得出现仅靠大小写区分的相似的标识符。
规则11:一个函数名禁止被用于其他之处。
规则12:所用宏定义、枚举常量、只读变量全用大写字母命名,用下划线分割单词。
规则13:考虑到习惯性问题,局部变量中可采用通用的命名方式,
但仅限于n,i,j等作为循环变量使用。
规则14:定义变量的同时千万不要忘记初始化。
定义变量时编译器并不一定清空了这块内存,它的值可能是无效的数据。
规则15:不同类型数据之间的运算要注意精度扩展问题,
一般低精度数据将向高精度数据扩展。
六、最冤枉的关键字——sizeof
1、sizeof是关键字而不是函数(eg:int i;此时sizeof i 为4 )。
2、sizeof在计算变量所占空间大小时,括号可以省略,而计算类型(模子)大小时不能省略。
3、`
sizeof(int) *p; ——————???
int *p = NULL;
sizeof(p);
sizeof(*p); `
int a[100];
sizeof(a);
sizeof(a[100]);
sizeof(&a);
sizeof(&a[0]);
int b[100];
void fun(int b[100])
{
sizeof(b);
}
七、signed、unsigned关键字
1、最高位为1,表明这个数是负数;最高位为0,表明这个数是正数。
2、在计算机系统中,数值一律用补码来表示(存储)。主要原因是:使用补码可以将符号位和其他位统一处理,同时,减法也可按加法来处理。
3、两个用补码表示的数 相加时,如果最高位(符号位)有进位,则进位被舍弃。
4、正数的补码与原码一致,负数的补码:符号位为1,其余位为该数绝对值的原码按位取反,然后整个数加1。
5、strlen函数是计算字符串长度的,并不包含字符串后面的‘\0’。
八、if、else组合
1、bool变量和“零值”进行比较
bool bTestFlag = FALSE;
if(bTestFlag)
if(!bTestFlag)
2、float变量和“零值”进行比较
float fTestFlag = 0.0;
const float EPSINON = 0.000001; //是定义好的float类型的精度
if((fTestFlag >= -EPSINON)&&(fTestFlag <= EPSINON));
3、指针变量和“零值”进行比较
int *p = NULL;
if(NULL ==p);
if(NULL != p)
4、else始终与同一括号内最近的未匹配的 if 语句结合
5、if 的空语句建议写成
if (condition)
{
NULL;
}
6、注意事项:
(1)先处理正常情况再处理异常情况
(2)确保if 和else 子句没有弄反
九、switch、case组合
1、用于分支很多的嵌套语句,这样可以提高效率。
2、每个 case 语句的结尾绝对不要忘记加 break ,否则将导致多个分支重叠。
3、最后必须使用 default 分支即使程序不需要 default 处理,也应该保留以下语句:
default :
break;
4、case 后面只能是整型或字符型的常量或常量表达式。
5、case 语句的排列顺序:
规则1:按字母或数字顺序排列各条 case 语句。
规则2:把正常情况放在前面,而把异常情况放在后面。
规则3:按执行频率排列 case 语句。(最常执行的情况放在前面,
而把不常执行的放在后面。)
6、其他注意事项:
规则1:简化每种情况对应的操作。
规则2:不要为了使用 case 语句而刻意制造一个变量。
规则3:将 default 子句只用于检查真正的默认情况。
十、do、while、for关键字
1、while(1) 表示死循环。
2、break 和 continue 的区别:
(1)break 表示终止本层循环。
(2)continue 表示终结本次(本轮)循环。(本轮循环结束, 进入下一轮循环)
3、while(1) || while(true) || while(1 == 1) || while((bool) 1) 这几种效果一样。
4、do-while 循环先执行do 后面的代码,再判断 while 后面括号里的值,如果为真,循环开始,否则,循环不开始。
5、for循环:for循环可以很容易的控制循环次数,多用于事先知道循环次数的情况下。
6、循环语句的注意点:
规则1:在多重循环中,如果有可能,应当将最长的代码放在最内层,
最短的循环放在最外层,以减少 CPU 跨切循环层的次数。
(长循环在最内层, 效率高。)
规则2:建议 for 语句的循环控制变量的取值采用“半开半闭区间”写法。
规则3:不能在 for 循环体内修改循环变量,防止循环失控。
规则4:循环要尽可能地短,要使代码清晰,一目了然。
(循环体内的代码一般不超过 20 行)
规则5:把循环嵌套控制在 3 层以内。
7、禁止使用 goto 语句。
十一、void 关键字
1、void 的字面意思是 “空类型”, void * 则为“空指针”,可以指向任何类型的数据。
2、void 的作用:对函数返回的限定,对函数参数的限定。
3、void * ,任何类型的指针都可以赋值给他,无需进行强制类型转换(但 void * 不可以赋值给其他类型的指针,因为“空类型”可以包含“有类型”)
void *a;
int *b;
a = b;
// b = a;
4、void修饰函数返回值和参数
规则1:如果函数没有返回值,应将其声明为 void 类型(在C语言中,
凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。)
规则2:如果函数无参数,那么应声明其参数为 void 。
5、void 指针
【C语言|C语言 用数组的绝对值替换它的,C语言深度解剖 -- 关键字(一)】规则1:小心使用 void 指针类型, 不能对void *类型进行算法操作
规则2:如果函数的参数可以是任意类型指针,那么应声明其参数为void *。
6、void不能代表一个真实的变量,因为定义变量时需要分配内存空间,但定义void 类型变量时,编译器不知道该给这个变量分配多大的空间。
十二、return关键字
1、return用来终止一个函数并返回其后面跟着的值。
2、return 语句不可返回指向“栈内存”的“指针”,因为该内存在函数体结束时被自动销毁。
十三、const关键字
1、const 修饰的是只读的变量。
2、const 推出的最初目的是 取代预编译指令,消除它的缺点,同时继承它的优点。
3、const 和 define 宏的区别:
(1)const 修饰的只读变量必须在定义的同时初始化。
(2)编译器通常不为 const 只读变量分配存储空间,而是将他们保存在符号表中,使得他们成为一个编译期间的值,没有了存储和读内存的操作,使得他们的效率很高。(节省空间,避免不必要的内存分配,同时提高效率。)
(3)const 给出了对应的内存地址,#define给出的是立即数。
(4)const定义的只读变量在程序运行过程中只有一个备份(因为他是
全局的只读变量,存放在静态区),#define 定义的 宏常量在内存
中有若干备份。
(5)const 修饰的只读变量是在编译的时候确定其值,
#define定义的宏常量在预编译阶段进行替换。
(6)const 修饰的只读变量具有特定的类型,#define 宏没有类型。
4、修饰一般变量
int const i = 2; 或 const i = 2;
5、修饰数组
int const a[5] = {1, 2, 3, 4, 5}; 或 const int a[5] = {1, 2, 3, 4, 5 }
6、修饰指针
const int *p; // p可变,p指向的对象不可变
int const *p; // p可变,p指向的对象不可变
int * const p; // p不可变,p指向的对象可变
const int *const p; // 指针p 和 p 指向的对象都不可变
7、修饰函数的参数
void Fun(const int i) // 告诉编译器 i 在函数体中不能改变
8、修饰函数的返回值
const int Fun(void ) //返回值不可被改变

    推荐阅读