文章目录

  • 一、结构体基础
    • 1.1 什么是结构体
    • 1.2 建立结构声明
    • 1.3 定义结构变量
    • 1.4 初始化结构
    • 1.5 访问结构成员
    • 1.6 结构的初始化器
  • 二、结构数组
    • 2.1 声明结构数组
  • 三、嵌套结构
  • 四、指向结构的指针
    • 4.1 声明和初始化结构指针
    • 4.2 用指针访问成员
  • 五、向函数传递结构信息
    • 5.1 传递结构成员
    • 5.2 传递结构地址
    • 5.3 传递结构
    • 5.4 结构和结构指针的选择
  • 六、联合(union)
    • 6.1 声明联合
    • 6.2 使用联合

设计程序时,最重要的步骤之一是选择表示数据的方法。在许多情况下,简单变量甚至是数组还不够。为此,C提供了结构变量(structure variable)提高表示数据的能力,它能让你创造新的形式。

一、结构体基础


1.1 什么是结构体

结构体与数组类似,都是由若干分量组成的,与数组不同的是,结构体的成员可以是不同类型,可以通过成员名来访问结构体的元素。


1.2 建立结构声明

结构声明(structure declaration)描述了一个结构的组织布局。声明语法如下:

structure 结构体名 {数据类型 成员1;数据类型 成员2;数据类型 成员3;...}
# include <stdio.h>#define MAXLARGE  20// 声明一个结构体名为book的结构体
struct book
{// 定义int类型的BookNum成员int booknum;// 定义char类型的Title数组成员,数组最大为MAXLARGEchar title[MAXLARGE];// 定义char类型的author数组成员,数组最大为MAXLARGE char author[MAXLARGE];  // 定义double类型的price成员double price;
};int main(void){return 0;
}

该声明描述了一个由一个int类型变量,两个char类型变量的数组和一个double类型的结构体。该声明并未创建实际的数据对象,只描述了该对象由什么组成。

在结构声明中,yong一对花括号括起来的是结构成员列表。每个成员都用自己的声明来描述。例如:title是一个内含MAXLARGE个元素的数组。成员可以是任意一种数据类型,甚至可以是其他结构!右花括号后的分号是必须的,它表示结构布局定义结束。

结构声明可以放在函数的外部也可以放在函数的内部。如果放在函数内部,就如同局部变量一样,只限于函数的使用。如果放在外部,那在声明之后的所有函数都可以使用。


1.3 定义结构变量

结构有两层含义。一层是结构布局,上面已经说过,结构布局是告诉编译器如何表示数据,但是它并未让编译器为数据分配空间。下一步是创建一个结构变量,即是结构体的另一层含义。

程序中创建结构变量的是:

// 声明一个结构体名为book的结构体
struct book
{// 定义int类型的BookNum成员int booknum;// 定义char类型的Title数组成员,数组最大为MAXLARGEchar title[MAXLARGE];// 定义char类型的author数组成员,数组最大为MAXLARGE char author[MAXLARGE];  // 定义double类型的price成员double price;  // library表示创建一个book结构体的变量名
} library;等效于:
struct book library;

编译器执行这行代码便创建了一个结构变量library。编译器使用book模板为该变量分配空间。

声明结构的过程和定义结构变量的过程可以组合成一个步骤。则如下所示:

struct
{// 定义int类型的BookNum成员int booknum;// 定义char类型的Title数组成员,数组最大为MAXLARGEchar title[MAXLARGE];// 定义char类型的author数组成员,数组最大为MAXLARGE char author[MAXLARGE];  // 定义double类型的price成员double price;
} library;  // 声明的右花括号后跟变量名

在结构变量的声明中,struct book所起的作用相当于一般声明中的int或float。例如:可以定义一个struct book类型的变量,甚至是指向struct book的指针。

struct book doyle, panish, *ptbook;

1.4 初始化结构

初始化一个结构变量与初始化数组的语法类似:

struct book library=
{100010,"Tom and Jerry","unknow",10.00
};

1.5 访问结构成员

结构类似一个超级数组,在这个超级数组中,可以是一个元素为char类型,下一个元素为int类型,在数组中可以使用下标单独访问数组中的各个元素。而在结构体中需要使用结构成员运算符 ------( . )访问结构体中的成员。

