影者东升 发表于 2021-8-8 13:19:34

c语言_Day36_08_07

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;
}联合体大小:

[*]至少为最大成员的大小
[*]当最大成员的大小不是最大对齐数的整数倍时,应对齐至最大对齐数的整数倍

文档来源:51CTO技术博客https://blog.51cto.com/u_15285915/3308832
页: [1]
查看完整版本: c语言_Day36_08_07