【C语言】21-结构体

C语言的核心部分都说得七七八八了,相信大家已经对C语言的基本数据类型(char\int\float)、数组、指针都很熟悉了,今天来学习C语言中另外一种数据类型:结构体。在iOS开发中,结构体是经常用到的数据类型,使用频率不亚于指针,所以需要重视,不过用法非常简单。

一、什么是结构体

* 在第八讲的时候已经介绍了C语言中的数组,用法跟其他语言差不多。当一个整体由多个数据构成时,我们可以用数组来表示这个整体,但是数组有个特点:内部的每一个元素都必须是相同类型的数据。

* 在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名、年龄、身高等数据构成,这些数据都具有不同的类型,姓名可以是字符串类型,年龄可以是整型,身高可以是浮点型。

* 为此,C语言专门提供了一种构造类型来解决上述问题,这就是结构体,它允许内部的元素是不同类型的。

二、结构体的定义

1.定义形式

结构体内部的元素,也就是组成成分,我们一般称为"成员"。

结构体的一般定义形式为:

 1 struct 结构体名{
 2
 3     类型名1 成员名1;
 4
 5     类型名2 成员名2;
 6
 7     ……
 8
 9     类型名n 成员名n;   
10
11 };

struct是关键字,是结构体类型的标志。

2.举例

比如,我们定义一个学生

struct Student {
    char *name; // 姓名
    int age; // 年龄
    float height; // 身高
};

上面定义了一个叫做Student的结构体,共有name、age、height3个成员。呵呵,看到这里是否有点面向对象的味道呢,其实这跟面向对象完全是两码事,只能说感觉有点像。

三、结构体变量的定义

前面只是定义了名字为Student的结构体类型,并非定义了一个结构体变量,就像int一样,只是一种类型。

接下来定义一个结构体变量,方式有好多种。

1.先定义结构体类型,再定义变量

1 struct Student {
2     char *name;
3     int age;
4 };
5
6 struct Student stu;

第6行定义了一个结构体变量,变量名为stu。struct和Student是连着使用的。

2.定义结构体类型的同时定义变量

struct Student {
    char *name;
    int age;
} stu;

结构体变量名为stu

3.直接定义结构体类型变量,省略类型名

struct {
    char *name;
    int age;
} stu;

结构体变量名为stu

回到顶部

四、结构体的注意点

1.不允许对结构体本身递归定义

如下做法是错误的,注意第3行

1 struct Student {
2     int age;
3     struct Student stu;
4 };

2.结构体内可以包含别的结构体

 1 struct Date {
 2     int year;
 3     int month;
 4     int day;
 5 };
 6
 7 struct Student {
 8     char *name;
 9     struct Date birthday;
10 };

注意第9行

3.定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间,就像系统不为int类型本身分配空间一样。只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量

1 struct Student {
2     char *name;
3     int age;
4 };
5
6 struct Student stu;

第1~4行并没有分配存储空间,当执行到第6行时,系统才会分配存储空间给stu变量。

4.结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列

比如下面的Student结构体:

1 struct Student {
2     char *name; // 姓名
3     int age; // 年龄
4     float height; // 身高
5 };

在16位编译器环境下,一个Student变量共占用内存:2 + 2 + 4 = 8字节。

五、结构体的初始化

将各成员的初值,按顺序地放在一对大括号{}中,并用逗号分隔,一一对应赋值。

比如初始化Student结构体变量stu

1 struct Student {
2     char *name;
3     int age;
4 };
5
6 struct Student stu = {"MJ", 27};

只能在定义变量的同时进行初始化赋值,初始化赋值和变量的定义不能分开,下面的做法是错误的:

struct Student stu;
stu = {"MJ", 27};

六、结构体的使用

1.一般对结构体变量的操作是以成员为单位进行的,引用的一般形式为:结构体变量名.成员名

1 struct Student {
2     char *name;
3     int age;
4 };
5
6 struct Student stu;
7
8 // 访问stu的age成员
9 stu.age = 27;

第9行对结构体的age成员进行了赋值。"."称为成员运算符,它在所有运算符中优先级最高

