一、枚举类型
枚举类型(Enumeration Type,简称enum
)是C语言中的一种用户定义的数据类型。枚举类型允许你为一组相关的整数常量赋予更具描述性的名称,从而使代码更具可读性和可维护性。
enum 枚举名
{
列举各种值1, //枚举元素//枚举常量
列举各种值2,
};
enum fire
{
LITTLE_FIRE,
MIDDILE_FIRE,
LARGE_FIRE,
};
1. 定义枚举类型
枚举类型是一种用户定义的类型,使用 enum 关键字定义。它用于定义一组相关的常量。
2. 枚举值的默认与显式赋值
枚举中的元素默认从0开始,后续元素依次递增。如果给某个枚举元素显式赋值,则后续未赋值的元素依次在该值的基础上递增。列举各种值,之间用逗号隔开,不需要写类型名
3. 枚举类型的本质
枚举类型本质上是一个 int 类型的数据,因此枚举变量可以与整型变量通用。
4. 与宏定义的对比
使用阶段不同:宏定义在预处理阶段展开,不进行语法检查。枚举在编译阶段进行语法检查,并在运行阶段参与代码运行。
可读性:两者都提高了代码的可读性。枚举更适合表示一组相关的值,能清晰地展示它们之间的关系。
5.作用域
枚举常量在定义它们的枚举类型的作用域内是全局的。如果不同的枚举类型中有相同的枚举常量名称,可能会导致冲突。
二、typedef
typedef是 C 语言中的一个关键字,用于为现有的数据类型定义新的名称或别名。它的主要作用是简化代码,使得代码更加易读、易维护,尤其是在处理复杂数据类型时。
typedef 并不会创建新的数据类型,只是为现有类型定义了一个新的名称。
typedef 常与 struct、enum 等关键字配合使用,以减少代码中的冗长和复杂性。
typedef unsigned int uint;
typedef int IntArray[10];
typedef int (*func_ptr)(int, int);
uint x = 20;
IntArray arr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
func_ptr add;
typedef 的优势:
提高代码可读性:使用简短且具有描述性的名称代替复杂的数据类型,使代码更易读。
增强代码的可维护性:如果需要更改某个数据类型,只需修改 typedef 定义,而不必修改整个代码中的每个地方。
便于跨平台开发:通过 typedef,你可以为不同平台上的数据类型定义统一的别名,从而在不同平台上使用相同的代码。
三、位运算
1.按位与 (`&`)
按位与运算符对两个操作数的每一位执行“与”操作:如果两个相应的位都是1,则结果位为1,否则为0。
int a = 5; // 二进制:0101
int b = 3; // 二进制:0011
int c = a & b; // 结果:0001,即 1
2. 按位或 (`|`)
按位或运算符对两个操作数的每一位执行“或”操作:如果两个相应的位中至少有一个是1,则结果位为1,否则为0。
int a = 5; // 二进制:0101
int b = 3; // 二进制:0011
int c = a | b; // 结果:0111,即 7
3. 按位异或 (`^`)
按位异或运算符对两个操作数的每一位执行“异或”操作:如果两个相应的位不同,则结果位为1,相同则为0。
int a = 5; // 二进制:0101
int b = 3; // 二进制:0011
int c = a ^ b; // 结果:0110,即 6
4. 按位取反 (`~`)
按位取反运算符对操作数的每一位执行“取反”操作:将1变为0,将0变为1。
int a = 5; // 二进制:0000 0101
int c = ~a; // 结果:1111 1010,即 -6 (在32位系统中)
5. 左移 (`<<`)
左移运算符将操作数的二进制表示向左移动指定的位数,右边补0。左移相当于对数字乘以2的指定次幂。
int a = 5; // 二进制:0101
int c = a << 1; // 结果:1010,即 10
6.右移 (`>>`)
右移运算符将操作数的二进制表示向右移动指定的位数。右移相当于对数字除以2的指定次幂。右移分为算术右移和逻辑右移:
算术右移:高位补符号位(正数补0,负数补1)。
逻辑右移:高位补0。
int a = 5; // 二进制:0101
int c = a >> 1; // 结果:0010,即 2
四、位运算的应用
1. 掩码操作
位运算常用于掩码操作,比如从一个整数中提取特定位、设置特定位或清除特定位。
int flags = 0x0F; // 二进制:00001111
int mask = 0x02; // 二进制:00000010
int result = flags & mask; // 提取第1位结果:00000010
2. 设置某个位为1
你可以使用按位或运算符来将某个位设置为1。
int flags = 0x01; // 二进制:00000001
flags |= 0x02; // 结果:00000011
flags = flags|(1<<n);//将第n位置1
3.清除某个位为0
使用按位与和取反运算可以将某个位清除为0。
int flags = 0x03; // 二进制:00000011
flags &= ~0x02; // 结果:00000001
flags = flags&~(1<<n);//将第n位置0
4. 判断某个位是否为1
使用按位与运算可以检查某个位是否为1。
int flags = 0x03; // 二进制:00000011
if (flags & 0x02) {
printf("第1位为1\n");
}
flags = flags&(1<<n);
5. 交换两个数值
位运算可以用于在不使用额外变量的情况下交换两个数的值(不建议实际应用,主要用于理解位运算的巧妙性)。
int a = 5; // 二进制:0101
int b = 3; // 二进制:0011
a = a ^ b;
b = a ^ b;
a = a ^ b;
6.循环左移
将最高位移到最低位。
int n = 0xf0000001;
for(int i=0;i<32;i++){
if(n&(1<<31)){
n<<=1;
n+=1;
}else{
n<<=1;
}
}