1.结构体(struct)
结构体是一种自定义数据类型,用于将不同类型的数据组合成一个整体。结构体的基本语法如下:
struct 标识符
{
// 成员变量
};
使用建议:
结构体定义通常放在头文件中,以便在多个源文件中共享。
结构体传参时一般使用指针,以提高效率。
1.结构体初始化
struct Student
{
char name[20];
int age;
float score;
};
// 完全初始化
struct Student stu1 = {"张三", 20, 90.5};
// 部分初始化
struct Student stu2 = {.age = 21}; // C99标准支持
2.结构体内存对齐规则
默认按照计算机位数对齐(32位系统按4字节,64位按8字节)。
以结构体中最大字节的成员为对齐基准。
成员按声明顺序依次放入内存,偏移量必须能被sizeof(成员)
整除。
示例
struct Example
{
char a; // 1字节
int b; // 4字节
short c; // 2字节
};
// 32位系统下大小为12字节(1+3填充+4+2+2填充)
2.共用体(union)
共用体允许在相同的内存位置存储不同的数据类型。共用体的基本语法如下:
union 标识符
{
// 成员变量
};
特点
所有成员共享同一内存空间。
空间大小等于最大成员的大小。
最后赋值的成员是有效的。
所有成员起始地址相同。
应用:判断大小端存储
union EndianTest
{
int i;
char c[4];
};
int main(void)
{
union EndianTest test;
test.i = 1;
puts(test.c[0] == 1 ? "Little Endian\n" : "Big Endian") ;
return 0;
}
3.枚举(enum)
枚举用于定义一组命名的整数常量。枚举的基本语法如下:
enum 标识符
{
// 枚举常量
};
示例
enum Weekday
{
SUN, MON, TUE, WED, THU, FRI, SAT
};
enum Weekday today = WED;
结合switch-case使用
switch(today) {
case MON: printf("Monday\n"); break;
case TUE: printf("Tuesday\n"); break;
// ...
default: printf("Invalid day\n");
}
并且enume类型实际与int型相兼容enum Weekday today = WED;也可写为enum Weekday today = 3;
4.typedef关键字
typedef
用于为已有数据类型创建别名。语法如下:
typedef 原类型名 新类型名;
示例
typedef unsigned int UINT32;
typedef struct
{
char name[20];
int age;
} Person;
UINT32 num = 100;
Person p = {"Alice", 25};
5.位运算
位运算直接对整数在内存中的二进制位进行操作。基本位运算符包括:
&
按位与:指定位清零|
按位或:指定位置一^
按位异或:相同为0,不同为1,可用于指定位翻转<<
左移:高位丢弃,低位补0>>
右移:低位丢弃,高位补符号位(算术右移)或0(逻辑右移)
位操作示例
置一操作(设置某位为1)
unsigned int set_bit(unsigned int num, int pos) {
return num | (1 << pos);
}
置零操作(清除某位为0)
unsigned int clear_bit(unsigned int num, int pos) {
return num & ~(1 << pos);
}
翻转位
unsigned int toggle_bit(unsigned int num, int pos) {
return num ^ (1 << pos);
}
检查位
int check_bit(unsigned int num, int pos) {
return (num >> pos) & 1;
}
掌握这些复合数据类型和位操作技巧,可以大大提高C语言编程的灵活性和效率。