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