c语言_Day36_08_07
1、自定义类型
1. 结构体
偏移量:相对于起始位置地址的距偏移距离
offsetof:用于计算结构体成员的偏移量
结构体传参:
struct S
{
char c;
int i;
double d;
};
int main()
{
struct S s;
s.c = 'a';
s.i = 1;
s.d = 3.14;
printf("%c %d %lf\n", s.c, s.i, s.d);
return 0;
}
struct S
{
char c;
int i;
double d;
};
void Init(struct S* p, char c, int i, double d)
{
p->c = c;
p->i = i;
p->d = d;
}
int main()
{
struct S s;
Init(&s, 'a', 1, 3.14);
return 0;
} 传值与传址:struct S
{
char a;
int b;
};
// 传值
void Print1(struct S s)
{
printf("%c %d\n", s.a, s.b);
}
// 传址
void Print2(struct S* p)
{
printf("%c %d\n", p->a, p->b);
} 传址更优,因为传址无需再创建形参的临时拷贝,内存需求更低,性能更高
通过const关键字防止在传址函数中修改原数据
void Print2(const struct S* p){} 2、位段
位段的声明类似于结构体,有两点不同:
- 成员必须为int、unsigned int或signed int
- 位段的成员名后有一个冒号和一个数字
struct A
{
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
}; 位段所赋值的数字表示成员所需的位大小,如上例中_a需2个比特位(可表示4个数字)
位段的内存分配:
- 根据成员类型开辟内存空间(int类型开辟4字节)
- 根据位段所赋值的数字依次划分空间,若空间无法一次性容纳位段成员则再开辟新的内存空间
struct A
{
char _a : 4;
char _b : 2;
char _c : 8;
};
int main()
{
struct A a = { 0 };
a._a = 10;
a._b = 5;
a._c = -1;
return 0;
}
3、枚举
枚举:把可能取值一一列举
typedef enum Gender
{
MALE,
FEMALE,
UNKNOWN
}Gender;
int main()
{
Gender g = MALE;
switch (g)
{
case MALE:
printf("male\n");
break;
case FEMALE:
printf("female\n");
break;
case UNKNOWN:
printf("unknown\n");
break;
}
return 0;
} 枚举可能取值的默认值从整数0开始依次递增,也可自行赋值
枚举的优点
- 增加代码可读性和可维护性
- 与宏定义相比,枚举有类型检查,更加严谨
- 防止命名冲突
- 易于调试
4、联合体
联合体:一种特殊的自定义类型,包含一系列的成员,特征是这些成员公用同一块空间
大小端字节序:
- 大端存储:低字节存在高地址处,高字节存在低地址处
- 小端存储:低字节存在低地址处,高字节存在高地址处
大小端存储的判断:
enum Endian
{
BIG_ENDIAN,
SMALL_ENDIAN
};
enum Endian Judge()
{
int i = 1;
char* p = (char*)&i;
if (*p > *(p + 1))
{
return SMALL_ENDIAN;
}
else
{
return BIG_ENDIAN;
}
}
int main()
{
enum Endian res = Judge();
if (res == SMALL_ENDIAN)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
} 2、联合体法
enum Endian
{
BIG_ENDIAN,
SMALL_ENDIAN
};
enum Endian Judge()
{
union Un
{
char c;
int i;
}u;
u.i = 1;
if (u.c == 1)
{
return SMALL_ENDIAN;
}
else
{
return BIG_ENDIAN;
}
}
int main()
{
enum Endian res = Judge();
if (res == SMALL_ENDIAN)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
} 联合体大小:
- 至少为最大成员的大小
- 当最大成员的大小不是最大对齐数的整数倍时,应对齐至最大对齐数的整数倍
|