IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c语言之结构体_part1 -> 正文阅读

[C++知识库]c语言之结构体_part1

一、定义和使用结构体变量

1 结构体定义以及如何创建结构体

在C语言的常见程序中,所用的变量大多数是相互独立、无内在联系的。例如定义了整型变量abc,他们都是单独存在的变量,在内存的地址中也是互不相干的。但是在实际的生活中,有些数据是存在相互联系,成组的出现,比如一个学生的姓名,学号,性别,地址和成绩等。

那么是否可以把学生的数据放在数组中呢,显然是不行的,因为数组中只能存放同一种数据类型的数据,整型数组可以存放学号和成绩,但是姓名,性别和地址是不能存放的。

今天要说的就是c语言中用户可以自己建立不同数据类型组成的组合型的数据结构——结构体(struct),在其他的高级语言里面称为“记录(record)”。

接下来举一个简单的栗子:

struct student
{
	int num; // 学号
	char name[20];  //姓名
	char sex;  // 性别
	int age; // 年龄
	float score; // 成绩
	char addr[30]; // 地址	
}; // 注意最后有一个分号

上面的程序设计指定了一个结构体类型 struct studentstruct 是声明结构体类型时必须使用的的关键字,不能省略)。

注:此时struct student 就相当于是一个类型名,类似于 int, float。

声明一个结构体的一般形式为:

struct 结构体名
{成员列表};

注意:结构体类型的名字是由一个关键字struct和结构体名tag组合而成(例如:struct student)。结构体名是由用户指定的,又称为“结构体标记(structure tag)”,作用是区别于其他的结构体类型。上例中的student就是结构体名(结构体标记)。

花括号内包含结构体的所有成员,声明规则为:

类型名 成员名;

“成员列表”(member list)也称为“域表”,每一个成员都是结构体中的一个域。成员名命名规则与变量名相同。

说明:结构体类型并非是只有一种,而是可以设计出很多种,除了上例的struct student,还可以设计struct teacherstruct worker等等,各自包含各自的成员。

2 如何定义结构体类型的变量

第一节的介绍中,我们只是建立了一个结构体类型,它只是一个模型,并没有定义变量,其中并无具体的数据,系统也不会分配存储单元。

第一种形式:先声明结构体类型,再定义该类型的变量

例如:

struct student
{
	int num; // 学号
	char name[20];  //姓名
	char sex;  // 性别
	int age; // 年龄
	float score; // 成绩
	char addr[30]; // 地址	
}; // 注意最后有一个分号


struct student student1, student2;

int main(){
	return 0;
}

这种结构体类型的定义和其他类型定义变量的形式相似(比如:int a;),上面的 student1,student2为 struct student 类型的变量。

student1的结构:

numnamesexagescoreaddr
10001xiao miM1990.5Shanghai

第二种形式:在声明结构体类型的同时定义变量

例如:

struct student
{
	int num; // 学号
	char name[20];  //姓名
	char sex;  // 性别
	int age; // 年龄
	float score; // 成绩
	char addr[30]; // 地址	
}student1, studnet2; // 注意最后有一个分号

这种定义的一般形式为:

struct 结构体名
{
	成员列表;
} 变量名列表;

这种形式的结构比较直观,在写小程序时会比较直观,清晰,但在写大程序时,往往要求对结构体类型的声明和对变量的定义分别放在不同的位置,以使程序的结构更加清晰,便于维护。

第三种形式:不指定结构体名tag而直接定义结构体类型变量

其一般形式为:

struct
{
	成员列表;
} 变量名列表;

说明:
指定了一个无名的结构体类型,它没有名字(不出现结构体名tag)。显然不能再以此类结构体类型去定义其他变量,因为我们往往使用struct demo_tag var1 来定义一个结构体变量var1,如果没有标签名(demo_tag)的话就不能用这种形式定义var1,所以我们在使用结构体变量的时候只能使用变量名列表的变量,如果要添加其他变量的话,只能提前在变量名列表中添加你需要的变量名。因此这种方式用的不多。

