结构体【struct】

一.结构体定义

概念:结构体是由一系列不同或相同基本类型数据组合而成的新的复合数据集合,从而使这些数据项组合起来反应一个信息。

意义:结构体的使用为处理复杂的数据结构(如动态数据结构等)提供了有效的手段,而且,它们为函数间传递不同类型的数据提供了方便。

特点:

1.结构体类型是用户自行构造的;

2.它由若干不同的基本数据类型的数据构成。

3.它属于C语言的一种数据类型,与整型、实型相当。因此,定义它时不分配空间,只有用它定义变量时才分配空间。

4.结构体类型中的成员名可以与程序中的变量名相同,两者并不代表同一对象,编译程序可  以自动对他们进行区分。

结构体类型的定义:

一般形式

Struct  结构体名

{

数据类型  成员名1;

数据类型  成员名2;

……

};

①.先定义结构,再说明结构变量。这种是C语言中定义结构体类型变量最常见的方式。

Struct  结构体名

{

成员列表;

};

Struct 结构体名 变量名;

如:

[cpp] view plaincopy

1. struct Clerk  //职工信息

2. {

3.    long  num;

4.    char  name[20];

5.    int   age;

6. };

7. struct  Clerk  p1,p2; //变量p1和p2同为 Clerk结构类型。

也可以用宏定义使一个符号常量来表示一个结构类型, 例如:

[cpp] view plaincopy

1. #define CLERK struct Clerk

2. CLERK

3. {

4. Long  num;

5. char  name[20];

6. int   age;

7. };

8. CLERK  p1,p2;

②.在定义结构类型的同时说明结构变量。这种形式的定义为:

Struct  结构体名

{

成员列表;

} 变量名;

实例如:

[cpp] view plaincopy

1. struct Clerk

2. {

3. Long  num;

4. char  name[20];

5. int  age;

6. } p1,p2;

③.直接说明结构变量。这种形式的定义为:

Struct           // 没有结构体名

{

成员列表;

} 变量名;

例如:

[cpp] view plaincopy

1. struct

2. {

3. Long num;

4. char name[20];

5. int age;

6. }  p1,p2;

二.结构体的大小:

一个结构体变量占用内存的实际大小,可以利用sizeof来求出。它的运算表达式为:

Sizeof(运算量)  //求出给定的运算量占用内存空间的字节数

其中运算量可以是变量、数组或结构体变量,可以是数据类型的名称。

例如:

Sizeof(struct clerk)

Sizeof(p1)

三.结构体类型嵌套

结构体类型中可包含以定义的结构体类型。

[cpp] view plaincopy

1. struct date{

2. int month;

3. int day;

4. int year;

5. } ;

6. struct Clerk

7. {

8. Long  num;

9. char  name[20];

10. struct date  birthday;

11. } ;

变量定义:如:struct Clerk p1,p2;

成员引用:p1.num, p1.name,

P1.bd.year , p1.bd.month, p1.bd.day

初始化:struct clerk p={0017482, “Li shan”,{1986,6,15}};

△注意:结构体类型和变量也有全局和局部之分

定义在所有函数之外的结构体类型(变量)称为全局(或外部)结构体类型(变量)。

定义在函数内部的结构体类型(变量)称为局部(或内部)结构体类型(变量)。

结构体类型一般定义为全局的,定义位置一般在主函数之前。

结构体变量初始化时,初始值类型对应成员的数据类型一致,否则会出错。

四.结构体变量的初始化

与其他类型变量一样,也可以给结构的每个成员赋初值,这称为结构体的初始化。一种是在定义结构体变量时进行初始化。语法格式如下:

Struct  结构体名 变量名={初始数据表};

另一种是在定义结构体类型时同时进行结构体变量的初始化。

Struct  结构体名

{

成员列表;

}变量名={初始数据表};     如:

[cpp] view plaincopy

1. struct Clerk

2. {

3. Long  num;

4. char  name[20];

5. struct date  birthday;

6. } p1={0017482, “Li shan”,{1986,6,15}};

还有一种是在main函数中进行初始化。

Struct 结构体名 变量名;

变量名.成员名 = 数值;

变量名.成员名 = 数值;

……

[cpp] view plaincopy

1. Struct  clerk  p2;

2. P2.num = 0017482;

3. P2.name =” lishan”;

4. P2.birthday = {1986,6,15}};

五.结构体数组

§1.结构体数组的定义

**具有相同结构体类型的结构体变量也可以组成数组,即为结构体数组。结构体数组的每一个数组元素都是结构体类型的数据,他们都分别包含各个成员项。

其定义形式如下:

Struct  结构体名

{

成员列表;

};

Struct  结构体名  数组名[元素个数];

[cpp] view plaincopy

1. Struct  student

2. {

3.  Char  name[20];

4.  Char  sex;

5.  Int    age;

6.  Char  addr[20];

7. };

8. Struct  student stu[3];

§2.结构体数组的初始化

Struct  结构体名

{

成员列表;

};

Struct  结构体名  数组名[元素个数]={初始数据表};

OR