# include <stdio.h>#define MAXLARGE  20struct book
{int booknum;   // 定义int类型的BookNum成员char title[MAXLARGE];   // 定义char类型的Title数组成员,数组最大为MAXLARGEchar author[MAXLARGE];    // 定义char类型的author数组成员,数组最大为MAXLARGEdouble price;    // 定义double类型的price成员
};struct book library=
{100010,"Tom and Jerry","unknow",10.00
};int main(void){// 在主函数中,使用结构体成员操作符访问结构体成员的属性。printf("%s\n", library.title);printf("%d", library.booknum);return 0;
}

1.6 结构的初始化器

C99和C11为结构体提供了指定初始化器,其语法与数组的指定初始化器类似。但是,结构的指定初始化器使用点运算符和成员名标识特定的元素。

# include <stdio.h>#define MAXLARGE  20struct book
{int booknum;   // 定义int类型的BookNum成员char title[MAXLARGE];   // 定义char类型的Title数组成员,数组最大为MAXLARGEchar author[MAXLARGE];    // 定义char类型的author数组成员,数组最大为MAXLARGEdouble price;    // 定义double类型的price成员
};// 使用C99和C11结构的初始化器初始成员,也可以只初始化部分成员。
struct book ptbook=
{.booknum=10010,.title="Tom",.author="unknow",.price=12.00
};int main(void){printf("%s\n", ptbook.title);printf("%d", ptbook.booknum);return 0;
}

二、结构数组

结构数组本质上是一个数组,其数组中的各个元素都是结构体。


2.1 声明结构数组

声明结构数组和声明其他类型的数组类似,声明结构数组如下:

struct book arrayst[MAXARRAY];

以上代码把arrayst声明为一个内含MAXARRAY个元素的数组。数组的每个元素都是一个book类型的结构。

数组名arrayat本身不是结构名,他是一个数组名,该数组中的每个元素都属struct book类型的结构变量。

#include <stdio.h>#define MAXLARGE  20struct book
{int booknum;   // 定义int类型的BookNum成员char title[MAXLARGE];   // 定义char类型的Title数组成员,数组最大为MAXLARGEchar author[MAXLARGE];    // 定义char类型的author数组成员,数组最大为MAXLARGEdouble price;    // 定义double类型的price成员
};struct book arrayst[3]={{100011, "围城", "钱钟书", 100.00},{100012, "西游记", "吴贯中", 102.00},{100013, "红楼梦", "曹雪芹", 103.00}
};int main(void){printf("%s\n", arrayst[0].title);printf("%d", arrayst[1].booknum);return 0;
}

arrayst[1].num表示访问数组中的第二个元素,也就是第二个结构体中的num属性的值。


三、嵌套结构

在一个结构中包含另一个结构(即嵌套结构)

示例:

#include <stdio.h>// 第一个结构体
struct names
{char first_name[20];char last_name[20];};// 第二个结构体
struct friends {// 嵌套第一个结构体struct names people;int age;char gender;// 初始化第二个结构体
} info={{"Tom", "jerry"},12,'m'
};int main(void){printf("%s\n", info.people);printf("%d", info.age);return 0;
}

注意如何在结构声明中创建嵌套结构体。和声明int类型变量一样:

struct names people;

该声明中people是一个struct names类型的变量。当然,文件中也应包含结构names的声明。

访问嵌套结构的成员时需要使用两次点运算符:

printf("%s\n", info.people.last_name);

四、指向结构的指针

#include <stdio.h>#define MAXLARGE  20struct names
{char first_name[20];char last_name[20];};struct friends {struct names people;int age;char gender;};struct friends info[2]={{{"Tom", "jerry"}, 12, 'm'},{{"John", "Tim"}, 11, 'f'}
};int main(void){// 声明一个结构指针struct friends *him;// 结构指针指向info的第1个元素him = &info[0];printf("%s\n", him->people.last_name);printf("%d", him->age);return 0;
}

4.1 声明和初始化结构指针

在上面的程序中,声明结构指针很简单:

struct friends *him;

首先是struct关键字,其次是标记结构friends,然后是一个星号,其后跟指针名。

和数组不同的是,结构变量并不是结构变量的地址,因此要在结构变量名前加上&运算符。