注意:
(1)结构体类型与结构体变量是不同的概念,不要混淆。只能对变量进行赋值,存取和运算,而不能对一个类型赋值,存取和运算。在编译时,对类型是不分配空间的,只对变量分配空间。
(2)结构体类型中的成员名可以和程序中的变量名同名,二者互不干扰。
(3)对结构体变量中的成员,即域,可以单独使用,它的作用和地位与普通变量无差。

第四种形式:使用typedef为结构体取一个新名字

c语言中,typedef的作用是给数据类型取一个新名字,比如:

typedef int ElementData;

这样的话,我们在使用结构体的时候,可以使用自己定义的数据类型,比如:

struct teacher
{
	char name[20]; // 姓名
	ElementData age; // 年龄
	ElementData num; // 工号
};

当然,不一定非得在结构体中才能使用 ElementData,在程序中其他的地方也是可使用的:

typedef int ElementData;

int main(){
	ElementData a = 20;
	printf("%d", a);
	return 0;
}

typedef的作用讲明白了,接下来我们可以进入正题:如何在结构体中使用typedef
常见两种形式:

// 第一种形式
typedef struct{
	char name;
	int age;
}STUDENT;

说明:这种形式下,并没有定义结构体名 tag ,但是使用了 typedef 给无标签tag的结构体取了一个新名字 STUDENT,此后,STUDENT 便是数据类型的名字,并且也不需要使用关键字struct,以后声明就可以用直接 STUDENT x;

// 第二种形式
typedef struct NODE{
	int data;
	struct NODE* next;
}node;

这是创建链表的常见写法,可以拆分两步来看:
第一步:创建了一个struct NODE类型的结构体,类型名是 struct NODE,结构体名是NODE

struct NODE{
	int data;
	struct NODE* next;
};

第二步,使用typedef struct NODE node给这个结构体取了一个新名字node,此时 node 便是这种结构体的数据类型名。以后便可以使用 node 直接声明变量,比如,node Lnode;而不必使用struct关键字。

需要注意的是:在创建链表的时候,使用的是 struct NODE 创建的指针变量next,此时是因为,结构体的新命名功能要晚于结构的创建功能,因此在创建 next 指针变量时使用 struct NODE *next

不过,在之后的创建、插入、删除、查找函数,以及主函数中,声明指针统一用的是 node* pointer;

3 结构体不同创建形式的比较

形式1:

struct {
	char a;
	short b;
	int c;
} var1;


struct {
	char a;
	short b;
	int c;
} var2;


int main(void)
{
	return 0;
}

说明:
(1)由于这种形式,没有标签tag,因此不能在程序中使用 struct tag 来定义一个新的结构体变量,只能是在创建结构体的同时就将需要的变量列表写全。
(2)上述方法定义了两个结构体变量var1与var2,两个变量的构造方式相同。但是,这种定义方式有着很大的不便,因为反复重写相同的东西。

对此做一下修改,于是有定义方法2。

形式2:

struct {
	char a;
	short b;
	int c;
} var1,var2;


int main(void)
{
	return 0;
}

说明:
(1)同形式1,由于没有 tag,因此不能额外声明结构体变量。
(2)这种方式少写了一次结构体,同时还能够实现两个变量的定义。不过,如果定义的结构体变量过多的时候代码就会有可读性以及维护性上的问题。对此改进有两种可选方式,也就是方法3-结构体tag以及方法4-结构体数据类型。

形式3

struct demo_tag {
	char a;
	short b;
	int c;
} var1;


struct demo_tag var2;


int main(void)
{
	return 0;
}

说明:上述代码同样实现了两个结构体变量的定义,但是此结构采用了结构体的tag用以代替了结构体的描述。这种定义方式每次需要写struct关键字,因为tag只是代表了结构体的描述信息,即结构体名,struct demo_tag才是一个类型名。不过,如果出现大量的结构体变量定义需要时,这种方式显然要比前两种方式好得多。