2.如果某个成员也是结构体变量,可以连续使用成员运算符"."访问最低一级成员

 1 struct Date {
 2      int year;
 3      int month;
 4      int day;
 5 };
 6
 7 struct Student {
 8     char *name;
 9     struct Date birthday;
10 };
11
12 struct Student stu;
13
14 stu.birthday.year = 1986;
15 stu.birthday.month = 9;
16 stu.birthday.day = 10;

注意第14行以后的代码

3.相同类型的结构体变量之间可以进行整体赋值

 1 struct Student {
 2     char *name;
 3     int age;
 4 };
 5
 6 struct Student stu1 = {"MJ", 27};
 7
 8 // 将stu1直接赋值给stu2
 9 struct Student stu2 = stu1;
10
11 printf("age is %d", stu2.age);

注意第9行。输出结果为:

七、结构体数组

1.定义

跟结构体变量一样,结构体数组也有3种定义方式

struct Student {
    char *name;
    int age;
};
struct Student stu[5]; //定义1
struct Student {
    char *name;
    int age;
} stu[5]; //定义2
struct {
    char *name;
    int age;
} stu[5]; //定义3

上面3种方式,都是定义了一个变量名为stu的结构体数组,数组元素个数是5

2.初始化

struct {
    char *name;
    int age;
} stu[2] = { {"MJ", 27}, {"JJ", 30} };

也可以用数组下标访问每一个结构体元素,跟普通数组的用法是一样的

八、结构体作为函数参数

将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也就是将实参中成员的值一一赋值给对应的形参成员。因此,形参的改变不会影响到实参。

 1 #include <stdio.h>
 2
 3 // 定义一个结构体
 4 struct Student {
 5     int age;
 6 };
 7
 8 void test(struct Student stu) {
 9     printf("修改前的形参:%d \n", stu.age);
10     // 修改实参中的age
11     stu.age = 10;
12
13     printf("修改后的形参:%d \n", stu.age);
14 }
15
16 int main(int argc, const char * argv[]) {
17
18     struct Student stu = {30};
19     printf("修改前的实参:%d \n", stu.age);
20
21     // 调用test函数
22     test(stu);
23
24
25     printf("修改后的实参:%d \n", stu.age);
26     return 0;
27 }

* 首先在第4行定义了一个结构体类型Student

* 在第18行定义了一个结构体变量stu,并在第22行将其作为实参传入到test函数

输出结果为:,形参是改变了,但是实参一直没有变过

九、指向结构体的指针

* 每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量

* 结构体指针变量的定义形式:struct 结构体名称 *指针变量名

* 有了指向结构体的指针,那么就有3种访问结构体成员的方式

  • 结构体变量名.成员名
  • (*指针变量名).成员名
  • 指针变量名->成员名

 1 #include <stdio.h>
 2
 3 int main(int argc, const char * argv[]) {
 4     // 定义一个结构体类型
 5     struct Student {
 6         char *name;
 7         int age;
 8     };
 9
10     // 定义一个结构体变量
11     struct Student stu = {"MJ", 27};
12
13     // 定义一个指向结构体的指针变量
14     struct Student *p;
15
16     // 指向结构体变量stu
17     p = &stu;
18
19     /*
20      这时候可以用3种方式访问结构体的成员
21      */
22     // 方式1:结构体变量名.成员名
23     printf("name=%s, age = %d \n", stu.name, stu.age);
24
25     // 方式2:(*指针变量名).成员名
26     printf("name=%s, age = %d \n", (*p).name, (*p).age);
27
28     // 方式3:指针变量名->成员名
29     printf("name=%s, age = %d \n", p->name, p->age);
30
31     return 0;
32 }

输出结果:

时间: 2024-12-17 17:11:14

【C语言】21-结构体的相关文章

黑 马 程 序 员_视频学习总结&lt;C语言&gt;----05 结构体

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 一.什么是结构体 在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名.年龄.身高等数据构成,这些数据都具有不同的类型,姓名可以是字符串类型,年龄可以是整型,身高可以是浮点型.为此,C语言专门提供了一种构造类型来解决上述问题,这就是结构体,它允许内部的元素是不同类型的. 二.结构体的定义 结构体内部的元素,也就是

C语言的结构体和C++结构体的区别