Struct  结构体名

{

成员列表;

} 数组名[元素个数]={初始数据表};

§3.结构体数组的使用

一个结构体数组的元素相当于一个结构体变量,因此有关结构体变量的规则也适用于结构体数组的元素。

⑴.引用某一元素中的成员。

如要引用数组第一个元素的name成员,则可写为:

stu[1].name

⑵.可以将一个结构体数组元素赋值给同一结构体类型的数组的另一个元素,或赋给同一类型的变量,如:

Struct  student  stu[3] , student1;

现在定义了一个结构体类型的数组,它有3个元素,又定义了一个结构体类型变量student1,

则下面的赋值是合法的。

Student1 = stu[0];

Stu[0] = stu[1];

Stu[1] = student1;

⑶.不能把结果体数组元素作为一个整体直接进行输入输出。如:

Printf(“.......”,stu[0]);

scanf(“.......”,&stu[0]);

都是错误的。

只能是以单个成员为对象进行输入输出,如:

scanf(“.......”,&stu[0].name);

scanf(“.......”,&stu[0].num);

Printf(“.......”,stu[0].name);

Printf(“.......”,stu[0].num);

六.结构体指针

△1.指向结构体变量的指针

结构体变量所占内存的首地址称为结构变量的指针。

结构体指针变量的定义:

Struct结构体名称*结构体指针变量名;

例如

[cpp] view plaincopy

1. Struct  clerk

2.    {

3.        Long num;

4.        Char name[20];

5.        Struct data bd;

6.     }a,*pa;

例如:

[cpp] view plaincopy

1. struct  clerk b,*pb;

注意:结构体指针变量必须先赋值后使用。

△2.结构体指针变量赋初始值

将结构体变量的首地址赋给指针变量,如:

Struct clerk a,*pa=&a;

Struct clerk b,*pb;

pb=&b;

△3.通过结构体指针变量引用结构体成员

一般形式:(*指针变量).成员名

如:(*pa).num=10;     等价于  a.num=10;

Get((*pa).name);    等价于  get(a.name);

(*pa).bd.year=1986;  等价于   a.bd.year=1982;

△4.指向运算符:“->”直观地引用结构体成员。

例如:上例可改写为:

pa->num=10; get(pa->name);pa->bd.year=1986;

△5.指向结构体数组的指针

#结构体数组的首地址,称为结构体数组的指针。例如

[cpp] view plaincopy

1. Struct  clerk

2. {

3.    Int num;

4.    Char name[20];

5.    Struct date birthday;

6. }a[3],*p;

或:struct  clerk a[3],*p;

P=a;

则:p->a[0];p+1->a[1];p+2->a[2];

#通过指针访问数组元素的成员:

P->num=10;  等价于  a[0].num=10;

scanf(“%s”,p->name);   等价于   scanf(“%s”,a[0].name);

如果:p++;则 p->a[1];

p->num=10;    等价于    a[1].num=10;

[cpp] view plaincopy

1.

2. /* 应用举例:利用指向结构体的数组的指针输出结构体数组*/

3. struct clerk

4. {

5. int num;

6. char name[20];

7. int  age;

8. char  addr[40];

9. };

10. int main()

11. {struct clerk *p, a[3]={{101,"zhangsan",26,"shanghai"},

12.                          {102,"lishan",27,"hubei"},

13.                          {103,"wangwu",28,"changsha"}};

14. int i;

15. for(i=0,p=a; i<3;i++,p++)

16.   printf("%d,%s,%d,%s\n",p->num,p->name,p->age,p->addr);

17. }

18.

七.如何取出结构体变量中的每一个成员?

总结三种方法:①.结构体变量.成员名

②.(*指针变量).成员名

③.结构体变量—>成员名

八.结构体变量和结构体指针变量作为函数参数传递的问题。

#结构体变量做函数参数

[cpp] view plaincopy

1. struct  clerk

2. {

3.   int  num;

4.   char name[20];

5.   int  age;

6.   char addr[40];

7. };

8. void func(struct clerk a);

9. int main(void)

10. {

11. struct clerk a={101,"zhangsan",26,"shanghai"};

12. func(a);

13. }

14. void func(struct clerk b)

15. {

16. printf("%d,%s,%d,%s\n",b.num,b.name,b.age,b.addr);

17. }

#结构体指针作函数参数:赋地址传递

[cpp] view plaincopy

1. struct  clerk

2. {

3. int num;

4. char name[20];

5. int age;

6. char addr[40];

7. };

8. void output(struct clerk*p);

9. int main(void)

10. {

11. struct clerk*p,a[3]={{101,"zhangsan",26,"shanghai"},

12.                       {102,"lishan",27,"hubei"},

13.                       {103,"wangwu",28,"changsha"}};

14. p=a;

15. output(p);

16. }

17. void output(struct clerk *p)

18. {

19. int i;

20. for(i=0;i<3;i++,p++)

21. printf("%d,%s,%d,%s\n",p->num,p->name,p->age,p->addr);

22. return 0;

23. }

