结构体(结构体嵌套结构体指针结构体参数传递)

Posted lanhaicode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构体(结构体嵌套结构体指针结构体参数传递)相关的知识,希望对你有一定的参考价值。

结构体(struct)

1、基本概念

结构体-----将不同类型的数据成员组织到统一的名字之下,适用于对关系紧密,逻辑相关、具有相同或不同类型的数据进行处理

2、结构体定义格式

struct 结构名(也可称作结构标识符)      

      {

      类型 变量名;

       类型 变量名;

       ······

      };

struct 结构名 结构变量;

或者

struct 结构名

       {

       类型 变量名;

       类型 变量名;

       ······

       }结构变量;

例:声明结构体类型的同时定义变量名

1 struct student
2 {
3   int num;
4 }teacher;

 

 定义了一个结构名为student的结构体和一个结构变量teacher,如果省略变量名(teacher),就变成了对结构的声明,上述结构体声明也可分开写

1 struct student
2 {
3   int num;
4 };
5 
6 struct student teacher;

 

与上面效果相同,可理解为struct student类似于int,而我们用的是teacher类似于变量,如果省略结构名,则称之为无名结构,这种情况常常出现在函数内部

1 struct
2 {
3   int num;
4 }teacher;

 

(在声明结构体时常常与typedef函数配合使用)

3、结构体成员的访问

访问结构体变量的成员必须使用成员选择运算符(也称圆点运算符),格式为:结构体变量名.成员名

若使用指针对结构体成员进行访问,格式为:指针->成员名 等价于 (*指针).成员名 

4、typedef函数

为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等),

(注意与#define的区别,typedef 是用来定义一种类型的新别名的,它不同于宏#define,不是简单的字符串替换)

例:

1 typedef int INTEGER;

 

 为int定义了一个新的名字INTEGER,也就是说INTEGER与int是同义词,也可以为结构体定义一个别名

1 typedef struct student STUDENT;

或者

1 Typedef struct student
2 {
3   int num;
4 }STUDENT;

上述两条语句是等价的,二者都是为struct student结构体类型定义了一个新的名字STUDENT,即STUDENT与struct student是同义词,所以下列两条语句等价

1 1 STUDENT stu1,stu2;
2 2 struct student stu1, stu2;

补充:

1 typedef struct tagNode
2 {
3     char *pItem;
4     pNode pNext;
5 } *pNode;

 

上述代码编译阶段会报错,原因:

在上面的代码中,新结构建立的过程中遇到了 pNext 声明,其类型是 pNode。这里要特别注意的是,pNode 表示的是该结构体的新别名。

于是问题出现了,在结构体类型本身还没有建立完成的时候,编译器根本就不认识 pNode,因为这个结构体类型的新别名还不存在,所以自然就会报错。

因此,我们要做一些适当的调整,比如将结构体中的 pNext 声明修改成如下方式:

1 typedef struct tagNode
2 {
3     char *pItem;
4     struct tagNode *pNext;
5 } *pNode;

 

或者将 struct 与 typedef 分开定义

1 typedef struct tagNode *pNode;
2 struct tagNode
3 {
4     char *pItem;
5     pNode pNext;
6 };

 

在上面的代码中,我们同样使用 typedef 给一个还未完全声明的类型 tagNode 起了一个新别名。不过,虽然 C 语言编译器完全支持这种做法,但不推荐这样做,建议改为

1 struct tagNode
2 {
3     char *pItem;
4     struct tagNode *pNext;
5 };
6 typedef struct tagNode *pNode;

 

5、typedef函数与#define函数

#define函数格式: 

#define 标识符 字符串,标识符成为宏名,宏替换时不做任何语法检查

1 typedef char* pStr1;
2 #define pStr2 char* 
3 pStr1 s1,s2;
4 pStr2 s3,s4;

 在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。

上例中#define语句应该写成 pStr2 s3, *s4; 

6、结构体嵌套

 就是在一个结构体内包含了另一个结构体作为其成员

 1 typedef struct date
 2 {    
 3     int year;
 4     int month;
 5     int day;
 6 }DATE;
 7 
 8 typedef struct student
 9 {
10     long studentID;
11     char studentName[10];
12     char studentSex;
13     DATE birthday;
14     int score[4];
15 }STUDENT;

 

当出现结构体嵌套时,必须以级联方式访问结构体成员,即通过成员选择运算符逐级找到最底层的成员时再引用

1 STUDENT pp;
2 pp.birthday.day = 10;
3 printf("%d", pp.birthday.day);

 

 

C语言允许对具有相同结构体类型的变量进行整体赋值,注意:对字符数组型结构体成员进行赋值时一定要使用strcpy()

1 strcpy(stu1.studentName, “王刚”);

 而不能写成

1 stu2.studentName = stu1.studentName

因为结构体成员studentName是一个字符型数组,studentName是该数组的名字,代表字符型数组的首地址,是一个常量,不能作为赋值表达式的左值,

结构体所占内存的字节数,不是简单的相加, 因为对多数计算机而言,为了提高内存寻址的效率,很多处理器体系结构为特定的数据类型引入了特殊了内存对齐需求,

不同的系统和编译器,内存对齐的方式有所不同,为了满足处理器的对其要求,可能会在较小的成员后加入补位,例:

1 Typedef struct sample
2 {
3     Char m1;
4     Int m2;
5     Char m3;
6 }SAMPLE;

 字节长度为12而不是1+4+1=6字节长度,即sizeof(struct sample)==12;

7、结构体指针的定义和初始化

 1 typedef struct student
 2 {
 3     long studentID;
 4     char studentName[10];
 5     char studentSex;
 6     DATE birthday;
 7     int score[4];
 8 }STUDENT;
 9 STUDENT stu1;
10 STUDENT *pt;
11 pt = &stu1;

或者

1 STUDENT *pt = &stu1;

 指向结构体数组的指针,假设已声明了STUDENT结构体类型,并且已定义了一个有30个元素的结构体数组stu,则定义结构体指针变量pt并将其指向结构体数组stu的方法为:

1 STUDENT *pt = stu;

 

等价于

1 STUDENT *pt = &stu[0];

 

等价于

1 STUDENT *pt;
2 pt = stu;

 

8、向函数传递结构体(参数传递)

将结构体传递给函数的方式有如下3种:

  1.用结构体的单个成员作为函数参数,向函数传递结构体的单个成员(属于传值调用不会影响相应的实参结构体的值

  2.用结构体变量做函数参数,向函数传递结构体完整结构(属于传值调用不会影响相应的实参结构体的值

  3.用结构体指针或结构体数组作函数参数属于模拟按引用调用向函数传递结构体地址,因为仅复制结构体首地址一个值给被调函数,相对于第二种方式,这种传递效率更高

 参考链接:

https://www.cnblogs.com/ktao/p/8578074.html

https://www.cnblogs.com/qyaizs/articles/2039101.html

http://c.biancheng.net/view/298.html

 


以上是关于结构体(结构体嵌套结构体指针结构体参数传递)的主要内容,如果未能解决你的问题,请参考以下文章

Go语言学习之旅--结构体

Go语言学习之旅--结构体

结构体指针与结构体变量用作函数参数时有啥区别,在用法上

C 语言关于结构体做参数传递?

C++基础3(函数指针结构体)

C++基础3(函数指针结构体)