【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体

(内容来自小破站《黑马程序员C++》复习自用,从入门到劝退)

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体

  • 6 函数
    • 6.1 概述
    • 6.2 函数的定义(五个步骤)
    • 6.3 函数的调用
    • 6.4 值传递
    • 6.5 函数的常见样式
    • 6.6 函数的声明
    • 6.7 函数的分文件编写
  • 7 指针
    • 7.1 指针的概念
    • 7.2 指针变量的定义和使用
    • 7.3 指针所占内存空间
    • 7.4 空指针&野指针
    • 7.5 const 修饰指针(康斯特)
      • 7.5.1 const 修饰指针——常量指针
      • 7.5.2 const 修饰常量——指针常量
      • 7.5.3 const 即修饰指针,又修饰常量
    • 7.6 指针和数组
    • 7.7 指针和函数(值传递&地址传递)
    • 7.8 指针、数组、函数
  • 8 结构体
    • 8.1 结构体的基本概念
    • 8.2 结构体定义和使用 (创建一个学生数据类型)
    • 8.3 结构体数组
    • 8.4 结构体指针
    • 8.5 结构体嵌套结构体
    • 8.6 结构体做函数参数
    • 8.7 结构体中const使用场景
    • 8.8 结构体案例
      • 8.8.1 案例一:3老师+15学生
      • 8.8.2 案例二:英雄排序

6 函数

6.1 概述

作用:讲一段经常使用的代码封装起来,减少重复代码。

6.2 函数的定义(五个步骤)

  1. 返回值类型
  2. 函数名
  3. 参数列表
  4. 函数体语句
  5. return表达式
// 语法:
返回值类型 函数名(参数列表){
	函数体语句
	return表达式
}
int add(int num1, int num2) {
	int sum = num1 + num2;
	return sum;
}

6.3 函数的调用

int add(int num1, int num2)
{
	int sum = num1 + num2;
	return sum;
}

int main()
{
	//main函数中调用add函数
	int a = 10;
	int b = 20;
	//函数调用语法:函数名称(参数)
	//ab成为“实际参数”,简称“实参”、
    //当调用函数的时候,实参的值会传递给形参,计算结果给c
		int c = add(a, b);
	cout << "c = " << c << endl;
	system("pause");
	return 0;
}

6.4 值传递

值传递,就在函数调用的时候,实参将数值传给形参,值传递时,如果形参发生改变,并不会影响实参。