结构体变量作为函数参数数据传递方式是赋值传递(单向值传递),实参把它每一个的成员的值依次传递形参,运行时间与存储空间的开销很大,程序运行效率很低。实际应用中,一般使用结构体指针作为函数参数。

时间: 2024-08-01 14:40:46

结构体【struct】的相关文章

C语言结构体-struct

知识点: 1)结构体的定义. 2)结构体的sizeof. 3)  结构体的指针. 1) 结构体的定义: 在逻辑上有一定关联的多个数据类型做为一整体进行操作的数据结构,它的关键字是struct.下面我将定义一个结构体 struct Student{ char *name; int age; int sid; }; 我用上面定义的结构体Student来定义一个变量. struct Student student; 上面的代码有点烦,其实我可以这样写 struct Student{ char *nam

C语言 - 结构体(struct)比特字段(:) 详细解释

结构体(struct)比特字段(:) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26722511 结构体(struct)能够使用位字段(:), 节省空间, 例如以下面代码, 结构体a中的, 第一个变量x占用1个字符, y占用2个字符, z占用33个字符(越界); 可是sizeof()会自己主动补齐, 如x+y一共占用4个字节, z占用8个字节, 所以结构体占用12个字节; 当使用加法运算时, 会初始化为0; 代码

关于c#的结构体struct与class的区别

C# 结构体 struct C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员. 结构和类的区别: 1.结构是值类型,它在栈中分配空间:而类是引用类型,它在堆中分配空间,栈中保存的只是引用. 2.结构类型直接存储成员数据,让其他类的数据位于对中,位于栈中的变量保存的是指向堆中数据对象的引用. C#中的简单类型,如int.double.bool等都是结构类型.如果需要的话,甚至可以使用结构类型结合运算符运算重载,再为C#语言创建出一种新的值类型来.

结构体struct sockaddr_in, struct sockaddr,struct in_addr

一.结构体 struct sockaddr_in,  struct sockaddr,  struct in_addr struct sockaddr_in,  struct sockaddr,struct in_addr,这是网络编程中常用的结构体,每次都记不住它们各自的成员是啥,需要临时查,为方便以后的查看,在这里总结下. struct sockaddr {unsigned short sa_family;  /* 地址族, AF_xxx */char sa_data[14];  /* 14

C# 结构体 struct

C# 结构体 struct C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员. 结构和类的区别: 1.结构是值类型,它在栈中分配空间:而类是引用类型,它在堆中分配空间,栈中保存的只是引用. 2.结构类型直接存储成员数据,让其他类的数据位于对中,位于栈中的变量保存的是指向堆中数据对象的引用. C#中的简单类型,如int.double.bool等都是结构类型.如果需要的话,甚至可以使用结构类型结合运算符运算重载,再为C#语言创建出一种新的值类型来. 由于结构

获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf

转载请注明出处:windeal专栏 Linux 下 可以使用ioctl()函数 以及 结构体 struct ifreq  结构体struct ifconf来获取网络接口的各种信息. ioctl 首先看ioctl()用法 ioctl()原型如下: #include <sys/ioctl.h> int ioctl(int fd, int request, ...); 参数: fd     : 文件描述符 request:  表示要请求的信息.如IP地址.网络掩码等 ...     :  后面的可变

Swift中元组(Tuples),结构体(Struct),枚举(Enums)之间的区别

Swift有许多种存储数据方式,你可以用枚举(enums),元组(tuples),结构体(structs),类(classes),在这篇文章中我们将比较枚举.元组.结构体之间区别,首先从最简单的开始-元组(tuples). 元组(tuple) 元组是多个值组成的复合值类型,例如,你可以定义一个含有整形和字符串的tuple let amout=(100,"EUR") 当你函数需要返回多个值时,元组这个时候非常有用,你可以使用下标方式来访问元组中的值,如.0,.1以此类推,如下: let

APUE学习笔记——4.2结构体 struct stat 及其相关函数介绍

以下不少内容来自man手册 结构体struct stat 结构体struct stat用于保存文件相关的所有信息. struct stat的基本成员如下所示 struct stat { dev_t st_dev; // 文件所在设备的设备id,可以分解为主设备号和此设备号 ino_t st_ino; // inode号 mode_t st_mode; // 文件的类型.存取权限等 nlink_t st_nlink; // 文件硬连接数 uid_t st_uid; // 文件拥有者的用户id gi

修改Dictionary或List中结构体struct值的问题

问题:修改Dictionary中结构体struct值的值,如果直接用Dictionary[key].a += XX;(a为结构体中某数值型属性) ,则会报错: 无法修改.Dictionary<int,struct>.this[int]”的返回值,因为它不是变量 如果用一个变量承接Dictionary[key]中的结构体,即struct newStr =Dictionary[key],然后再做出修改:newStr.a += XX,则Dictionary中对应的结构体的值不发生变化.(由此可判断结

内核中用于数据接收的结构体struct msghdr(转)

内核中用于数据接收的结构体struct msghdr(转) 我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,ping另一台主机172.16.48.1.我们使用系统调用sendto发送这个icmp包. ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);