C++结构体


1 结构体的基本概念

结构体是用户自定义的数据类型(内置数据类型的集合),可存储不同的数据类型。


2 结构体定义和使用

2.1 定义结构体

语法struct 结构体名 { 结构体成员列表 };
例:struct Person { string name, int age};

2.2 创建结构体变量

创建结构体变量的3种方式:
(1)struct 结构体名 结构体变量名;
先创建结构体变量,再对结构体成员进行赋值(使用.访问结构体变量的属性,即结构体成员)。
例:

struct Person p;
p.name = "Tom";
p.age = 16;

(2)struct 结构体名 结构体变量名 = { 成员1初始值 , 成员2初始值...};
创建结构体变量时进行初始化。
例:

struct Person p = {"Tom", 16};

(3)定义结构体时即创建变量。

struct Person { 
	string name, 
	int age
} person;

注1:C++中,定义结构体时,struct关键字不可省略创建结构体变量时,struct关键字可省略
注2:结构体变量使用操作符.访问结构体成员/属性,即结构体变量x.成员a

示例

//结构体定义
/* 定义结构体时,struct关键字不可省略 */
struct Person {
	string name;
	int age;
} p1;	//结构体变量创建方式1

int main() {
	/* 创建结构体变量时,struct关键字可省略 */
	//结构体变量创建方式2
	struct Person p2;
	p2.name = "Tom";
	p2.age = 16;

	//结构体变量创建方式3
	struct Person p3 = {"Jerry", 18};

	cout << p2.name << "\t" << p2.age << endl;
	cout << p3.name << "\t" << p3.age << endl;

	return 0;
}

3 结构体数组

作用:将自定义的结构体变量存储至数组中,即结构体变量的数组,方便进行维护。
语法struct 结构体名 数组名[元素个数] = { {...} , {...} , ... , {...} }

注1:对比基本数据类型的变量和数组:
基本数据类型变量:int var;
基本数据类型数组:int var[5];
结构体变量:struct Person person;
结构体数组:struct Person persons[5];

注2:定义结构体数组时,struct关键字可省略

示例

#include <iostream>
using namespace std;
#include <string>

/* 结构体定义 */
struct Person {
	string name;
	int age;
};

int main() {
	/* 创建结构体数组 */
	//1.定义时结构体数组时初始化(可省略struct关键字)
	Person persons[3] = { {"Tom", 12}, {"Jerry" , 13} };
	//2.修改结构体数组元素
	persons[2].name = "Lucy";
	persons[2].age = 16;

	/* 遍历结构体数组 */
	for (int i = 0; i < sizeof(persons) / sizeof(persons[0]); i++) {
		cout << "姓名:" << persons[i].name << ",年龄:" << persons[i].age << endl;
	}

	return 0;
}

4 结构体指针

作用:利用结构体指针访问或操作结构体成员。

注1:对比基本数据类型的指针:
基本数据类型指针:int *p = &var;
结构体指针:struct Person *p = &person; //结构体指针类型需与结构体类型相匹配

注2:结构体指针使用操作符->访问结构体成员/属性,即结构体指针p -> 成员a
注3:定义结构体指针时,struct关键字可省略

示例

#include <iostream>
using namespace std;
#include <string>

/* 结构体定义 */
struct Person {
	string name;
	int age;
};

int main() {
	//1.创建结构体变量
	Person person = {"Tom", 12};
	//2.创建指向结构体变量的结构体指针(struct关键字可省略)
	Person *p = &person;

	//使用结构体变量访问成员
	cout << "姓名:" << person.name << ",年龄:" << person.age<< endl;
	//使用结构体指针访问成员
	cout << "姓名:" << p->name << ",年龄:" << p->age << endl;

	return 0;
}

5 结构体嵌套结构体

作用: 结构体中可定义其它结构体作为成员,用于解决实际问题。

注:作为结构体成员(被包含)的结构体需预先定义,否则编译器报错:结构体A使用未定义的struct “B”。

示例:每门课程对应一个老师,课程的结构体成员记录老师结构体。

#include <iostream>
using namespace std;
#include <string>

/* teacher类型结构体需先于course类型结构体前被定义,否则编译器报错:"course::t"使用未定义的struct "teacher" */
struct teacher {
	string name;
	int age;
};

struct course {
	string courseName;
	struct teacher t;
};