#include 
using namespace std;
#include 
//定义函数,实现两个数字进行交换函数
//如果函数不需要返回值,声明的时候可以谢void
void swap(int num1, int num2)
{
	cout << "交换前: " << endl;
	cout << "num1 =  " << num1 << endl; cout << "num2 =  " << num2 << endl;
	int temp = num1; num1 = num2; num2 = temp;
	cout << "交换后: " << endl;
	cout << "num1 =  " << num1 << endl; cout << "num2 =  " << num2 << endl;
	temp = num1; num1 = num2; num2 = temp;
	return;//返回值不需要的时候,可以不写return
}
int main()
{
	int a = 10; int b = 20;
	cout << "a = " << a << endl; cout << "b = " << b << endl;
	swap(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << " 值传递时,如果形参发生改变,并不会影响实参" << endl;
	system("pause");
	return 0;
}

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第1张图片

6.5 函数的常见样式

  1. 无参无返
  2. 有参无返
  3. 无参有返
  4. 有参有返
#include 
using namespace std;
#include 

//1. 无参无返
void test01() {
	cout << "this is test01" << endl;
}

//2. 有参无返
void test02(int a) {
	cout << "this is test02, a = " << a << endl;
}

//3. 无参有返
int test03() {
	cout << "this is test03, and ";
	return 200;
}

//4. 有参有返
int test04(int a) {
	cout << "this is test04, and a = " << a << endl;
	return a;
}

//函数调用
int main() {
	test01();
	test02(100);
	int num03 = test03();
	cout << "num03 = " << num03 << endl;
	int num04 = test04(404);
	cout << "num04 = " << num04 << endl;
	system("pause");
	return 0;
}

在这里插入图片描述

6.6 函数的声明

作用:告诉编译器函数名称以及如何调用函数,函数的实际主体可以单独定义。函数的声明可以多次,到那时函数的定义只能有一次。

#include 
using namespace std;
#include 
//比较函数,两个整型数字比较,返回较大值
//声明可以写很多次,但是定义只能写一次
int maax(int a, int b);
int maax(int a, int b);
int maax(int a, int b);
//定义
int maax(int a, int b)
{
	return a > b ? a : b;
}
    //int maax(int a, int b) } 
    //错的,定义只能写一次
    //	return a > b ? a : b;
    //}
int main() {
	int a = 10;
	int b = 20;
	cout << maax(a, b) << endl;
	system("pause");
	return 0;
}

6.7 函数的分文件编写

作用:让代码结构更加清晰。

  1. 创建.h头文件
  2. 创建.cpp源文件
  3. 在头文件中写函数的声明
  4. 在源文件中写函数的定义
    【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第2张图片

7 指针

7.1 指针的概念

作用:可以通过指针间接访问内存
内存编号是从0开始记录的,一般用十六进制数字表示,可以利用指针变量保存地址

7.2 指针变量的定义和使用

语法:数据类型 * 变量名;

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

7.3 指针所占内存空间

指针也是种数据类型

#include 
using namespace std;
#include 
int main() {
	//指针所占内存空间
	int a = 10;
	int* p = &a;
	//在32位操作系统下,指针占4个字节空间大小,不论什么数据类型,64位-8个字节。
	cout << "sizeof (int *) = " << sizeof(p) << endl;
	cout << "sizeof (float *) = " << sizeof(float*) << endl;
	cout << "sizeof (double *) = " << sizeof(double*) << endl;
	cout << "sizeof (char *) = " << sizeof(char*) << endl;
	system("pause");
	return 0;
}

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第3张图片

7.4 空指针&野指针

空指针:指针变量指向内存中编号为零的空间。
用途:初始化指针变量。
注意:空指针指向的内存是不可以访问的。
【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第4张图片
野指针:指针变量指向非法的内存空间
【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第5张图片

7.5 const 修饰指针(康斯特)

三种情况:
① const 修饰指针——常量指针;
② const 修饰常量——指针常量;
③ const即修饰指针——又修饰常量。

7.5.1 const 修饰指针——常量指针

指针的指向可以修改,但是指针指向的值不可以修改
【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第6张图片

int a = 10;
int b = 10;
int * p = &a;

说明:创建变量a,存放了10,b存放了10,a的地址编号是0x0011,b的地址编号是0x0022,p指向的是a,保存的就是a的地址0x0011。const修饰指针,就是在指针的前边加一个const。
const int * p = &a; //常量指针// 特点:指针的指向可以修改,但是指针指向的值不可以修改。
判断正误:

*p = 20;
     // *p是对p指向的内存进行操作,p指向的0x0011,想把10要改成20。
P = &b; 
     // 正确,指针的指向可以更改

7.5.2 const 修饰常量——指针常量

int * const p = &a;  //这种形式是指针常量 
// 特点:指针的指向不可以改,但是指针指向的值可以修改。

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第7张图片

7.5.3 const 即修饰指针,又修饰常量

const int * const p = &a;
// 特点:指针的指向,和,指针指向的值,都不可以修改

7.6 指针和数组

目的:利用指针访问数组中的每一个元素。(数组是一段连续的空间中,存放了相同类型的数据元素)

#include 
using namespace std;
#include 

int main() {
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	cout << "第一个元素为: " << arr[0] << endl;  //正常访问数组内第一个元素。

	int* p = arr;  //arr就是数组名就是数组的首地址,*p解引用,就能解出来数组的第一个数据。

	cout << "利用指针访问第一个元素为: " << *p << endl;

	p++; //让指针向后偏移四个字节
	cout << "利用指针访问第二个元素为: " << *p << endl << endl;
	cout << "开始利用指针遍历数组" << endl;
	int* p2 = arr;
	for (int i = 0; i < 10; i++)
	{
		//cout << arr[i] << endl;
		cout << *p2 << endl;
		p2++;
	}
	system("pause");
	return 0;
}

7.7 指针和函数(值传递&地址传递)

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

  1. 值传递
  2. 地址传递
#include
using namespace std;
#include
//实现两个数字进行交换
void swap01(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
	cout << "swap01 a = " << a << endl;
	cout << "swap01 b = " << b << endl;
}

void swap02(int* p1, int* p2)    // int了两个指针 p1 p2
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
	cout << "swap02 *p1 = " << *p1 << endl;
	cout << "swap02 *p2 = " << *p2 << endl;
}
int main()
{
	//1.值传递
	int a = 10;
	int b = 20;
	//swap01(a, b);
	//cout << "a = " << a << endl;
	//cout << "b = " << b << endl;

	//2.地址传递(地址传递可以修饰实参)
	swap02(&a, &b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;//将输出a=20,b=10
	system("pause");
	return 0;
}

7.8 指针、数组、函数

案例描述:封装一个函数,冒泡排序,实现对整型数组{4,3,6,9,1,2,10,8,7,5}的升序排列。

#include
using namespace std;
#include

void bubbleSort(int* arr, int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - 1 - i; j++)
		{
			//如果j > j+1的值,交换数字
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
  //打印数组
void printArray(int* arr, int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		cout << arr[i] << " < ";
	}
	cout << 10 << endl << endl;
}

int main() {
	//1.先创建数组
	int arr[] = { 4,3,6,9,1,2,10,8,7,5 };
	int len = sizeof(arr) / sizeof(arr[0]);//数组长度
	//2.创建函数,实现冒泡排序
	bubbleSort(arr, 10);
	//3.打印排序后的数组
	printArray(arr, len);
	system("pause");
	return 0;
}

8 结构体

8.1 结构体的基本概念

结构体属于用户自定义的数据类型,允许用户存储不同的数据类型(整形、浮点型、字符型、布尔数据类型、字符串型)。可以创建无数个,只要开心可以随意写。

8.2 结构体定义和使用 (创建一个学生数据类型)

语法:struct 结构体名{ 结构体成员列表 };
通过结构体创建变量的方式 *3

  1. struct 结构提名 变量名
  2. struct 结构体名 变量名 = {成员1值, 成员2值…}
  3. 定义结构体时顺便创建变量
#include
using namespace std;
#include

//1. 创建学生数据类型:学生包括(姓名,年龄,分数)
struct Student
{
	//成员列表
	//姓名
	string name;
	//年龄
	int age;
	//分数
	int score;
}s3;

//2. 通过学生类型创建具体学生
int main()
{
	//2.1 struct Student s1
	struct Student s1;
	//进行赋值
	s1.name = "AA";
	s1.age = 18;
	s1.score = 100;
	cout << "name:" << s1.name << "  s1.age:" << s1.age << "  score: " << s1.score << endl;   //s1.name是一个string,所以需要include 包含一下这个头文件

	//2.2 stuct Student s2 = { ... }
	struct Student s2 = { "CC" , 19,80 }; //按顺序给初值
	cout << "name:" << s2.name << "  s2.age:" << s2.age << "  score: " << s2.score << endl;

	//2.3 在定义结构体时顺便创建结构体变量
	s3.name = "ccc"; //赋初值
	s3.age = 18;
	system("pause");
	return 0;
}

8.3 结构体数组

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

#include 
using namespace std;
#include    //记得包含头文件

    //1. 定义一个结构体
struct student
{
	string name;//姓名年龄分数
	int age;
	int score;
};
int main()
{
	//2. 创建结构体数组
	struct student stuArray[3] =
	{
		{ "AA", 18, 100 },
		{ "BB", 19, 95 },
		{ "CC", 20, 99 },
	};
	//3. 给结构体数组中的元素赋值
	stuArray[2].name = "GG";
	stuArray[2].age = 80;
	stuArray[2].score = 60;
	//4. 遍历(访问)结构体数组
	int i = 0;
	for (int i = 0; i < 3; i++)
	{
		cout << "Stu01's name: " << stuArray[i].name
			<< "      Age: " << stuArray[i].age
			<< "      Score: " << stuArray[i].score << endl << endl;
	};
	system("pause");
	return 0;
}

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第8张图片

8.4 结构体指针

作用:通过指针访问结构体中的成员。利用操作符->可以通过结构体指针访问结构体属性。

#include 
using namespace std;
#include 

// 定义学生结构体
struct student
{
	string name;
	int age;
	int score;
};
int main()
{
//1. 创建学生结构体变量
	struct student s = { "AA",18,100 };

	//2. 通过指针指向结构体变量
	struct student* p = &s;
	//3. 通过指针访问结构体变量中的数据'->'
	cout << "name: " << p->name << endl << endl
		 << "age:"   << p->age << endl << endl
		 << "score"  << p->score << endl << endl;
			system("pause");
	return 0;
}

8.5 结构体嵌套结构体

作用:结构体中的成员可以是另一个结构体
【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第9张图片

#include 
using namespace std;
#include 

//1. 定义学生结构体
struct student
{
	string name;    // 学生姓名
	int age;      // 学生年龄
	int score;    // 考试分数
};
struct teacher
{
	int id;       // 教师编号
	string name;  // 教师姓名
	int age;    // 教师年龄
	struct student stu;  // 辅导的学生
};

int main()
{
	teacher t;     // t老师
	t.id = 20253001;
	t.age = 30;
	t.name = "TT";   // t老师的名字是TT
	t.stu.name = "yy";  // TT老师的学生是yy
	t.stu.score = 78;   //这个学生考了78分
	cout << t.name << "    " << t.id << "    " << t.stu.score << endl;
	system("pause");
	return 0;
}

8.6 结构体做函数参数

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

  1. 值传递
  2. 地址传递
#include 
using namespace std;
#include 

//定义一个学生结构体
struct student
{
	//姓名,年龄,分数
	string name;
	int age;
	int score;
};

//打印学生信息的函数
//1. 值传递
void printStudent1(struct student s)
{
	s.age = 100;
	cout << "子函数1中  姓名:" << s.name << " 年龄:" << s.age << endl;
}
//2. 地址传递
void printStudent2(struct student* p)
{
	p->age = 200;
	cout << "子函数2中  姓名:" << p->name << "  年龄:" << p->age << endl;
}
int main()
{
	//将学生传入到一个参数中,打印学生身上的所有信息

	//创建结构体变量
	struct student s;
	s.name = "张三";
	s.age = 20;
	s.score = 85;
	printStudent1(s);
	printStudent2(&s);
	cout << "main函数中打印  姓名:" << s.name << "  年龄:" << s.age << endl;

	system("pause");
	return 0;
}

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第10张图片

8.7 结构体中const使用场景

作用:使用const来防止误操作,康斯特,可读不可写
看到康斯特,就代表了是要限定一个只读状态,防止修改操作。
【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第11张图片

#include 
using namespace std;
#include 

struct student {
	string name;
	int age;
	int score;
};     // 先写一个结构体

//将函数中的形参改为指针,可以减少内存空间,指针只占四个字节,并且不会复制一个新的副本出来
void printStudents(const student* s)
{
	//s->age = 150;
	cout << "姓名:" << s->name << "   年龄:" << s->age << endl;
}
int main() {
	//创建结构体变量
	struct student s = { "张三" , 15,70 };    // 15岁、70分

	//通过函数打印结构体变量信息
	printStudents(&s);
	cout << "main's.age:  " << s.age << endl;
	system("pause");
	return 0;
}
/*值传递:
void printStudents(student s) {
cout << "name: " << s.name << endl;}
主函数中 printStudents(s);
在值传递中,void中是s和主函数struct student s中的s,不是同一个s。
如果在void中加一个s.age = 150; 把年龄改成了150岁,main中的s不会修改。
因为值传递会把s中所有的数据拷贝出来一份,放在void printStudents(student s)形参中的s中。*/

8.8 结构体案例

8.8.1 案例一:3老师+15学生

案例描述:
毕设,每名老师带领五个学生,共三名老师,设计学生和老师的结构体。在老师的结构体中,有老师姓名和一个存放五名学生的数组作为成员。学生的成员有姓名、考试分数。创建数组存放三名老师,通过函数给每一个老师及所带学生赋值,最终打印出老师数据和老师所带学生数据。

#include 
using namespace std;
#include 

struct Student //学生的结构体
{
	string sName;
	int score;
};
struct Teacher//老师的结构体
{
	string tName;
	struct Student sArray[5];
};
string nameSeed = "ABCDE";
//给老师赋值的函数
void allocateSpace(struct Teacher tArray[], int len)
{
	for (int i = 0; i < len; i++) //开始给老师赋值了
	{
		tArray[i].tName = "Teacher_";
		tArray[i].tName += nameSeed[i];
		//通过循环给每名老师带的学生赋值
		for (int j = 0; j < 5; j++)
		{
			tArray[i].sArray[j].sName = "Student_";
			tArray[i].sArray[j].sName += nameSeed[j];
			int random = rand() % 61 + 40; // 40~100
			tArray[i].sArray[j].score = random;
		}
	}
}
//打印所有信息
void printInfo(struct Teacher tArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "老师姓名:" << tArray[i].tName << endl;
		for (int j = 0; j < 5; j++)
		{
			cout << "\t学生姓名:" << tArray[i].sArray[j].sName << "   考试分数:" << tArray[i].sArray[j].score << endl;
		}
	}
}
int main()
{
	srand((unsigned int)time(NULL));//随机数种子#include 
//1. 创建三名老师的数组
	struct Teacher tArray[3];
	//2. 通过函数给三名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(tArray) / sizeof(tArray[0]);
	allocateSpace(tArray, len);
	//3. 打印所有老师及所带学生的信息
	printInfo(tArray, len);

	system("pause");
	return 0;
}

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第12张图片

