评论

收藏

[C++] c语言_Day36_08_07

编程语言 编程语言 发布于:2021-08-08 13:19 | 阅读数:540 | 评论:0

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;
}
DSC0000.png

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;
}
联合体大小:
  • 至少为最大成员的大小
  • 当最大成员的大小不是最大对齐数的整数倍时,应对齐至最大对齐数的整数倍

关注下面的标签,发现更多相似文章