赞
踩
1、结构体的定义
typedef struct tag {
member-list
} variable-list ;
创建一个别名为variable-list的结构体。其中struct是结构体关键字,tag是结构体的标志,member-list是结构体成员列表,variable-list是此结构体声明的变量。
一般情况下,tag、member-list、variable-list这三个部分至少要有2个。
注意只有结构体变量才会分配地址,结构体的定义是不分配地址的。结构体不能直接进行强制转换,只有结构体指针才能进行强制转换。
struct Book
{
char title[20];//一个字符串表表示的title题目
char author[20];//一个字符串表示的author作者
float value;//价格表示
};//这里只是声明 结构体的定义
struct Book book1,book2;//结构体变量的定义 分配空间
book1.value;//引用结构体变量
2、结构体的存储
结构体的整体空间是占用空间最大的成员类型所占字节数的整数倍。编译器会自动补齐。
struct S1
{
char a;
int b;
double c;
};
其中char a占用1字节,int b是4个字节,double c是8个字节。在定义char a和int b时,会先按4字节补齐,这两个定义就占用8个字节,在定义double c时,就不需要再进行补齐,因此整个结构体占用8+8=16个字节。
3、结构体变量初始化
在对结构体变量初始化时,要对结构体成员一 一赋值,不能跳过前面成员变量,而直接给后面成员赋初值,但是可以只赋值前面几个,对与后面未赋值的变量,如果是数值型,则会自动赋值为0,对于字符型,会自动赋初值为NULL,即‘\0’。
也可以在定义时直接赋值
struct Student
{
char name[20];
char sex;
int number;
}stu1={"zhaozixuan",'M',12345};
//或者
struct Student
{
char name[20];
char sex;
int number;
};
struct Student stu1={"zhaozixuan",'M',12345};
//注意字符为‘ ’ 字符串为""
也可以在定义结构体之后逐个赋值
stu1.name="王伟";
stu1.sex='M';
stu1.number=12305;
//也可用strcpy函数进行赋值
strcpy(stu1.name,"王伟");
或者定义之后任意赋值
struct Student stu1={
.name="Wang",
.number=12345,
.sex='W',
};//可以对任意变量赋值
4、结构体指针
指针指向的是变量所占内存的首地址,在结构体中,指针指向的是结构体变量的起始地址,当然也可指向结构体变量的元素
指向结构体变量的指针
定义形式一般为
struct 结构体名* 指针名;
比如: struct Student* p;
struct Student
{
char cName[20];
int number;
char csex;
}student1;
struct Student*p;
p=&student1;
//若为结构体数组则
struct Student stu1[5];
struct Student*p;
p=stu1;//因为stu1为结构体数组而p=stu1直接是指向stu1的首地址,就不用再加&符
用结构体指针变量访问结构体变量成员有以下三种方式:
p->cName
(*p).cName
student1.cName
p->number++; 是将结构体变量中number的值进行运算,然后再加一。
指向结构体数组的指针
想要用指针访问结构体数组的第n个数据时可以用
struct Student stu1[5];
struct Student*p;
p=stu[n];
(++p).number//是指向了结构体数组下一个元素的地址
5、结构体的嵌套
结构体可以有子引用和相互引用。
子引用:就是在结构体内部包含指向自身类型结构体的指针。
相互引用:就是在结构体中都包含指向其他结构体的指针。
struct tag_1{
struct tag_1 *A;
int value;
};
tips:关于使用typedef
typedef struct tag_1{
struct tag_1 *A;
int value;
}TAG;
没有使用typedef的话,在声明变量的时候必须是struct tag_1 t1;
若使用typedef的话定义的话,在声明变量时就可以TAG t1;相当于TAG==struct tag_1。
或者使用typedef,以下三种都可以。
typedef struct tag_1{ int value; struct tag_1 *link; } NODE; struct tag_2; typedef struct tag_2 NODE; struct tag_2{ int value; NODE *link; }; struct tag_3{ int value; struct tag_3 *link; }; typedef struct tag_3 NODE;
在自引用中定义的一个指向结构体的指针,看似是指向自身,其实是指向同一类型的不同结构。
链表和树的结构就都使用到此技巧。自身的结构体指针指向下一节点或者下一子树的地址。
有一种情况需要注意:
typedef struct { //这里是结构体类型定义
int a;
s_ref *b; //注意这句引用了结构体类型名
char c;
}s_ref ;
这个结构体类型定义是为了定义类型名s_ref,但却失败了。因为结构体中就引用了结构类型名,而此时还没定义类型名。
可以改为如下:
typedef struct s_ref_t{ //这里是结构体类型定义和结构体标签
int a;
struct s_ref_t *b; //注意这句与上面相同位置的区别,使用了标签
char c;
}s_ref ;
//(使用“不完全声明”) struct tag_a{ struct tag_b *bp; int value; }; struct tag_b{ struct tag_a *ap; int value; }; typedef struct tag_a A; typedef struct tag_b B; struct tag_a; struct tag_b; typedef struct tag_a A; typedef struct tag_b B; struct tag_a{ struct tag_b *bp; int value; }; struct tag_b{ struct tag_a *ap; int value; };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。