该声明并未创建一个新的结构,但是指针him现在可以指向任意现有guy类型的结构。在本例中,info是一个结构数组,这意味info[0]是一个结构,所以,要让him指向info[0],可以这样写:

him = &info[0];

him指向info[0],则him+1指向info[1]。


4.2 用指针访问成员

在上述程序中him指向info[0],在操作符一节中我们使用 -> 操作符获取结构指针成员的值。

// 获取him指向的成员属性值
printf("%s\n", him->people.last_name);
printf("%d", him->age);

五、向函数传递结构信息

ANSI C允许把结构作为参数使用。所以程序员可以选择是传递结构本身,还是传递指向结构的指针。如果你只关心结构中的某一部分,也可以把结构的成员作为参数。接下来解析这三种传递方式。


5.1 传递结构成员

传递结构成员就是把结构体成员属性的值传递到函数的参数中,完成函数的功能。

#include <stdio.h>// 定义结构体
struct funds
{double balance;double savefunds;
};// 定义相加函数
double sum(double x, double y){return x + y;
}int main(void){// 初始化结构体struct funds per={1000,1000};//调用函数,函数的参数为结构体的成员属性 printf("The total balance is : %lf", sum(per.balance, per.savefunds));return 0;
}

5.2 传递结构地址

接上面的内容,下面将结构的地址传递给函数。

#include <stdio.h>// 定义结构体
struct funds
{double balance;double savefunds;};// 定义加法函数。声明形参为结构体地址。形参地址为money
double sum(const struct funds * money){return (money->balance + money->savefunds) ;
}int main(void){// 初始化结构体struct funds per={1000,1000};// 将实参结构体地址传入函数。printf("The total balance is : %lf", sum(&per));return 0;
}

5.3 传递结构

对于支持将结构传递给函数的编译器可以把结构体当作参数进行传递。

#include <stdio.h>// 定义一个结构体
struct funds
{double balance;double savefunds;};// 定义相加函数,并将结构体传给函数
double sum(struct funds totalbal){return (totalbal.balance + totalbal.savefunds) ;
}int main(void){// 初始化结构体struct funds per={1000,1000};// 将结构体传给函数使用printf("The total balance is : %lf", sum(per));return 0;
}

5.4 结构和结构指针的选择

传递结构和传递结构指针各有各的优缺点。把指针作为参数时执行起来很快,只要传递一个地址。缺点是无法保护数据,不过新增的const限定符解决了这个问题。

把结果作为参数的优点是函数处理的是原始数据的副本,这保护了原始数据。缺点是较老的版本可能无法实现,而且传递结构浪费时间和空间。尤其是把大型结构传递给函数。


六、联合(union)

6.1 声明联合

在C语言中,允许几种不同类型的变量存放到同一段内存单元中(不是同时存储),其典型用法是设计一种表以存储无规律、事先也不知道顺序的混合类型。使用联合类型的数组,其中的联合都大小相等,每个联合可以存储各种数据类型。

创建联合和创建结构的方式相同,需要一个联合模板和联合变量。用关键字union声明联合

union hold{int dight;double big;char litter;
}

6.2 使用联合

下面是联合的一些用法:

union hold fit;fit.dight = 10; // 把10存储在fit的dight中
fit.big = 2.1 // 清除10,存储2.0
fit.litter = 'w' // 清除2.0 存储w

点运算符表示正在使用哪种数据类型。在联合中,一次只能存储一个值。即时有足够的空间,也不能同时存储一个char类型值和一个int类型的值。所以编写代码时要注意当前存储的是哪一种数据类型。

和用指针访问结构使用一样,用指针访问联合时也要使用 ->运算符

pu = &fit;int x = pu->dight; // 相当于fit.dight

