C++学习记录 二、指针,通讯录管理系统

再系统地过一次,夯实基础

学习目标:

过一遍黑马程序员C/C++学习视频

学习内容:

一、C++基础入门

7. 指针

7.1 指针的基本概念

指针的作用: 可以通过指针间接访问内存

  • 内存编号时从 0 开始记录的,一般使用十六进制数字表示
  • 可以利用指针变量保存地址

语法 数据类型* 指针变量

#include <iostream>
using namespace std;
int main(){
    
    
	//1. 定义指针
	int a = 10;
	int* p;
	//让指针记录变量a的地址
	p = &a;
	cout << "a的地址为: " << &a << endl;
	cout << "指针p为: " << p << endl;
	
	//2. 使用指针
	//可以通过解引用的方式找到指针指向的内存
	//指针前加一个*号,代表解引用,找到指针指向的内存中的数据
	*p = 1000;
	cout << "a = " << a << endl;
	cout << "*p = " << *p << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

7.3 指针所占内存空间

指针存的是一个地址如:0x0000
在32位操作系统下:4个字节空间
在64位操作系统下:8个字节空间
示例:`int* p = &a;
在这里插入图片描述

7.4 空指针和野指针

空指针: 指针变量指向内存中编号位0的空间
用途: 初始化指针变量
注意: 空指针指向的内存是不可以访问的

//黑马的空指针设置方式:
int *p = NULL;
//C++11新特性写法
int *p = nullptr;
//C++11中,nullptr在C++11中就是代表空指针,不能被转换成数字,以前NULL其实是会被当作0;

野指针: 指针变量指向非法的内存空间
程序中应该避免写出野指针

7.5 const 修饰指针

const修饰指针有三种情况:

  1. const 修饰指针 – 常量指针
  2. const 修饰常量 --指针常量
  3. const 即修饰指针,又修饰常量

常量指针的特点:指针的指向可以修改,但是指针指向的值不可以修改

扫描二维码关注公众号,回复: 11869146 查看本文章
	//常量指针,const修饰指针
	int a = 10;
	int b = 10;
	const int* p = &a;

指针常量的特点:指针的指向不可以修改,但是指针指向的值可以修改

	//指针常量,const修饰常量
	int* const p = &a;

即修饰指针,又修饰常量的特点就是,指针的指向,指针的值都不可以修改

	const int* const p = &a;

7.6 指针和数组

作用: 利用指针访问数组中的元素
int arr[10] = { 1, 2, 3, 4, 5 };
int* p = arr;
p++;

7.7 指针和函数

作用: 利用指针做函数参数,可以修改实参的值

//地址传递
void swap(int* a, int* b) {
    
    
	int temp = *a;
	*a = *b;
	*b = temp;
}
int main() {
    
    
	int a = 10;
	int b = 20;
	swap(a, b);
	//等同于 swap(&a, &b)
	cout << "a: " << a << endl;
	cout << "b: " << b << endl;

	system("pause");
	return 0;
}

7.8 指针、数组、函数

案例描述: 封装一个函数,利用冒泡排序,实现对整型数组的升序排序

#include <iostream>
using namespace std;

void sort(int* arr) {
    
    
	for (int i = 9; i >= 0; i--) {
    
    
		int temp;
		for (int j = 0; j < 9; j++) {
    
    
			if (arr[j] > arr[j + 1]){
    
    
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

int main() {
    
    
	int arr[10] = {
    
     4, 3, 6, 9, 1, 2, 10, 8, 7, 5 };

	sort(arr);
	for (int i = 0; i < 10; i++) {
    
    
		cout << arr[i] << ' ';
	}

	system("pause");
	return 0;
}

8. 结构体

8.1 结构体基本概念

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型

8.2 结构体定义和使用

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

通过结构体创建变量的方式又三种:

  • struct 结构体名 变量名
  • struct 结构体名 变量名 = { 成员1值, 成员2值 }
  • 定义结构体时顺便创建变量
#include <iostream>
#include <string>
using namespace std;

//自定义数据类型
struct Student {
    
    
	string name;
	int age;
	double score;
}s3; //后面添加 s3,就代表在顺便创建结构体变量

//创建具体的学生
// struct Student s1
// struct Student s2 = { ... }
// 在定义结构体时顺便创建结构体变量

int main() {
    
    
	//创建具体的学生
	
	// struct Student s1
	//具体实施过程中 struct关键字可以不写
	Student s1;
	s1.name = "Zhang san";
	s1.age = 18;
	s1.score = 99.1;
	cout << "s1.name: " << s1.name << "age: " << s1.age << endl;
	
	// struct Student s2 = { ... }
	Student s2 = {
    
     "Lisi", 15, 88.1 };
	
	// 在定义结构体时顺便创建结构体变量
	s3.name = "s3";
	cout << s3.name << endl;

	system("pause");
	return 0;
}

8.3 结构体数组

作用: 将自定义的结构体放入到数组中方便维护
语法: struct 结构体名 数组名[ 元素个数 ] = { {}, {}, {}, {} };

#include <iostream>
#include <string>
using namespace std;
struct Student {
    
    
	string name;
	int age;
	float score;
};

int main() {
    
    
	struct Student stuArray[3] = {
    
    
		{
    
    "zhangsan", 18, 88.5},
		{
    
    "Lisi", 18, 55.0},
		{
    
    "wangwu", 15, 99.1}
	};
	cout << stuArray[0].age << endl;

	system("pause");
	return 0;
}

8.4 结构体指针

作用: 通过指针访问结构体中的成员

  • 利用操作符 -> 可以通过结构体指针访问结构体属性
#include <iostream>
#include <string>
using namespace std;
struct Student {
    
    
	string name;
	int age;
	float score;
};

int main() {
    
    
	Student A1 = {
    
     "wang", 18, 50.2 };
	Student* p = &A1;
	cout << p->name << endl;
	//cout << (*p).name << endl; 两种方式相同
	
	system("pause");
	return 0;
}

8.5 结构体嵌套结构体

作用: 结构体中的成员可以是另一个结构体
例如: 每个老师辅导一个学院,一个老师的结构体中,记录一个学生的结构体

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

struct Student {
    
    
	string name;
	int age;
	int score;
};

struct Teacher {
    
    
	string name;
	int age;
	Student stu;
};

int main() {
    
    
	Student stu1 = {
    
     "wang", 18, 55 };
	Teacher Ma = {
    
     "mayichao", 30, stu1 };
	cout << Ma.stu.name << endl;
	system("pause");
	return 0;
}

8.6 结构体做函数参数

作用: 将结构体作为参数向函数中传递
传递方式有两种:

  • 值传递
  • 地址传递
#include <iostream>
#include <string>
using namespace std;

struct Student {
    
    
	string name;
	int age;
	int score;
};

void stu(Student* who) {
    
    
	cout << who->name << endl;
	cout << who->age << endl;
	cout << who->score << endl;
}


int main() {
    
    
	Student stu1 = {
    
     "wang", 18, 55 };
	stu(&stu1);
	system("pause");
	return 0;
}

8.7 结构体中 const 使用场景

作用: 用const来防止误操作

加入const之后,一旦有修改的操作就会报错。

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

struct Student {
    
    
	string name;
	int age;
	int score;
};

//将函数中的形参改为指针,可以节约内存,而不会复制新的副本出来
void printStudent(const Student *s) {
    
    
	s->age = 22;
	cout << "name: " << s->name << endl;
}

int main() {
    
    
	Student stu1 = {
    
     "wang", 18, 55 };
	printStudent(&stu1);
	system("pause");
	return 0;
}

在这里插入图片描述

8.8 结构体案例

8.8.1

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

struct Student {
    
    
	string name;
	int score;
};

struct Teacher {
    
    
	string name;
	Student stus[5];
};



void allocateSpace(Teacher tea[],int len) {
    
    
	//给老师赋值
	string nameSeed = "ABCDE";
	for (int i = 0; i < len; i++) {
    
    
		tea[i].name = "Teacher_";
		tea[i].name += nameSeed[i];
		//通过循环给每名老师所带的学生赋值
		for (int j = 0; j < 5; j++) {
    
    
			tea[i].stus[j].name = "Student_";
			tea[i].stus[j].name += nameSeed[j];


			int scores = rand() % 61 + 40; // 0 ~ 100;
			tea[i].stus[j].score = scores;
		}
	}
}

void printInfo(Teacher tea[], int len) {
    
    
	for (int i = 0; i < 3; i++) {
    
    
		cout << "老师的姓名: " << tea[i].name << endl;
		for (int j = 0; j < 5; j++) {
    
    
			cout << "	学生的姓名: " << tea[i].stus[j].name << endl;
			cout << "	学生的分数: " << tea[i].stus[j].score << endl;
		}
	}
}

int main() {
    
    

	//随机数种子;
	srand((unsigned int)time(NULL));

	Teacher teachs[3];
	int len = sizeof(teachs) / sizeof(teachs[0]);
	allocateSpace(teachs, len);

	printInfo(teachs, len);

	system("pause");
	return 0;
}

8.8.2

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

struct heros {
    
    
	string name;
	int age;
	string sex;
};

void exchange(heros* H, int index) {
    
    
	heros temp;
	temp = H[index];
	H[index] = H[index + 1];
	H[index + 1] = temp;
}

void bubblesort(heros* H, int n) {
    
    
	for (int i = n - 1; i >= 0; i--) {
    
    
		for (int j = 0; j < n - 1; j++) {
    
    
			string names;
			int ages;
			string sexs;
			if ( H[j].age > H[j+1].age ) {
    
    
				exchange(H, j);
			}
		}
	}
}

int main() {
    
    
	heros Heros[5] = {
    
    
		{
    
    "刘备", 23, "boy"},
		{
    
    "关羽", 22, "boy"},
		{
    
    "张飞", 20, "boy"},
		{
    
    "赵云", 21, "boy"},
		{
    
    "貂蝉", 18, "girl"}
	};

	int len = sizeof(Heros) / sizeof(Heros[0]);

	bubblesort(Heros, len);
	for (int i = 0; i < 5; i++)
		cout << Heros[i].name << ' ' << Heros[i].age << endl;

	system("pause");
	return 0;
}

二、通讯录管理系统

#include<iostream>
using namespace std;
#include<string>
#define MAX 1000

void showMenu() {
    
    
	string gongneng[7] = {
    
     "1、添加联系人", "2、显示联系人", "3、删除联系人", "4、查找联系人", "5、修改联系人",
	"6、清空联系人", "0、退出通讯录" };
	for (int i = 0; i < 9; i++) {
    
    
		if (i == 0) {
    
    
			for (int j = 0; j < 29; j++) {
    
    
				cout << "*";
			}
			cout << endl;
		}
		else if (i == 8) {
    
    
			for (int j = 0; j < 29; j++) {
    
    
				cout << "*";
			}
			cout << endl;
		}
		else
			cout << "*****\t" << gongneng[i - 1] << "\t*****" << endl;
	}
}

//联系人结构体
struct Person {
    
    
	string name;
	int sex; //1代表男 2代表女 其他不通过
	int age;
	string tell;
	string address;
};


//通讯录结构体
struct Addressbooks {
    
    
	struct Person personArray[MAX];
	int m_Size;
};

void addusers(Addressbooks* address) {
    
    
	int cur = address->m_Size;
	while (1) {
    
    
		if (cur == MAX) {
    
    
			cout << "通讯录已满";
			break;
		}
		cout << "添加姓名: ";
		cin >> address->personArray[cur].name;
		cout << endl;
		cout << "添加性别: ";
		while (1) {
    
    
			int sexx;
			cin >> sexx;
			if (sexx == 1 || sexx == 2) {
    
    
				address->personArray[cur].sex = sexx;
				cout << endl;
				break;
			}
			cout << "输入非法,请重输:" << endl;
		}
		cout << "添加年龄: ";
		cin >> address->personArray[cur].age;
		cout << endl;
		cout << "添加电话: ";
		cin >> address->personArray[cur].tell;
		cout << endl;
		cout << "添加地址: ";
		cin >> address->personArray[cur].address;
		cout << endl;
		address->m_Size++;
		cout << "添加成功,请进行下一次操作!" << endl;
		system("pause");
		system("cls");//清屏操作
		break;
	}
}

void showusers(Addressbooks address) {
    
    
	if (address.m_Size == 0)
		cout << "没有联系人" << endl;
	for (int i = 0; i < address.m_Size; i++) {
    
    
		cout << "用户 " << i << ":" << endl;
		cout << "\t" << address.personArray[i].name << endl;
		cout << "\t" << (address.personArray[i].sex == 1 ? "男" : "女") << endl;
		cout << "\t" << address.personArray[i].age << endl;
		cout << "\t" << address.personArray[i].tell << endl;
		cout << "\t" << address.personArray[i].address << endl;
	}
	system("pause");
	system("cls");
}

int isExist(Addressbooks address, string name) {
    
    
	for (int i = 0; i < address.m_Size; i++) {
    
    
		if (address.personArray[i].name == name) {
    
    
			return i;//返回该用户的下标
		}
	}
	return -1;
}


//删除指定联系人
void deletePerson(Addressbooks* address) {
    
    
	cout << "请输入您要删除的联系人: " << endl;
	string name;
	cin >> name;
	if (isExist(*address, name) == -1) {
    
    
		cout << "查无此人" << endl;
	}
	else cout << "待删除联系人下标为: " << isExist(*address, name) << endl;
	int index = isExist(*address, name);
	//address->personArray[index] = address->personArray[address->m_Size - 1];
	//address->m_Size--;
	//cout << "删除成功" << endl;
	if (index < address->m_Size - 1) {
    
    
		for (int i = index; i < address->m_Size; i++) {
    
    
			address->personArray[index] = address->personArray[index + 1];
		}
	}
	address->m_Size--;
	cout << "删除成功: " << endl;
}

//查找
void find(Addressbooks address) {
    
    
	cout << "请输入您要查找的联系人: " << endl;
	string name;
	cin >> name;
	int flag = 0;
	for (int i = 0; i < address.m_Size; i++) {
    
    
		if (address.personArray[i].name == name) {
    
    
			cout << "姓名: " << address.personArray[i].name << endl;
			cout << "性别: " << (address.personArray[i].sex == 1 ? "男" : "女") << endl;
			cout << "年龄: " << address.personArray[i].age << endl;
			cout << "电话: " << address.personArray[i].tell << endl;
			cout << "地址: " << address.personArray[i].address << endl;
			flag = 1;
			break;
		}
	}
	if (flag == 0) cout << "查无此人" << endl;
	else cout << "查找成功" << endl;
}

int main() {
    
    
	int keyboard = 0;
	Addressbooks address;
	address.m_Size = 0;
	//实现退出功能
	while (true) {
    
    
		showMenu();
		cin >> keyboard;
		if (keyboard == 1) {
    
    //添加
			addusers(&address);
		}
		else if (keyboard == 2) {
    
    //显示
			showusers(address);
		}
		else if (keyboard == 3) {
    
    //删除
			deletePerson(&address);
			system("pause");
			system("cls");
		}
		else if (keyboard == 4) {
    
    //查找
			find(address);
			system("pause");
			system("cls");
		}
		else if (keyboard == 5) {
    
    //修改
			cout << "不写了" << endl;
			system("pause");
			system("cls");
		}
		else if (keyboard == 6) {
    
    //清空
			address.m_Size = 0;
			cout << "清空成功" << endl;
			system("pause");
			system("cls");
		}
		else if (keyboard == 0) {
    
    //退出
			cout << "成功退出系统";
			break;
		}
		else cout << "输入错误请重新输入" << endl;
	}

	return 0;
}

三、C++核心编程


四、基于多态的企业职工系统


五、C++提高编程


六、基于STL泛化编程的演讲比赛


七、C++实战项目机房预约管理系统


学习产出:

1、github 啃STL简化项目,能够自己实现STL相关项目
2、做一个微信小程序,具体功能暂定

猜你喜欢

转载自blog.csdn.net/qq_39274501/article/details/108761920
今日推荐