自定义类型

enum枚举

枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。
它是一种用户定义的数据类型,它用关键字enum以如下语法来声明:enum 枚举类型名字,{名字0,…,名字n};第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1 (这个是可以自定义成员值的)。

在C 语言中,枚举类型是被当做 int 或者 unsigned int 类型来处理的

枚举也是一种数据类型,所以它和基本数据类型一样也可以对变量进行声明,枚举也可以用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明。

1、同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量。
2、枚举成员)是「常量」而不是变量,因为枚举成员是常量,所以不能对它们赋值,只能将它们的值赋给其他的变量。
3、枚举类型的定义和变量的声明分开:如果对枚举型的变量赋整数值时,需要进行类型转换。

struct 结构体

结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员,结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。

声明定义结构体:
struct关键字+结构体的标志名+{大括号里边是成员}+后面的声明此结构变量+末尾分号

无名结构体: 可以定义无名结构体类型的变量。编译器对无名结构体的处理是随机生成一个不重复的变量名。
无名结构的定义方式就是定义无名结构体时必须定义该结构体类型的至少一个变量。

1、结构体本身并不会被作为数据而开辟内存,真正作为数据而在内存中存储的是这种结构体所定义的变量。
2、先声明结构体类型,再定义该类型的变量,声明结构体类型,不分配空间定义结构体类型变量,就要分配内存空间。
3、结构体变量不能相加,相减,也不能相互乘除,但结构体可以相互赋值,也就是说,可以将一个结构体变量赋值给另一个结构体变量。但是前提是这两个结构体变量的结构体类型必须相同。
4、结构体的运算:要访问整个结构,直接用结构变量的名字,对于整个结构,可以做赋值,取地址,也可以传递给函数参数。

结构体内存对齐

结构体的对齐规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8 Linux中的默认值为4

  1. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  2. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

可以通过预编译命令#pragma pack(n)来改变这一系数,其中的n就是要指定的“对齐系数”。

结构体数组

指数组中的每个元素都是一个结构体。如struct student tp[10];
结构体数组的初始化与数值型数组的初始化是一样的,数值型数组初始化的方法和需要注意的问题在结构体数组的初始化中同样适用,因为不管是数值型数组还是结构体数组都是数组。

结构体指针

和数组不同,结构变量的名字并不是结构变量的地址,必须使用&运算符。
strcut node *tp=&nb; 指针一般用->访问结构体里边的成员。

这 2 种形式是等价的: (*指针变量).成员名。 指针变量->成员名

结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间。结构体变量才包含实实在在的数据,才需要内存来存储。所以用一个结构体去取一个结构体名的地址,这种写法是错误的,也不能将它赋值给其他变量。

结构体数组的每一个元素都是一个结构体变量。如果定义一个结构体指针变量并把结构体数组的数组名赋给这个指针变量的话,就意味着将结构体数组的第一个元素(即第一个结构体变量的地址),也即第一个结构变量中的第一个成员的地址赋给了这个指针变量。

union 联合体

几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中 以关键字union声明的一种数据结构,这种被称作“共用体”类型结构,也叫联合体。

“联合”与“结构”有一些相似之处。但两者有本质上的不同。在结构中各成员有各自的内存空间,一个结构体变量的总长度大于等于各成员长度之和。而在“联合”中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度。

1、不能把共用体变量作为函数参数,也不能是函数带回共用体变量,但可以使用专用指向共用体变量的指针。
2、所有成员占用同一段内存,修改一制个成员会影响其余所有成员。

共用体的访问:共用体访问成员的值时一般使用点.运算符,指针时用->运算符(和结构体是一样的)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QVariant 是 Qt 中的一个通用的值类型,可以用来存储各种类型的数据,包括基本类型、用户自定义类型、甚至指针等。但是,如果要在 QVariant 中存储用户自定义类型的对象,需要实现 QVariant::Type 类型的转换函数。这个转换函数的基本要求是将自定义类型转换为 QVariant,并将 QVariant 转换回自定义类型。这个过程可以称为类型注册,它将自定义类型与 QVariant 类型关联起来,使得 QVariant 在遇到这种类型时可以正确地进行操作。 要完成 QVariant 自定义类型的实现,首先需要了解 QVariant 的内部实现机制。QVariant 内部使用了一个类似于 Variant 类的黑盒子来存储各种类型的值,在存储、获取、转换值时,需要使用 QVariant 内部提供的接口来进行操作。 接着,将自定义类型与 QVariant 类型进行关联,用户需要实现 QVariant::Type 类型的转换函数。这个函数的实现方式取决于自定义类型的实现机制,可以使用 QVariant 提供的模板类型来序列化与反序列化自定义类型,或者手动实现这些转换函数。 完成了自定义类型与 QVariant 类型之间的关联,就可以将自定义类型的对象存储到 QVariant 中了。存储时,需要将自定义类型的对象转换为 QVariant 类型,这里需要使用 QVariant::fromValue 函数。获取时,则需要将 QVariant 类型转换为自定义类型,这里可以使用 QVariant::value 函数,并传入自定义类型的 TypeId。 总之,QVariant 自定义类型的实现需要实现 QVariant::Type 类型的转换函数,并将自定义类型与 QVariant 类型关联起来,实现自定义类型与 QVariant 类型之间的转换。在实际的应用中,需要根据自定义类型的实现机制来选择相应的序列化与反序列化方式,以便正确存储、获取自定义类型的对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值