C语言学习(九)之结构体相关推荐

  1. c语言学习笔记【结构体02】结构体指针变量与结构体变量的函数参数,C语言学习笔记结构体02结构体指针变量与结构体变量的函数参数.docx...

    C 语言学习笔记[结构体02]结构体指针变量与结构体变量 的函数参数 C 语言学习笔记之结构体指针变量一提指针,那可 是 C 语言的核心了,有多少学子曾拜倒在指针的脚下.单纯的说指针,其实并不难,但是 ...

  2. c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体

    枚举 枚举是一种用户定义的数据类型,它用关键字enum以如下语法格式来声明: enum 枚举类型名字 {名字0,名字1,...,名字n}: 枚举类型名字通常并不真的使用,要用的是大括号里面的名字,因为 ...

  3. C语言学习笔记(15)——结构体程序设计

    前言 C语言的基本数据类型有整数型.实数型及字符型,使用这些基本数据类型可以构造数组类型,并且可以定义相关数据类型的指针.本节介绍的结构体类型区别于以上任何数据类型,它还能把各种不同类型的数据组合成一 ...

  4. C语言学习笔记---嵌套结构体

      结构体不仅可以单独使用,也可以在结构体中嵌套另一个结构体.如下面的例子: struct Date{int year;int month;int day;};struct book{char tit ...

  5. Go语言学习-- No.11结构体--结构体内嵌

    结构体内嵌 结构体内嵌 结构体内嵌的初始化 结构体内嵌 Go语言的结构体内嵌是一种组合特性,使用结构体内嵌可构建一种面向对象编程思想中的继承关系. 结构体实例化后,可直接访问内嵌结构体的所有成员变量和 ...

  6. C++入门基础教程(一):C语言的指针与结构体到底怎么用?

    目录 一.前言 二.指针 2.1 指针与地址 2.2 指针与函数参数 2.3 指针与数组 2.3.1 指针与一维数组 2.3.2 指针与二维数组 2.4 字符指针与函数 2.5 指针数组以及指向指针的 ...

  7. Go 语言编程 — 高级数据类型 — 结构体

    目录 文章目录 目录 结构体 访问结构体成员 向函数传递结构体 结构体指针 结构体标签(Struct Tag) 结构体 Golang 中,结构体是由一系列具有相同类型或不同类型的数据构成的数据集合.与 ...

  8. OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)...

    OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-wh ...

  9. C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?

    C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题? 问题1:结构体指针最开始怎么分配内存?用sizeof()是不能确定大小的. 问题2:给结构体变量分配之后,是否还要 ...

  10. c语言程序设计实验8,C语言程序设计实验八结构体.doc

    C语言程序设计实验八结构体 C语言程序设计实验八:结构体 请求用户输入若干个学生的基本情况,其中包括每位学生的学号.姓名和两门课(C语言.数学)的成绩.然后用下面的格式输出学生的成绩列表. 格式描述如 ...

最新文章

  1. ASan(Linux),gcc4.8以上版本自带的内存检查工具
  2. 敏捷个人实践第18次活动:选择朋友
  3. PHP中正则表达式学习及应用(二)
  4. CodeForces - 1486B Eastern Exhibition(二维中位数)
  5. SAP CRM get_children 方法里面参数 iv_as_copy 有什么用?
  6. 关于 Azure SQL 数据库你不知道的 5 件事
  7. 求字符串里里面字符出现的次数和出现哪些不同的字符的字符串
  8. SecureCRT 免安装、绿色版、免费版本
  9. Android设置透明效果的三种方法(转)
  10. Zend Framework 简介
  11. window环境下杀死tomcat
  12. paip.提升用户体验---提示语
  13. 贪吃蛇C语言代码(window版本)
  14. python IMAP4命令详解
  15. python 必应搜索教程
  16. Arun Murthy谈Apache YARN
  17. 利用PHP开发的一款万能、表白墙系统
  18. matlab中magy是什么意思,MATLAB入门基本知识——音频处理
  19. OSChina 周六乱弹 ——抗议破坏教学道具,致其严重变形!
  20. Quartus安装及使用教程(13版附安装包)

热门文章

  1. SkyWalking--OAL--使用/教程/示例
  2. Mvp-10隔膜泵串口编程
  3. H5多媒体音频歌曲JavaScript和jQuery混编,点击下一首播放下一首简单效果
  4. 华为OD机试 - 连接器问题(Java JS Python)
  5. 【转】vdd,vcc,vss,vref介绍
  6. 如何实现4G DTU网关远程抄表方案
  7. ZOJ 1090 The Circumference of the Circle(计算三角形的外接圆)
  8. Generic Array Creation,泛型数组创建时提示出错
  9. C/C++练习(一)——将句子倒序输出:输入“how are you倒序输出you are how
  10. 北京大学计算机硕博连读5年,关于2019年北京大学硕博连读研究生选拔工作的通知...