int main() {
	course c;
	c.courseName = "C++";
	c.t.name = "老王";
	c.t.age = 16;

	cout << "课程名:" << c.courseName << ",授课老师:" << c.t.name << ",年龄:" << c.t.age << endl;

	return 0;
}

6 结构体作为函数参数

作用:将结构体作为函数的参数进行传递。

传递方式有2种:
(1)值传递:函数参数使用结构体变量接收值(结构体变量)。
(2)地址传递:函数参数使用结构体指针接收地址(结构体变量的地址)。

注1:若不希望修改实参,则使用值传递(函数形参使用结构体类型接收结构体变量的实参)。形参的改变不影响实参
注2:若希望修改实参,则使用地址传递(函数形参使用结构体指针接收结构体变量地址的实参)。形参的改变会影响实参
注3:结构体类型结构体指针作为函数形参时,struct关键字可省略

示例

#include <iostream>
#include <string>
using namespace std;

struct Person {
	string name;
	int age;
};

/* 值传递:形参的改变不影响实参 */
void func_value(struct Person person) {
	person.name = "Jerry";
	person.age = 15;
	cout << "结构体变量作为函数参数传递:" << person.name << "\t" << person.age << endl;
}

/* 地址传递:形参的改变影响实参 */
void func_address(struct Person *p) {
	p->name = "Lucy";
	p->age = 20;
	cout << "结构体指针作为函数参数传递:" << p->name << "\t" << p->age << endl;
}

int main(){
	struct Person person = { "Tom", 10 };
	
	/* 结构体变量作为函数参数传递 */
	func_value(person);		//Jerry	15
	cout << "main函数中的结果:" << person.name << "\t" << person.age << endl;	//Tom	10

	/* 结构体指针作为函数参数传递 */
	func_address(&person);	//Lucy	20
	cout << "main函数中的结果:" << person.name << "\t" << person.age << endl;	//Lucy	20

	return 0;
}

7 结构体中const的使用场景

作用:使用const可避免数据被修改的误操作(不可写)
场景:值传递过程有更大的内存开销,会拷贝新的副本(结构体成员越多,内存占用越大)。地址传递过程(形参改为指针)可减少内存空间占用,不会拷贝新的副本且指针类型仅占用4字节;为避免数据被修改等误操作,可使用const关键字函数形参的指针限定为常量指针,无法进行解引用赋值操作(限定为只读不可写状态)。

注1:对函数参数的结构体指针使用const关键字修饰后,无法通过结构体指针使用操作符->修改结构体成员的值(可读不可写),否则编译器报错:表达式必须是可修改的左值
注2:const关键字的作用:限定为只读状态,防止修改操作(不可写)。

示例

struct Person {
	string name;
	int age;
};

/* 传递地址值:形参的改变影响实参 */
void func_address(const struct Person* p) {
	//使用const关键字修饰结构体指针后,不能通过结构体指针修改结构体成员的值
	//p->age = 20;		
	cout << "结构体指针作为函数参数传递:" << p->name << "\t" << p->age << endl;
}

int main() {
	struct Person person = { "Tom", 10 };
	
	/* 结构体指针作为函数参数传递 */
	func_address(&person);	//Tom	10
	cout << "main函数中的结果:" << person.name << "\t" << person.age << endl;	//Tom	10

	return 0;
}

8 结构体案例练习

练习:设计学生结构体,包含姓名与成绩,创建结构体数组存储若干名学生;使用冒泡排序实现结构体数组中学生成绩的降序排序。

#include <iostream>
#include <string>
using namespace std;

struct Student {
	string name;
	int score;
};

/* 冒泡排序 */
void bubbleSort(struct Student students[], int length) {
	for (int i = 0; i < length - 1; i++) {
		for (int j = 0; j < length - i - 1; j++) {
			if(students[j].score < students[j + 1].score){	//降序排序
				struct Student temp = students[j];
				students[j] = students[j + 1];
				students[j + 1] = temp;
			}
		}
	}
}

int main() {
	//创建学生结构体数组
	struct Student stus[3] = {
		{"张三" , 89},
		{"李四" , 68},
		{"王五" , 95}
	};
	int len = sizeof(stus) / sizeof(stus[0]);

	//冒泡排序:实现成绩降序排序
	bubbleSort(stus, len);

	for (int i = 0; i < len; i++) {
		cout << "姓名:" << stus[i].name << ",成绩:" << stus[i].score << endl;
	}

	return 0;
}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值