8.8.2 案例二:英雄排序

案例描述:
设计一个英雄的结构体,包括成员姓名、年龄、性别。创建结构体数组,数组中存放五名英雄,通过冒泡排序算法,将数组中的英雄按照年龄进行升序排序,并打印排序后的结果。(设定:刘备23、关羽22、张飞20、赵云21、貂蝉19。)

#include 
using namespace std;
#include 
//1. 设计英雄结构体
struct Hero
{
	string name;
	int age;
	string sex;
};
//冒泡排序,实现年龄升序排列
void bubbleSort(struct Hero heroArray[], int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - 1 - i; j++)
		{
			//如果j下表的元素年龄大于j+1下表的元素的年龄,交换这两个元素
			if (heroArray[j].age > heroArray[j + 1].age)
			{
				struct Hero temp = heroArray[j];
				heroArray[j] = heroArray[j + 1];
				heroArray[j + 1] = temp;
			}
		}
	}
}
//打印排序后的信息
void printHero(struct Hero heroArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "姓名:" << heroArray[i].name << "   年龄:" << heroArray[i].age << "   性别:" << heroArray[i].sex << endl;
	}
}
int main()
{
	//2. 创建数组存放5名英雄
	struct Hero heroArray[5] =
	{
		{"刘备",23,"男"},
		{"关羽",22,"男"},
		{"张飞",20,"男"},
		{"赵云",21,"男"},
		{"貂蝉",19,"女"},
	};
	int len = sizeof(heroArray) / sizeof(heroArray[0]);
	/*输出测试*/
	for (int i = 0; i < len; i++)
	{
		cout << "姓名:" << heroArray[i].name << "   年龄:" << heroArray[i].age << "   性别:" << heroArray[i].sex << endl;
	}
	//3. 对数组进行排序,按照年龄进行排序
	bubbleSort(heroArray, len);
	cout << endl << "排序后打印结果:" << endl;
	//4. 将排序后的结果进行输出
	printHero(heroArray, len);
	system("pause");
	return 0;
}

【学习笔记】C++ 基础入门(三)函数 + 指针 + 结构体_第13张图片

你可能感兴趣的:(C++,从入门到劝退,c++)