形式4

typedef struct demo_tag {
	char a;
	short b;
	int c;
} demo_t;


demo_t var1,var2;


int main(void)
{
	return 0;
}

说明:代码中的结构体demo_tag其实是没有用了的,可以去掉。我个人感觉这种方法是最好的一种使用方式。只需要构造一个结构体数据类型,接下来的结构体对象构建起来就简单很多了。而且,当出现大量的结构体数据时,代码需要维护的时候工作量也会小很多。不仅仅在于代码的字符会看着少一些,同时这种方式也比较适合最基本的C语言定义规则。当然,这得建立在你对这种技术有一定的熟知的基础上。

二、使用结构体

1 赋值和初始化

代码示例1:

#include<stdio.h>
#include<iostream>


struct Student
{
	int age;
	float score;
	char sex;

}s={12, 95.5, 'F'};

int main(){
	printf("%d %f %c", s.age, a,score, s.sex);
	return 0;
}

代码示例2:

#include<stdio.h>
#include<iostream>


struct Student
{
	int age;
	float score;
	char sex;

};



int main()
{
	//初始化-方式1 定义同时赋值
	struct Student st = { 80, 66.6, 'F' };


	//初始化-方式2
	struct Student st2; //定义
	st2.age = 10;  //赋值
	st2.score = 88.8;
	st2.sex = 'F';


	printf("age=%d st.score=%.2f sex=%c\n", st.age, st.score, st.sex);
	printf("age=%d st.score=%.2f sex=%c\n", st2.age, st2.score, st2.sex);
	
	system("pause");
	return 0;
}

2 如何取出结构体变量中的每一个成员

方式1
结构体变量名.成员名

方式2
指针变量->成员名

代码示例:

#include<stdio.h>
#include<iostream>


struct Student
{
	int age;
	float score;
	char sex;

};



int main()
{
	
	struct Student st = { 80, 66.6, 'F' };


	struct Student st2;
	struct Student *pst = &st2; //定义指针变量
	pst->age = 90;//方式1
	st2.score = 88.8;//方式2
	pst->sex = 'F';


	printf("age=%d st.score=%.2f sex=%c\n", st.age, st.score, st.sex);
	printf("age=%d st.score=%.2f sex=%c\n", pst->age, pst->score, pst->sex);
	
	system("pause");
	return 0;
}

3 结构体与指针

要求:通过指针和函数对结构体变量的输入和输出

代码示例:

#pragma warning( disable : 4996)
#include<stdio.h>
#include<iostream>
#include<malloc.h>
#include<string.h>

struct Student
{
	int age;
	char sex;
	char name[100];

};

void InputStudent(struct Student * pstu);//对结构体变量进行输入
void OutputStudent(struct Student * pstu);//对结构体变量进行输出

int main()
{
	struct Student st;

	InputStudent(&st);//对结构体变量进行输入
	OutputStudent(&st);//对结构体变量进行输出


	system("pause");
	return 0;
	

}


void InputStudent(struct Student * pstu) //指针变量pstu只占用4个字节
{
	pstu->age = 10;//(*pstu).age
	strcpy(pstu->name, "zhangsan");(*pstu).name
	pstu->sex = 'F'; //(*pstu).sex
}

void OutputStudent(struct Student * pstu)
{
	printf("age=%d name=%s sex=%c\n", (*pstu).age, (*pstu).name, (*pstu).sex);
}

/* 也可以使用
void OutputStudent(struct Student stu)
{
	printf("age=%d name=%s sex=%c\n", stu.age, stu.name, stu.sex);
}
*/

未完待续

参考文献

1、c程序设计(第五版)(谭浩强)
2、https://blog.csdn.net/grey_csdn/article/details/68954750
3、https://zhuanlan.zhihu.com/p/87364251
4、https://blog.csdn.net/zaishuiyifangxym/article/details/105565374

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 20:56:54  更:2022-10-22 20:59:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:37:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码