自定义类型

目录

一、结构体

1.1声明一个结构体

1.2结构体自引用

 1.2.1定义

1.2.2初始化

1.3内存对齐

1.3.1练习

1.3.2设置默认对齐数

1.3.3计算偏移量offsetof()

1.3.4总结

1.4结构体传参

1.5位段

二、枚举

1.1初始化

1.2优点

三、联合体

1.1定义

1.2计算联合体大小


一、结构体

1.1声明一个结构体

声明一个学生类型,目的是通过学生类型来创建学生变量(对象)  <---标签
    描述学生属性:姓名,电话,性别                    <---成员变量

//Stu为标签

struct Stu {

   //定义成员变量

   char name[20];

   char tel[12];             char sex[10];

};

//创建全局变量 struct Stu s2;

//Wor为标签

struct Wor {

        //定义成员变量

        char name[20];

        char tel[12];

        char sex[10];

}w1,w2,w3; //这个 w1,w2,w3 是全局变量

//匿名结构体变量
struct
{
    int a;
    int b;
    float c;
}x,*pa;

1.2结构体自引用

 1.2.1定义


//代码1
struct Node{
    int data;
    struct Node*next;
};
//代码2
typedef struct Node{
    int data;
    struct Node* next;
}Node;

1.2.2初始化


#include <stdio.h>
struct S
{
    char c;
    int a;;
    double d;
    char arr[20];
};
int main()
{
    struct S s = {'c',1,1.0,"hello"};
    printf("%c %d %lf %s",s.c,s.a,s.d,s.arr);
}

1.3内存对齐

1.第一个成员在与结构体变量偏移量为0的地址处
2.其他成员变量要对其某个数字(对齐数=编译器默认的对齐数与该成员大小的较小值)的整数倍地址处
3.结构体总大小为最大对齐数(每个成员变量头有的一个对齐数)的整数倍
4.如果嵌套了结构的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

1.3.1练习
//1.请输出下列结果
#include <stdio.h>
struct S1
{
    char c1;
    int a;
    char c2;
};
struct S2
{
    char c1;
    char c2;
    int a;
};
int main()
{
    struct S1 s1 = {0};
    printf("%d\n", sizeof(s1));//12
    struct S2 s2 = {0};
    printf("%d\n", sizeof(s2));//8
    return 0;
}

如下图:

//2.请输入下列结果
#include <stdio.h>
struct S2
{
    double c1;
    char c2;
    int a;
};
 struct S3
{
    char c1;
    struct S2 s2;
    double c2;
};
int main()
{
    struct S3 s3;
    printf("%d\n", sizeof(s3));//32
    return 0;
}

如图所示:

1.3.2设置默认对齐数
#include <stdio.h>
#pragma pack(1)
struct S
{
    char c1;
    int d;
};
int main()
{
    struct S s;
    printf("%d", sizeof(s));//8 修改后->为5
}
1.3.3计算偏移量offsetof()
#include <stdio.h>
#include <stddef.h>

struct S
{
    char c;
    int i;
    double d;
};
int main()
{
    printf("%d\n",offsetof(struct S,c));//0
    printf("%d\n",offsetof(struct S,i));//4
    printf("%d\n",offsetof(struct S,d));//8
    return 0;
}
1.3.4总结

要满足对齐,又要节省空间,要将占用空间空间较小的尽量集中在一起

1.4结构体传参

#include <stdio.h>
struct S
{
    char name;
    int age;
    char sex;
};
void init1 (struct S *tmp)
{
    tmp->name = 'w';
    tmp->age = 100;
    tmp->sex = 'n';
}

void print1(const struct S* tmp)
{
    printf("%c %d %c",tmp->name,tmp->age,tmp->sex);
}
void print2(struct S tmp)
{
    printf("%c %d %c",tmp.name,tmp.age,tmp.sex);
}
int main()
{
    struct S s ={0};
    //初始化
    init1(&s);
    //传参
        // 【传地址】
    print1(&s);
        // 【传参数】
    print2(s);
    return 0;
}

1.5位段

//位段->节省空间
//位段不跨平台的(最大位不确定、左向右分配不确定)
#include <stdio.h>
struct S
{
    int a : 2;//a只需要2个bit位
    int b : 5;//b只需要5个bit位
    int c : 10;//c只需要10个bit位
    int d : 30;//d只需30个bit位     要 <= 32bit
};
struct S1
{
    char a : 2;//a只需要2个bit位
    char b : 5;//b只需要5个bit位
    char c : 4;//c只需要4个bit位
    char d : 8;//d只需8个bit位     要 <= 8bit
};

int main()
{
    struct S s;
    struct S1 s1;
    printf("%d\n", sizeof(s));
    //输出:8   2bit+5bit+10bit+30bit=17bit+30bit > 32bit   17bit + 30bit < 4byte + 4byte = 8
    printf("%d", sizeof(s1));
    //输出:3    2bit + 5bit <= 1byte ,4bit <= 1byte ,8bit <= 1byte
}

二、枚举

1.1初始化

enum Sex
{
    //枚举的赋值初始化
    MALE = 1,
    FEMALE = 2,
    SECRET = 8
};
enum Color
{
    //从0开始递增
    RED,//默认为0
    GREEN,//默认为1
    BLUE//默认为2
};

1.2优点

  • 增加代码的可读性和可维护性
  • 和#define定义的标识符(完全替换),比较枚举有类型检查,更加严谨
  • 防止了命名污染(封装)
  • 便于调试(在使用过程中间变量出问题,可直接找到错误位置)
  • 使用方便,一次可以定义多个常量

三、联合体

1.1定义

联合体(共用体-[共用同一块空间])
union un
{
    char c;//1字节    
    int i;//4字节
};
联合体至少是最大成员的大小,则un占4个字节
运用时,只能用一个与struct不同
//与struct定义方法基本一致,可以匿名,可以定义变量u
union
{
    char c;//1字节
    int i;//4字节
};
union
{
    char c;//1字节
    int i;//4字节
}u;

1.2计算联合体大小

//联合体计算
#include <stdio.h>
union U
{
    int a;//4本身占4字节,编译器默认8字节,占1个byte,最大对齐数为4,偏移4的整数倍
    char arr[5];//本身5个连续1字节,但算的话,要算[元素]字节占1一个byte,默认编译器8字节.最大对齐数为1
    //两者相加 4 + 1 < 8
};
int main()
{
    union U u;
    printf("%d", sizeof(u));//8
}

目录

一、结构体

1.1声明一个结构体

1.2结构体自引用

 1.2.1定义

1.2.2初始化

1.3内存对齐

1.3.1练习

1.3.2设置默认对齐数

1.3.3计算偏移量offsetof()

1.3.4总结

1.4结构体传参

1.5位段

二、枚举

1.1初始化

1.2优点

三、联合体

1.1定义

1.2计算联合体大小


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值