C语言实验5:结构体

目录

一、实验要求

二、实验原理

[1. 普通结构体](#1. 普通结构体)

[1.1 显示声明结构体变量](#1.1 显示声明结构体变量)

[1.2 直接声明结构体变量](#1.2 直接声明结构体变量)

​编辑

[1.3 typedef在结构体中的作用](#1.3 typedef在结构体中的作用)

[2. 结构体的嵌套](#2. 结构体的嵌套)

[3. 结构体数组](#3. 结构体数组)

[4. 指向结构体的指针](#4. 指向结构体的指针)

[4.1 静态分配](#4.1 静态分配)

[4.2 动态分配](#4.2 动态分配)

三、实验内容

[1. 学生数据库](#1. 学生数据库)

代码

截图

分析

[2. 书籍信息](#2. 书籍信息)

代码

截图

分析


一、实验要求

  1. 能够理解结构体的定义和基本概念。

  2. 熟练掌握结构体的初始化、访问和应用,包括数组的使用。

  3. 理解结构体与指针的关系,能够使用指针访问结构体成员。

二、实验原理

1. 普通结构体

cpp 复制代码
struct 结构体名称 {
    // 成员变量定义
};

1.1 显示声明结构体变量

在结构体定义之后,显式声明结构体变量。

例如

cpp 复制代码
struct Person {
    char name[20];
    int age;
};

struct Person person1; // 显式声明结构体变量

最后一行代码创建了结构体的实例化person1

eg:

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS //消除strcpy带来的警告
#include<iostream>
using namespace std;

struct Person {
	char name[20];
	int age;
};

int main() {
	struct Person person1,person2; // 显式声明结构体变量
	person1 = { "xiaoming",18 };
	//或者用下面这种方式赋值
	strcpy(person2.name, "xiaofang");//直接复制进去
	person2.age = 19;
	cout << person1.name << " " << person1.age << endl;
	cout << person2.name << " " << person2.age << endl;
	return 0;
}

结果

分析

1.#define _CRT_SECURE_NO_WARNINGS:

这是一个预处理指令,用于在编译时禁用某些与安全性检查相关的警告,主要用于 Microsoft Visual Studio 编译器。在此例中,用于消除 strcpy 可能引发的安全性警告。

2.struct Person:

定义了一个结构体 Person,包含一个名为 name 的字符数组和一个名为 age 的整数。

3.main 函数:

创建了两个 Person 结构体变量 person1 和 person2。

person1 使用了类似于初始化列表的方式直接赋值,这在 C++11 及以后的标准中是合法的。

person2 使用了 strcpy 函数将字符串 "xiaofang" 复制到 name 成员中,并通过直接赋值给 age 进行赋值。

1.2 直接声明结构体变量

在结构体定义的同时直接声明结构体变量。

例如

cpp 复制代码
struct Point {
    int x;
    int y;
} p1, p2; // 直接声明结构体变量 p1 和 p2

定义结构体Point的同时实例化p1,p2

对其赋值

cpp 复制代码
#include<iostream>
using namespace std;
struct Point {
    int x;
    int y;
} p1, p2; // 直接声明结构体变量 p1 和 p2
int main() {
    p1 = { 3,4 };
    p2 = { 5,6 };
    cout << p1.x <<" "<< p1.y << endl;
    cout << p2.x << " " << p2.y << endl;
	return 0;
}

p1,p2是全局变量

使用直接声明结构体变量的好处就是简单且可以声明全局变量

1.3 typedef在结构体中的作用

typedef 是 C 语言中用来给数据类型取别名的关键字。在结构体的定义中,使用 typedef 可以简化对结构体类型的引用。

不使用typedef:

cpp 复制代码
struct Point {
    int x;
    int y;
};

struct Point p1;

使用typedef:

cpp 复制代码
typedef struct {
    int x;
    int y;
} Point;

Point p1;

一个是定义简单,实例化复杂些,一个是定义麻烦,实例化简单些

由于结构体只用定义一次,而结构体可能需要多次实例化,建议用typedef struct定义结构体

2. 结构体的嵌套

在结构体中嵌套其他结构体,形成复合结构体。

cpp 复制代码
struct 结构体A {
    // 成员变量定义
    struct 结构体B {
        // 成员变量定义
    } 变量名B;
};

上述代码在结构体A中定义了一个结构体B,并实例化B

eg:

cpp 复制代码
struct A {
	struct B {
		int year;
	}student;
	int grade;
}xiaoming,xiaofang;
  • 定义了一个结构体 A,其中嵌套了一个结构体 B。结构体 B 包含一个整数成员 year。结构体 A 包含了一个名为 studentB 类型的成员和一个整数成员 grade
  • 同时在全局范围内声明了两个结构体变量 xiaomingxiaofang。

通过结构体的嵌套,可以建立更复杂和层次化的数据结构,使得代码更具可读性和可维护性。

对其实例化:

cpp 复制代码
#include<iostream>
using namespace std;
struct A {
	struct B {
		int year;
	}student;
	int grade;
}xiaoming,xiaofang;
int main() {
	xiaoming = {{19},93 };
	xiaofang.student.year = 18;
	xiaofang.grade = 94;
	return 0;
}

分析

main 函数中,通过初始化列表为 xiaoming 赋值。xiaofangstudent.yeargrade 成员分别被单独赋值。

切记不能在嵌套中用typedef struct定义结构体!!!

3. 结构体数组

定义数组,每个元素是一个结构体。

即用已定义的结构体来声明一个结构体数组。

cpp 复制代码
struct 结构体名称 数组名[大小];

例如

cpp 复制代码
#include<iostream>
using namespace std;

struct Person {
	char name[20];
	int age;
};

int main() {
	struct Person person[3]{ {"xiaofang",17},{"xiaoming",18},{"xiaokai",19} };
	for (int i = 0; i < 3; i++) {
		cout << person[i].age <<"  " <<person[i].name << endl;
	}
	return 0;
}

结果为

分析

对person数组中的每个元素赋值时要用"{}"

4. 指向结构体的指针

使用指针访问结构体的成员。

cpp 复制代码
struct 结构体名称 *指针名;

原理类似上一篇文章中的指针

https://mp.csdn.net/mp_blog/creation/editor/135313150

4.1 静态分配

eg:

cpp 复制代码
#include<iostream>
using namespace std;

struct Person {
	char name[20];
	int age;
};

int main() {
	struct Person person1 = { "Alice", 25 }; // 定义结构体变量
	struct Person* ptrPerson = &person1;   // 定义指向结构体的指针
	cout << ptrPerson->age << " " << ptrPerson->name;
	return 0;
}

结果为

需要强调的一点是使用指针时访问结构体的成员,可以使用箭头运算符**"->"****,不能用"."。**

4.2 动态分配

使用 new 运算符动态分配结构体内存,并返回指向该内存的指针。

例如:

cpp 复制代码
struct Person *ptrPerson2 = new Person;

使用 delete 运算符释放通过 new 分配的结构体内存。

例如:

cpp 复制代码
delete ptrPerson2;

三、实验内容

1. 学生数据库

定义一个名为 Student 的结构体,用于存储学生信息。结构体应包含以下成员:

rollNumber(整数)

name(最大长度为50的字符串)

marks(浮点数)

编写一个程序,声明一个包含5个 Student 结构体的数组,为每个学生输入信息,然后打印每个学生的详细信息。

代码

cpp 复制代码
#include<iostream>
using namespace std;

typedef struct Student {
	int rollNumber;
	char name[50];
	float marks;
};
int main() {
	Student student[5];
	for (int i = 0; i < 5; i++) {
		cin >> student[i].rollNumber >> student[i].name >> student[i].marks;
	}
	for (int i = 0; i < 5; i++) {
		cout << student[i].rollNumber<<" " << student[i].name <<" " << student[i].marks<<endl;
	}
	return 0;
}

截图

分析

这段代码定义了一个名为 Student 的结构体,用于存储学生的信息,包括学号 (rollNumber)、姓名 (name) 和成绩 (marks)。然后,在 main 函数中,它声明了一个包含5个 Student 结构体的数组 student

接下来,通过一个循环,程序从用户输入中获取每个学生的信息,包括学号、姓名和成绩。最后,通过另一个循环,程序将每个学生的信息输出到标准输出。

2. 书籍信息

代码

cpp 复制代码
#include<iostream>
using namespace std;

typedef struct Book {
	char title[100];
	char author[50];
	float price;
	int publishedYear;
};
int main() {
	Book book[3];
	int index = 0;
	float max_price = 0;
	for (int i = 0; i < 3; i++) {
		cin >> book[i].title >> book[i].author >> book[i].price>> book[i].publishedYear;
	}
	for (int i = 0; i < 3; i++) {
		if (book[i].price > max_price) {
			max_price = book[i].price;
			index = i;
		}
		cout << book[i].title <<" " << book[i].author <<" " << book[i].price << " "<<book[i].publishedYear << endl;
	}
	cout <<"最贵的书籍为"<< book[index].title;
	return 0;
}

截图

分析

这段代码定义了一个名为 Book 的结构体,用于存储书籍的信息,包括书名 (title)、作者 (author)、价格 (price) 和出版年份 (publishedYear)。然后,在 main 函数中,它声明了一个包含3个 Book 结构体的数组 book

通过两个循环,程序从用户输入中获取每本书的信息,包括书名、作者、价格和出版年份。同时,它找到了价格最高的书籍,并记录了其索引。最后,通过循环输出每本书的信息,并额外输出价格最高的书籍的标题。

相关推荐
程序员_三木3 分钟前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊13 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama19 分钟前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全22 分钟前
Java的基础概念(一)
java·开发语言·python
liwulin050623 分钟前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc28 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Oneforlove_twoforjob32 分钟前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言
羚羊角uou34 分钟前
【C++】优先级队列以及仿函数
开发语言·c++
FeboReigns40 分钟前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns43 分钟前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++