自定义类型下

简介: 自定义类型下

结构体传参


struct S
{
int data [ 1000 ];
int num ;
};
struct S s = {{ 1 , 2 , 3 , 4 }, 1000 };
// 结构体传参
void print1 ( struct S s )
{
printf ( "%d\n" , s . num );
}
// 结构体地址传参
void print2 ( struct S * ps )
{
printf ( "%d\n" , ps -> num );
}
int main ()
{
print1 ( s );   // 传结构体
print2 ( & s ); // 传地址
return 0 ;
}

上面的 print1 和 print2 函数哪个好些?

答案是:首选 print2 函数。

原因:

函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。

如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

结论

结构体传参的时候,要传结构体的地址。

位段


位段的声明和结构体是类似的,有两个不同:


位段的成员必须是 int、unsigned int 或signed int 。


位段的成员名后边有一个冒号和一个数字。


如图:


18374a4538b24a2992bd5721e28dd440.png


A就是一个位段。


计算:位段是按比特位的大小来进行计算的,比如一个字节有8个比特位,存入的时候根据数据类型的不同计算出相应的比特位依次往后存储,若存储不下则开辟下一个字节


举个例子:


1eee49a0a3a74b4fa7a887855b89300a.png




d172ac37003e4d5ca6fcb00f47047b03.png


那么8这个数字是怎么来的呢?是这样的:


int 型具有四个字节,共32个比特位,故存储时将前三个放入第一块空间中,由于第四个是30个比特位存储不下,因此开辟下一块空间存储,即开辟了两块空间,就是好8个字节。


注意:

和结构体相比,位段可以达到同样的效果,但是可以很好地节省空间,但是有跨平台的问题存在。


94d4d6c264f84ea3b6f3bfcad39574d9.png

跨平台问题:

枚举的声明

枚举顾名思义就是一一列举。把可能的取值一一列举。
比如我们现实生活中:

一周的星期一到星期日是有限的7天,可以一一列举

性别有:男、女、保密,也可以一一列举。

月份有12个月,也可以一一列举

这里就可以使用枚举了。先上代码:

enum Day // 星期
{
Mon ,
Tues ,
Wed ,
Thur ,
Fri ,
Sat ,
Sun
};
enum Sex // 性别
{
MALE ,
FEMALE ,
SECRET
} ;
enum Color // 颜色
{
RED ,
GREEN ,
BLUE
};

enum Day、enum Sex、enum Color都是枚举类型。

而{}里边的是枚举的可能取值,叫做枚举常量

这些可能取值都是有值的,默认从0开始,一次递增1。

当然,在定义的时候也可以赋初值。像这样:

enum Color // 颜色
{
RED = 1 ,
GREEN = 2 ,
BLUE = 4
};

枚举的优点

我们可以使用 define 定义常量,为什么非要使用枚举?

原因如下:
1. 增加代码的可读性和可维护性

2. 和define定义的标识符比较枚举有类型检查,更加严谨。

3. 防止了命名污染(封装)

4. 便于调试

5. 使用方便,一次可以定义多个常量

枚举的使用

enum Color // 颜色
{
RED = 1 ,
GREEN = 2 ,
BLUE = 4
};
enum Color clr = GREEN ; // 只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5 ;               //ok??

只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。

联合体

联合也是一种特殊的自定义类型

这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

比如:

// 联合类型的声明
union Un
{
char c ;
int i ;
};
// 联合变量的定义
union Un un ;
// 计算连个变量的大小
printf ( "%d\n" , sizeof ( un ));

联合体的声明

大小的特点:

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联

合至少得有能力保存最大的那个成员。

union Un
{
int i ;
char c ;
};
union Un un ;
// 下面输出的结果是一样的吗?
printf ( "%d\n" , & ( un . i ));
printf ( "%d\n" , & ( un . c ));
// 下面输出的结果是什么?
un . i = 0x11223344 ;
un . c = 0x55 ;
printf ( "%x\n" , un . i );

大小的计算:

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

union Un1
{
char c [ 5 ];
int i ;
};
union Un2
{
short c [ 7 ];
int i ;
};
// 下面输出的结果是什么?
printf ( "%d\n" , sizeof ( union Un1 ));
printf ( "%d\n" , sizeof ( union Un2 ));

以上就是我对自定义类型的相关讲解,讲解有不清楚或者讲错的地方,可以在评论区或者私信.看完记得点赞哦!!!  



相关文章
|
6月前
|
存储 Linux C++
自定义类型讲解
自定义类型讲解
81 0
|
5月前
|
存储 编译器 Linux
自定义类型详解(1)
自定义类型详解(1)
45 5
|
5月前
自定义类型详解(2)
自定义类型详解(2)
45 1
|
6月前
|
存储 移动开发 API
其他内置类型
本文介绍了 .NET 中的 Console 类和 Environment 类。Console 类提供了控制台输入输出的功能,如设置背景色和前景色、打印文本、读取行和发出蜂鸣声。而 Environment 类则包含有关全局环境的信息和方法,如当前目录、进程路径、处理器数量、操作系统信息等。另外,文章还提及了 .NET Framework 的 AppDomain(用于表示应用程序域,但在 .NET Core 中功能减弱)和 .NET Core 中新引入的 AppContext 类,用于存储全局数据和开关。
|
6月前
|
编译器 Linux C++
自定义类型详解
自定义类型详解
|
6月前
|
编译器 C++
自定义类型
自定义类型
|
6月前
|
C++
c++基本内置类型
c++基本内置类型
51 0
|
11月前
|
存储 算法 程序员
自定义类型总结
自定义类型总结
74 0
|
编译器 C++
自定义类型超详细解答!!!!!(上)
自定义类型超详细解答!!!!!
|
存储
自定义类型超详细解答!!!!!(下)
自定义类型超详细解答!!!!!