结构,联合和枚举

454 阅读5分钟

《c程序设计现代方法》读后笔记

结构的成员在内存中是按照声明的顺序存储的。结构体part1的位置就是第一个成员的首位置,再根据成员的数据类型决定他们各自占据多大内存。

struct {
int a;
char b[20];
}part1 ={528,"zrr"},
part2={333,"ZRR"};

结构变量可以在声明的同时进行初始化,但是初始化的值必须按照结构体成员的顺序写,且用于初始化的表达式必须是常量,剩余的成员用0作为它的初始值。

结构成员的值是左值,所以可以写在等号左边赋值或者成员++(这没搞懂加加是指向下一个成员还是数值增加);

左值是可以当右值使用的。(这里还有种思路是因为part12是结构变量!变量)所以可以part2=part1;把1的成员内容赋值给2;

除了赋值,不能用其它运算操作,尤其是==或!=;

类型定义:

typedef int B;
B flag;

B现在可以和内置的类型名一样去声明变量,强制类型转换或其它;

这样一方面可以使程序更好理解(我们可以对相似属性的变量声明一样),另一方面,如果要改动这些变量的数据类型更方便。

结构类型的声明:

重复的结构信息使程序膨胀,我们于是为结构的类型命名,而不是为结构变量命名。

struct part{...};//第一种
struct part part1;
struct part part1={...};
struct part{...}part1;
part1=part2;

typedef struct {...}part;//第二种
part part1;

void printf(struct part p){
struct part p2=p;//这是可行的
p.name;
p.age};//作为参数
printf(part1);

struct part builidpart(char name){ //返回值为结构体
struct part p;
p.name=name;
return p};

用指向结构的指针代替结构;

结构嵌套结构

struct name{
char firstname[5];
char middlename[5];
char lastname[5];

};
struct p {
struct name name1;
int i;
}p1;
p1.name1.firstname//引用时
struct name name2;
p1.name1=name2;

结构嵌套结构的优点有更容易把成员的特性使用,当作一个单元.

display(p1.name1);

具有结构类型的数组:

struct part index[100];有100种原件;

赋值:index[1].number=9;

index[1].name[0]='\0';

结构数组初始化:

const struct part index[]={//这个大括号是数组的
{"ab",1}//这个大括号是结构体的
,{"cd",2}};

C 库函数 int isspace(int c) 检查所传的字符是否是空白字符。如果 c 是一个空白字符,则该函数返回非零值(true),否则返回 0(false)。

EOF end of file

联合

结构变量和联合变量只有一处不同:结构变量都是存储在不同的内存地址中,而联合则时在同一内存地址中。

成员之间互相交迭,改变一个成员就会改变之前存储在任何其他成员之间的值,所有把联合想象成只能存储一个成员的地方。

初始化

u{
int i;
float f;}u={0};//i为0;

联合的应用

1.节省空间

设计一个礼品的结构体,该礼品有书籍,杯子,衣服,分别对应不同单品信息

可以在礼品结构体里:

union{
struct{
char title[title_len+1]}book;
struct{}mug;
struct{}cloth;}item;

调用时候,c(结构名字).item(结构的联合成员的名字).book(联合的结构成员的名字).title(该结构的成员名)

2.可以创建含有不同数据类型的数据结构

typedef union{
int i;
float f;}Number;

Number number_array[10];
number_array[1].i=1;
number_array[2].f=1.0;

现在数组也可以包含不同类型的成员。

标记字段:寻找简便方法判断联合改变后最后的成员


#define int_kind 0
#define float_kind 1

typedef {
int kind;

enum{int_kind,float_kind}kind;

union{
int i;}u;
}n;
n.kind =int_kind;//对联合成员赋值时加上这一步
n.u.i=1;

if(n.kind==int_kind){  }
else //判断时这样判断

枚举

枚举不像结构和联合,枚举常量的名字必须不同于闭合作用域内声明的其他标识符。

枚举常量自由选择不同的值,不同枚举常量选择相同的值也是合法的。

1.enum suit {a,b,c,d};

enum suit s1,s2;

2.typedef enum {a,b,c,d}suit;

suit s1,s2;

当没有为枚举常量指定值时候,它的值是一个大于前一个常量值的值,默认第一个枚举常量的值是0。

enum colors{black,gray,orange=15,red};

0,1,15,16;


当试图用sizeof确定结构中的字节数时,获得的数大于成员加在一起的字节数,是因为一些计算机要求数据项从某个数量字节(一般四个)倍数开始,char a,a后将跟3个字节的空洞(无用字节),c标准只允许在成员之间或最后一个成员后面有空洞,保证第一个成员的地址和整个结构的地址一样,所以用==判断两个结构是否相等是不合法的,逐个比较没有意义(如果打乱顺序了),比较总字节数(结构若含有空洞,比较则无意义;对应成员即使值相同,空洞中的废弃值也可能不同,而初始化空洞(使他们都为0),着影响结构的程序的性能)。

把结构声明放在头文件,在需要的地方包含头文件,就可以多个文件共享结构类型了。