结构变量用作函数参数
结构变量做为一种变量类型,完全可以用于函数参数。如果直接把 结构名做为参数,那么根据传值特性,函数调用时,
会为其开辟一部分内存单元,并完成copy值的传递。如果结构变量很庞大,就会很浪费。
还有一种方式,函数参数是: 一个指向struct的指针。这样在函数体内,我们可以使用 px->成员来进行访问。
此时实参---》形参只需要传递一个指针变量,大幅缩小。但我们知道,传递指针有一个坏处,就是函数体内
若修改成员内容,就会真实的反馈到 实参中。需要特别注意、
实参和形参
实参是真实声明的变量参数。
形参是函数调用时,参数列表中的参数。 它只在函数被调用时,才被分配内存单元。函数调用完之后,这个内存位置会被释放。
形参的值,均是所用实参的copy值。并不会改变实参自身。
有一点比较特殊:如果形参是一个数组名、指针,因为它们具有间接访问的特性。 实参copy值--> 形参。 在函数体中若执行
间接操作,操作的将是真实的物理地址,故而看上去 数组内容、指针指向内容被修改了。这一切只是 间接访问作怪,
传参依旧是 实参的copy-->形参。
位段
什么是位段?
Struct CHAR {
Unsigned ch : 7 ;
Unsigned font : 6 ;
Unsigned size : 19;
} my_reg;
位段是结构变量的一种特殊形式。它不是n个类型变量的组合。而是n个 位的组合。用于把位拼接成一个整体。
位段需要借助: struct结构声明。 总长度最好不超过 sizeof(int) 。
歧义: 位段不是很常用,因为移植性不好。编译器对于 总长度超过sizeof(int)的部分 处理机制不一样。
分配位顺序也不一样。有的从右向左排列位,有的从左向右排列。
好处: 如果十分清楚以上问题,那么位段能减少内存的浪费。 6 + 7 需要2byte. 19需要4byte ,放一起这样就能省2byte。
访问: 跟结构变量一样 。 my_reg.size = xxxxx ;
我们声明了 my_reg之后, 依然可以使用 my_reg | (0x1) ;置最低位。
联合
结构变量,是把所有 相关信息汇总,且相互独立存在。
类型 |
正方形 |
圆形 |
边长l |
L |
- |
半径r |
- |
r |
面积 |
当我们填写表格的时候,时常出现二选一填写的情况。正方形需要填写边长,原型需要填写半径。
在C语言中,我们需要创建: 类型、边长、半径、面积。四个位置。但是考虑到 正方形只需要填入 边长、无需半径、
圆形只需要半径、无需边长。可以将这两个共享一个位置。变成:
类型 |
正方形 |
圆形 |
边长(半径) |
L |
r |
面积 |
联合体就是为了这种情况而生.
Union {
Float length ;
Float radius ;
} len ;
Len是一个联合体,声明时只分配一个内存。 Length、radius共享此位置。这两个值不会同时存在,这是肯定的。
枚举类型 :
既然说道这个地方,我们就先说下枚举类型。补补前面挖的坑.
enum type {square、round} my_type ; 声明一个枚举—type型 的变量my_type。
My_type的值只取 square 、round 两者其一。
枚举类型仅仅是一种特殊一点的变量而已: 其特殊性在于,不像int 有取值范围。 枚举变量的值只取枚举出来的几个值。
即把该变量的值范围一一枚举出来了。
举例子 :
enum Weekday { Sun , Mon ,Tue ,Wednesday ,Thursday ,Fri,Satu } ;
这里只声明了一类 enmu体。归属于该类型的变量,值只取枚举列表内的。我们可以使用 enum Weekday my_week;
自己定义一个变量my_week,它是一个枚举类型的变量。其值在 Sun , Mon ,Tue ,Wednesday ,Thursday ,Fri,Satu
之间。对其赋值 可以使用 my_week = Satu; my_week = (enum Weekday) 7; 这两者是等价的。
回到上面的表格:
我们在C中定义一个 结构:
Struct example { enum type {square,round} my_type ; Union { Float length ; Float radius; } len ; Float size ; } my_table ;
我们定义了一个结构体变量,名称为my_table , 它由枚举参数、一个联合体参数、一个float变量组成。
当我们输入信息时: round 0.8 时,会把0.8当成半径存储; 当输入 square 1.2时,会当成正方形处理。
If(my_table.my_type == square) { my_table. Len .length = 1.2 ; my_table.size = 1.2*1.2 ; } else If(my_table.my_type == round) { my_table. Len .length = 0.8 ; my_table.size = π*0.8*0.8 ; }