一起来学习c语言结构体吧!!
相信大家在学习c语言时会遇见各种各样的问题。对于我来说,我在学习过程中首先遇到的几个难理解的地方就是结构体的一系列操作。那么这篇笔记就带领大家一起来看看结构体到底是个什么东西。
一、引入
在学习结构体之前我们得先知道它是个什么东西。
接下来举个简单的栗子:假如你的面前有三个篮子,对应的分别放着苹果,梨子,香蕉,我现在给你一个水果,叫你把它放到对应的篮子中,此时你很开心,这不很简单吗?结果你一看我给了一个榴莲,此时你慌了,因为没有榴莲的篮子。所以为了解决这个没有榴莲框的问题,那我们就要去再买一个篮子专门装这个榴莲。而映射到c语言上,我们买篮子的这个操作就是构造结构体的过程。
二、结构体的定义
1.何为结构体
就是一种用无自定义的数据类型。在面对一个复杂对象时,几种基本数据结构显然是不够用的,此时根本的解决办法就是允许用户自定义数据类型。
用户利用已有的基本数据结构来构造自己的所需的数据类型。可以说它们是由基础数据结构派生而来的。
结构体将不同的数据成员组织到统一的名字下,适合于对关系紧密、逻辑相关、具有相同或者不同属性的数据进行处理。
2.结构体的定义
第一步:声明结构体模板
struct 结构体名 {
数据类型 成员1的名字;
数据类型 成员2的名字;
......
数据类型 成员n的名字;
};
解释:
其实可以将结构体看成一个特殊的数组,该数组的第一个元素所对应的就是成员1,第二个元素是成员2,以此类推,第n个元素就是成员n,最后将整个数组又看成一个变量或是常量(具体看用户想要哪种)
注:1)结构体的名字称为结构体标签(可以理解为int的作用),构成结构体的变量称为结构体成员。
2)前往要记住,最后一个括号后面的分号,牢记struct!
3)成员也可以数组。
4)结构体模板只是声明了一种数据类型,定义了数据的组织形式,并未声明结构体类型的变量。
第二步:声明结构体变量
(1)先声明模板,在定义变量
例如,定义一个love的结构体变量:
srtuct i love;
(2)在声明结构体的同时定义结构体变量
struct i
{
数据类型 成员1的名字;
数据类型 成员2的名字;
......
数据类型 成员n的名字;
}love;
注:当将结构体模板和结构体变量放在一起定义时,结构体标记时可选的,即可以不用出现结构体名。
struct
{
数据类型 成员1的名字;
数据类型 成员2的名字;
......
数据类型 成员n的名字;
}love;
3.用typedef定义数据类型
关键字typedef就时给结构体起一个小名,就类似于sgod也叫帅哥一样(嘻嘻)
typedef struct i I;
与下列等价
typedef struct i
{
long a;
int b;
char c;
}I;
这样做的好处就是让自己轻松点。
以前我们要写:struct i love;
现在我就只写:I love;
(嘻嘻)
4.变量初始化
struct i love={10000,1,a}; 或 I love={10000,1,a};
5.嵌套的结构体
嵌套结构体就是在一个结构体内包含了另一个结构体作为其成员。
例如:先定义一个结构体模板
typedef struct my
{
int d1;
int d2;
int d3;
}MY;
然后将son结构体模板来声明 i 结构体模板
typedef strcut i
{
long a;
int b;
char c;
MY e;
}I;
6.结构体的引用
访问结构体变量的成员要使用成员选择运算符(也称圆点运算符)。格式如下:
结构体变量名 . 成员名
例如:
O.a=1000;
当出现结构体嵌套时,必须以级联方式访问结构体成员,即通过成员选择符逐级找到最底层的成员再引用。
例如:
O.e.d1=100;
O.e.d2=100;
O.e.d3=100;
//(此时的O要理解成变量名)
对啦!C语言允许对具有相同结构体类型的变量进行整体赋值。
例如:
I O1={1000,1000,1000};
I 02;
O2=O1;
以上的表达是正确的。
注:(1)并非所有的结构体成员都是可以使用复制运算符来赋值,对于字符数组类型的结构体成员进行赋值时,必须使用字符串处理函数strcpy()。
(2)结构体变量的地址是结构体变量所占的内存空间的首地址,而结构体成员的地址值与结构体成员在结构体中所在的位置即该成员所占内存的字节数有关
三、结构体数组的定义和初始化
可以理解为大篮子(数组)里面有数个小篮子(结构体),数个小篮子里又有数个更小的篮子(结构体成员)
1.数组定义
STUDENT stu[30];
2.初始化
STUDENT stu[30]={{xxx,xxx,xxx,xxx}
{yyy,yyy,yyy,yyy}
};
四、结构体指针的定义和初始化
1.指向结构体变量的指针
假如已经声明了STUDENT结构体类型,那么定义一个指向该结构类型的指针变量的方法为:
STUDENT *pt;
pt = &stu1
或者是:
STUDENT *pt = &stu1
当然,我们也可以具体的指向某一个结构体成员,方法如下:
指向结构体的指针变量名->成员名
pt -> a1 = xxx;
//与下面语句等价的
(*pt).a1=xxx;
注:pt存的是结构体的首地址,而(*pt)是先取出pt所指向的内容,再将其看成一个结构体变量,利用成员选择符访问它的成员。
2.指向结构体数组的指针
STUDENT *pt = stu;
STUDENT *pt = &stu[0];
STUDENT *pt;
pt = stu;
三条语句是等价的;
五、向函数传递结构体
1.用结构体的单一成员作为函数参数,向函数传递结构体的单个成员。
与普通类型的变量最为函数实参没什么区别,都是传值调用。
2.用结构体变量作函数参数,向函数传递结构体的完整结构。
用结构体变量作为函数实参,向函数传递的是结构题的完整结构,即将整个结构体的内容赋值给被调函数(传值调用)
例如:
void Func(struct date p)
{
阿巴阿巴阿巴;
}
int main (void)
{
struct date P;
Func(P);
}
注:向函数传递结构体变量时,实际传递给函数的是该结构体变量成员值的副本,这意味着结构体变量的成员值是不能再被调函数中被修改的。和其他变量一样,仅当将结构体的地址传递给函数时,结构体变量的成员值才可以在被调函数中被修改。
3.用结构体指针或是结构体数组作为函数蚕食,向函数传递结构体的地址。
例如:
void Func(struct date *pt)
{
阿巴阿巴阿巴;
}
int main (void)
{
struct date P;
Func(&P);
}
六、结尾
说到这里,基本的结构体知识就已经介绍完了,希望对大家有帮助。
参考书籍:
C语言程序设计(第四版)——苏小红