关于C++中声明结构体中需要使用构造器创建实例对象的语法: 接着上两个代码截图你就初步体会到C语言的结构体和C++结构体的区别了:     对于右边的C++结构体的使用类似Java,C++,Swift中的类,类中有构造器方法,然后构造器创建这个类的实例对象. 当然Swift中也有一样用法的结构体.毕竟Swfit是集大家之所成的现代语言.

c语言的结构体字节数统计

struct结构体的字节数 等于 结构体中最大类型的字节数的倍数. 如:?typedef struct Student{??? short id; //2个字节??? char name[15]; //1*15个字节??? int age; //4个字节??? char num; //1个字节} Student; 总共28个字节. c语言的结构体字节数统计

C语言的结构体和 C++结构体的区别

 C语言的结构体和 C++结构体的区别 关于C++中声明结构体中需要使用构造器创建实例对象的语法: <C++的结构体构造方法的基本概念:结构体的构造方法需要和结构体的名字相同,并且无返回值,也不要void关键字,这样的方法就是构造器的初始化方法> 接着下面两个代码截图(一个是C源码,一个是C++源码)对比你就初步体会到C语言的结构体和C++结构体的区别了:      对于右边的C++结构体的使用类似Java,C++,Swift中的类,类中有构造器方法,然后构造器创建这个类的实例对象. 当然Sw

C语言之结构体

1 概述 结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型. 2 定义结构体类型变量的方法 定义结构体变量的一般格式为: struct 结构名 { 类型  变量名; 类型  变量名: ... }结构变量; 代码如下: struct Student{         char name[8];         int age;     }stu1; 上面的代码声明了一个名为Student的结构体,它包含两个成员name和age,成员name的数据类型为字符数组,成员ag

【剑仙教程】易语言的结构体。自定义数据类型。

1楼. [剑仙教程]易语言的结构体.自定义数据类型. 在易语言中,有基本数据类型,自定义数据类型. 自定义数据类型,在C语言/C++中称为结构体.这是面向对象和类的编程. . . 先上代码.打开易语言的IDE,IDE,是开发环境. 点击“插入”菜单,选择“数据类型” 这时,代码编辑框就会增加一个数据类型的窗口. 把“数据类型1”命名为“精易_座标”,勾选“公开项”. 这样,一个 精易_座标 的类就做好了. . 再按回车键,给这个类增加2个成员. x 整数型 y 整数型 . 访问时,直接写代码就O

黑马程序员---C语言基础---结构体

------iOS培训.Java培训.Android培训, iOS学习型技术博客,期待与您交流------ C语言基础---结构体 一.什么是结构体 介绍结构体之前,我想先简单介绍下数组.我想大家对数组都再熟悉不过了,顾名思义,数组就是将一些数据(元素)组合在一起,作为一个整体.使用数组需要注意的是这些元素必须是相同类型.而结构体和数组类似,也是将一些数据组合在一起作为一个整体,但是这些元素可以是不同类型.可以这么理解:结构体是更加灵活的数组,因为它允许元素是不同的类型. 实际生活中,如果我们要

C语言中结构体赋值问题的讨论(转载)

今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言中结构体赋值的问题吧: 结构体直接赋值的实现 下面是一个实例: #include <stdio.h> struct Foo { char a; int b; double c; }foo1, foo2; //define two structs with three different field

c语言 struct结构体的变量声明加冒号

有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可. 为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为"位域"或"位段".所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数.每个域有一个域名,允许在程序中按域名进行操作.这样就可以把几个不同的对象用一个字节的二进制位域来表示. [1]定义: struct 位域结构名 { 位

ios开发中的C语言学习—— 结构体简介

在开发过程中,经常会需要处理一组不同类型的数据,比如学生的个人信息,由姓名.年龄.性别.身高等组成,因为这些数据是由不同数据类型组成的,因此不能用数组表示,对于不同数据类型的一组数据,可以采用结构体来进行存储.当然,对于面向对象的语言来说,最好是用类来表示,但是C语言是面向过程的,因此选择用结构体来表示. 一.结构体的定义 struct 结构体名{ 类型名 成员名1; 类型名 成员名2; ... ... 类型名 成员名n; }; 二.结构体的变量声明 1.先定义结构体类型,再定义变量 代码 //