C语言结构体的一些总结

来源:互联网 发布:2015年网络作家富豪榜 编辑:程序博客网 时间:2024/06/01 21:56

struct结构体的总结
一.声明与定义
1.声明:
例如建立一个图书的结构体,包括书的名字,书的作者以及价格
struct book{
char title[20];
char author[20];
float value;
};
需要注意的是声明结构体时只是声明了一种类型,并未创建实际的数据对象,并没有分配内存;
结构体声明可以放在一个函数的外部,也可以放在一个函数内部,表示不同的作用域。
2.定义:
struct book library; //创建了一个结构变量library,并分配内存;
3.初始化一个结构:
struct book library={
“The Pious Private and the Devious Damsel”,
“Renee Vivotte”,
1.95
};
简而言之,我们使用在一对花括号中括起来的初始化列表进行初始化,各初始化项用逗号分隔。
4.访问结构成员:
点(.)成员运算符;
如library.title, library.author;
要注意如果对结构体中一个成员取地址:
&library.float;
(.)运算符的优先级比&高,所以不加括号;
5.结构的初始化器:
C99和C11为结构提供了指定初始化器,例如,只初始化book结构的value成员,可以这样做:
struct book surprise = {.value=10.99};
可以按任意顺序使用指定初始化器:
struct book gift{
.value=25.99,
.author=”James Broadfool”,
.title=”Rue for the Toad”
};

二. 结构数组
1.声明结构数组
struct book library[10];
2.标识结构数组中成员
library //一个book结构数组;
library[2] //一个数组元素,该元素是book结构;
library[2].title //library[2]的title成员;
library[2].title[4] //library[2]的title成员的一个字符;

三.嵌套结构
第一个结构:
struct names{
char first[20];
char last[20];
};
第二个结构:
struct guy{
struct names handle;
char favfood[20];
char job[20];
float income;
};
struct guy fellow;
如果要访问嵌套结构的成员,使用两次点运算符:
fellow.handle.first;

四.指向结构的指针
1.以上面的guy结构为例,声明结构指针:
struct guy* him;
如果a是一个barney是一个guy类型的结构,可以这样写:
him = &barnery;
和数组不同的是,结构名并不是结构的地址,因此要在结构名前面加上&运算符;
2.关于结构的大小:根据我个人的理解,不同编译器的实现不一样:有的按最大类型对齐,有的按4字节对齐;
3.用指针访问成员:
如果him==&barnery;
那么 him->income
(him).income //.运算符优先级比 高,所以必须加括号
都是barnery.income

五.其他结构特性
1.可以把一个结构赋给另一个结构,例如n_data和o_data都是相同类型的结构,可以这样做:
o_data = n_data; //把一个结构赋值给另一个结构;
这条语句把n_data的每个成员的值都赋给o_data相应成员,即使成员是数组,也能完成赋值;

还可以把一个结构初始化为相同类型的另一个结构:
struct names right_field={“Ruthie”,”George”};
struct names captain = right_field;
2.结构中的字符数组与字符指针
struct names{
char first[20];
char last[20];
};

struct pnames{
char*first;
char*last;
};
第二个结构pnames的两个结构成员是两个char*指针,共占8字节(32位)或16字节(64位),但是指针并未初始化,将一个字符串赋给它时,指向的地址可以是任意值,因此存在潜在的风险;
所以这种情况最好用malloc为这个指针分配内存,并用strcpy()函数将字符串复制到这块内存;

3.复合字面量和结构(C99)
语法是把类型名放在圆括号中,后面紧跟一个用花括号括起来的初始化列表:
(struct book) {“The Idiot”,”Fyodor Dostoyevsky”,6.99}

4.伸缩型数组成员(C99)
利用这项特性声明的结构,其最后一个数组成员具有一些特性:
1.该数组不会立即存在;
2.使用这个伸缩型数组成员可以编写合适的代码,就好像它确实存在并具有所需数目元素一样。
首先,声明一个伸缩型数组成员有如下规则:
1.伸缩型数组成员必须是结构的最后一个成员;
2.结构中必须至少有一个成员;
3.伸缩数组的声明类似于普通数组,只是他的方括号是空的。
struct flex
{
int count;
double average;
double scores[];
};
声明一个struct flex类型的结构变量时,不能用scores成员做任何事,因为没有给这个数组预留存储空间,实际上,C99的意图并不是让你声明struct flex类型的变量,而是希望你声明一个指向struct flex类型的指针,然后用malloc分配足够的内存空间,以储存struct flex类型结构的常规内容和伸缩型数组成员所需的额外空间。例如,假设用scores表示一个内含5个double类型值的数组,可以这样做:
struct flex*pf;
pf=malloc(sizeof(struct flex) +5*sizeof(double));

使用带伸缩型数组成员的结构有一些特殊的处理要求:
第一:不能用结构进行赋值或拷贝:
struct flex *pf1, *pf2;
* pf1=* pf2;
这样做只能拷贝除伸缩型数组成员以外的其他成员,确实要进行拷贝,用memcpy();
第二:不要用按值方式把这种结构传递给函数,原因是按值传递与赋值类似。要把结构的地址传递给函数;
第三:不要使用带伸缩型数组成员的结构作为数组成员或另一个结构的成员。

5.匿名结构(C11)
struct person
{
int id;
struct {char first[20];char last[20];};
};
初始化:
struct person ted={8483,{“Ted”,”Grass”}};
可以直接访问first成员:
ted.first;

原创粉丝点击