c语言_Day36_08_07
c语言_Day36_08_071、自定义类型
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;
}联合体大小:
[*]至少为最大成员的大小
[*]当最大成员的大小不是最大对齐数的整数倍时,应对齐至最大对齐数的整数倍
文档来源:51CTO技术博客https://blog.51cto.com/u_15285915/3308832
页:
[1]