C语言32个关键字
1.1类型关键字(12个)
char、short、int、long、float、double、unsigned、signed、struct、union、enum、extern、static
1.2控制语句(12个)
if、else、switch、for、while、do-while、case、break、continue、goto 、return、default
1.3存储类型(4个)
auto、static、register、volatile
①auto在C语言中只有一个作用就是修饰局部变量,表示这个变量是自动变量,分配在栈上,平时定义的局部变量就是自动局部变量,只是省略了auto。
{int A =10;} A自动变量/局部变量 int A =10;===== auto int A =10;
②static关键字在C语言中有两种用法
A)第一种就是修饰局部变量:static修饰的局部变量只是改变了存储类型,其存储方式和全局变量一样,作用域和普通局部变量一样。
在子函数内定义的静态局部变量:分配至全局静态区;
B)第二种就是修饰全局变量和函数:static修饰全局变量和函数只是改变了他们的链接属性由外链接变为内链接(.C文件内),全局变量和函数默认的链接属性为外链接(可以跨文件进行链接)
外链接侧重于工程中其它源文件;
内链接:侧重于当前的源文件;
本知识点联系函数:static相关知识点;
对全局变量进行修饰: 修饰全局变量和函数只是改变了他们的链接属性由外链接变为内链接(.C文件内),全局变量和函数默认的链接属性为外链接(可以跨文件进行链接).
③register这个关键字不常用,register修饰的变量,编译器会尽量将他们分配在寄存器中,(平时分配的一般变量都是在内存中,分配在寄存器中一样的用,但是读写效率会提高很多)。所以register修饰的变量通常是被反复高频率的使用,通过改善这个变量的访问效率可以极大的提升程序的运行效率。
总耗时比较;
浅析C语言的一个关键字——register_21aspnet的博客-CSDN博客_c语言register
④volatile (可变的 易变的) C语言中volatile用来修饰一个变量,表明这个变量可以被编译器之外的东西改变(编译器不可预知的东西,比如硬件自动更改了这个变量的值,一般这个变量是一个寄存器的值,比如在多线程中在别的线程更改了这个变量的值),如果不该加时加了会降低效率。
C语言中volatile关键字的作用 - 行路人& - 博客园
1.4其他类型(4个)
extern、const、typdef、sizeof
- const:声明一个变量的值不可变,要求const修饰的变量在定义时必须进行初始化。
#include <stdio.h> #include <string.h> int main() { const int A=10; //初始化时进行赋值 return 0; } |
#include <stdio.h> #include <string.h> int main() { const int A; A =10; //错误的 return 0; } |
Const修饰变量内容存放至文本常量区;
常量指针是指指向常量的指针,顾名思义,就是指针指向的是常量,即,它不能指向变量,它指向的内容不能被改变,不能通过指针来修改它指向的内容,但是指针自身不是常量,它自身的值可以改变,从而指向另一个常量。
指针常量是指指针本身是常量。它指向的地址是不可改变的,但地址里的内容可以通过指针改变。它指向的地址将伴其一生,直到生命周期结束。有一点需要注意的是,指针常量在定义时必须同时赋初值。
例程代码:
#include <stdio.h> #include <string.h> int main() { int A =10; int B =20; printf("******************常量指针*************************\n"); const int *p1 =&A; //const 修饰的 *p1 //常量指针 printf("%d\n",*p1); //*p1 = 20; //报错 //就是指针指向的是常量,即,它不能指向变量,它指向的内容不能被改变,不能通过指针来修改它指向的内容 p1= &B; printf("%d\n",*p1); //常量指针:可以切换指向 但是不能修改指向的内容 printf("******************指针常量*************************\n"); int *const p2 =&A; //const 修饰的为 p2 printf("%d\n",*p2); *p2 = 99; printf("%d\n",A); //p2 =&B; //报错 指针常量 指针是常量 不能切换位置 //指针常量 不能改变指向但是可以改变内容 const p2 printf("******************常量指针常量*************************\n"); const int *const p3 =&A; //const 修饰的为 *p3 也修饰p3 printf("%d\n",*p3); //*p3 =100; //p3 =&B; //常量指针常量:不能改变指向 也不能改变内容 return 0; } |
const int a /* 声明变量a的值在程序过程中,a的值不可变 */
int const a /* 声明变量a的值在程序过程中,a的值不可变 */
int *const a /* 声明指针a的指向不可变,但指向地址中的值可变*/
const int *a /* 声明指针a的指向可变,但指向地址中的值不可变 */
const int * const a /* 声明指针a的指向不可变,但指向地址中的值也不可变 */
- typdef:类型重定义,表示要重新定义一个新的类型
typdef unsigned char u8; /* 定义一个新的数据类型u8,这个数据类型等价于 unsigned char */
数据类型重定义:让该数据类型或者定义的变量表述更加有意义;
typedef unsigned int size_t;
size_t buffsizeof;
- typedef和define的区别:
- define要配合#号使用,是预编译处理中的内容,只是单纯的替换,在预编译处理中进行。
- typedef是定义一个新的数据类型,在正式编译时执行。
- #define后边没有分号,typedef后边有分号。
- #define是使用说明来替代这个类型(标识符在前,替代的类型在后);typedef是重新定义这个类型叫什么(类型在前,标识符在后)。
单片机阶段:typedef unsigned char u8;
未使用typedef及define代码验证: #include <stdio.h> #include <string.h> int main() { int A =10; int *p= &A,p1; //p:类型? p1:类型? printf("%lf\n",p); //--->p int * 指针类型 printf("%lf\n",p1); //--->p1 int 整型 return 0; } |
#include <stdio.h> #include <string.h> #define PPPPP int* int main() { int A =10; PPPPP p= &A,p1; //p:类型? p1:类型? printf("%lf\n",p); //--->p int * 指针类型 printf("%lf\n",p1); //--->p1 int 整型 return 0; } |
#include <stdio.h> #include <string.h> typedef int * PPPPP; int main() { int A =10; PPPPP p= &A,p1; //p:类型? p1:类型? printf("%lf\n",p); //--->p int * 指针类型 printf("%lf\n",p1); //--->p1 int * 指针类型 return 0; } |
1.5位运算符
- 运算符号:&、|、^、~、<<、>>。
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; int main() { unsigned char num =0x13; ByteToBits *p=(ByteToBits *)# printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
&位与运算符:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //&位与运算符: 有0则零 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 unsigned char num3 = num1 & num2; //0001 0000 ByteToBits *p=(ByteToBits *)&num3; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
|位或运算符:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //|位与运算符: 有1则1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 unsigned char num3 = num1 | num2; //0001 0011 ByteToBits *p=(ByteToBits *)&num3; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
^位异或运算符 位相异为1,相同为0
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 unsigned char num3 = num1 ^ num2; //0000 0011 ByteToBits *p=(ByteToBits *)&num3; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
位取反~
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 unsigned char num3 = ~num2; //1110 1100 ByteToBits *p=(ByteToBits *)&num3; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
<<左移 低位移至高位,低位填充0
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 unsigned char num3 = num2<<3; //1001 1000 152 // 扩展 0x13*8 152 //后期如果您需要对一个整数进行乘2的n方数时可以考虑采用位运算; //num*2 num<<1 //num*4 num<<2 //num*8 num<<3 //num*16 num<<4 //乘法运算效率低于位运算效率 ByteToBits *p=(ByteToBits *)&num3; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
>>右移 高位移至低位,高位填充0
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 unsigned char num3 = num2>>3; //0000 0010 ByteToBits *p=(ByteToBits *)&num3; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
复合运算符:
左移后赋值:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 num2 <<= 3; //num2 = num2<<3 1 0011000 ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
右移后赋值:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 num2 >>= 3; //num2 = num2>>3 0000 0010 ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
按位与后赋值:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 num2 &= 0x10; //num2 = num2 & 0x10 0001 0000 ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
按位或后赋值:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 num2 |= 0x10; //num2 = num2 | 0x10 0001 0011 ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
按位异或后赋值:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //^位异或运算符: 相同为0 相异为1 int main() { unsigned char num1 =0x10; //0001 0000 unsigned char num2 =0x13; //0001 0011 num2 ^= 0x10; //num2 = num2 ^ 0x10 0000 0011 ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
符号运算符(在项目中能用位运算的不能用乘除法);
- 运算作用:对数据的每一位(每个二进制位)进行运算操作,需要将操作的对象空间位存储写出来。
- 位运算符操作原则
- 按位与(&):任何数的每个位按位与上0,结果为0;按位与上1,结果不变(原来是多少就是多少)。
- 按位或(|):任何数的每个位按位或上1,结果为1;按位或上0,结果不变(原来是多少就是多少)。
- 按位异或(^):不同为1,相同为0。(相异为1,相同为0)
- 按位取反(~):1变0,0变1
- 左移(<<):数据的所有位往左移动,数据的高位被移出,在低位补0对齐。1100<<1 --> 1000
- 右移(>>):数据的所有位往右移动,数据的低位被移出,在高位补0对齐。1100>>1 --> 0110
- 位运算作用:
- “左移”、“右移”主要是对数据的位寻址。(将数据中的每一个二进制位提取出来)
- “按位与”一般配合上“按位取反”来对数据具体的某一位进行清空数据(清0)。
- “按位或”主要用于对数据的具体某一位进行写入数据(置1)。
- “按位异或”主要用于单独针对某一位进行取反(其他位不变)
例:把数据n的第4位清零:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //例:把数据n的第4位清零: int main() { unsigned char num2 =0x13; //0001 0011 //num2 = num2 & ~(0x10); //最原始写法 死板 //num2 = num2 & ~(1<<4); //改进1 繁琐 num2 &=~(1<<4); //改进2 ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
例:把数据n的第5位置1:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //把数据n的第5位置1: int main() { unsigned char num2 =0x13; //0001 0011 //num2 = num2 | (1<<5); //繁琐 num2 |= (1<<5); ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |
例:连续将n的第10位、11位写入数字2
#include <stdio.h> #include <string.h> //位运算 typedef struct Twobyte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; unsigned int bit8:1; unsigned int bit9:1; unsigned int bit10:1; unsigned int bit11:1; unsigned int bit12:1; unsigned int bit13:1; unsigned int bit14:1; unsigned int bit15:1; }TwoByteToBits; //例:连续将n的第10位、11位写入数字2 int main() { unsigned short num2 =0xff13; //0000 0001 0011 //num2 |= (2<<10); //如果原数值该位为1呢 到不到0 //先进行位num2 10 11清零 num2 &= ~(3<<10); // ~(3<<10)只有第10位 第11位为0 其它位1 //再进行赋值操作 num2 |= 2<<10; TwoByteToBits *p=(TwoByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",p->bit15,p->bit14,p->bit13,p->bit12,p->bit11,p->bit10,p->bit9,p->bit8,p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; }
|
例:把数据n的第7位单独取反:
#include <stdio.h> #include <string.h> //位运算 typedef struct byte{ unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }ByteToBits; //把数据n的第7位单独取反: int main() { unsigned char num2 =0x13; //0001 0011 //num2 = num2 ^ (1<<7) //异或相同为0 相异1 //1000 0000 num2 ^= 1<<7; ByteToBits *p=(ByteToBits *)&num2; printf("%d %d %d %d %d %d %d %d\n",p->bit7,p->bit6,p->bit5,p->bit4,p->bit3,p->bit2,p->bit1,p->bit0); return 0; } |