day04 c++复习

很无力的复习。

目录 

1、函数的声明 

2、分文件编写

1、函数的声明

在顺序中,可以先声明,证明有该函数,使编译器不报错,并在全编码搜索改函数, 这是由于c语言的特性决定的,因为c语言是从上往下走的,如果主函数前面没有该函数,编译器将不会运行该段编码,先声明则修补了这个问题,先声明,后运行。

有趣的是,函数的声明写很多次都不会有问题。


int max(int a, int b) ;     //在顺序中,可以先声明,证明有该函数,使编译器不报错,并在全编码搜索改函数
                          // 这是由于c语言的特性决定的,因为c语言是从上往下走的,如果主函数前面没有该函数,编译器将不会运行该段编码
	                       //先声明则修补了这个问题,先声明,后运行。

int main()
{
	int a = 0;
	int b = 0;                //创建变量

	cout << "请输入要比较的第一个数字" << endl;                   
	cin >> a;
	cout << "第二数字" << endl;
	cin >> b;
	
	cout <<"最大的为:  " << max(a, b) << endl;                //打印输出

	system("pause");

	return 0;
}
int max(int a, int b)
{
	return a > b ? a : b;        //三目运算符比较大小,a>b满足,输出a,否则输出b
}

2、分文件编写

为了降低主函数的复杂性和组合功能的实现,使用分文件的方式进行处理。

简单来说,为了保持主函数的简洁和分配工作,部分功能其他人编写测试完成后,通过分文件的方式插入到主函数中。

具体实现见下图

头文件编写

#pragma once
#include  
using namespace std;//因为分文件在本质上也是一个函数,因此同样执行iOS标准体系,
                     //源文件有的标准,他都有

int max(int a, int b)          //正常编写函数
{
	return a > b ? a : b;        //三目运算符比较大小,a>b满足,输出a,否则输出b
}

主文件编写

#include 
#include "max.h"           //在主函数中建立与分文件的链接
using namespace std;

int max(int a, int b);    //声明使用分文件的函数

int main()
{
	int a = 0;
	int b = 0;                //创建变量

	cout << "请输入要比较的第一个数字" << endl;
	cin >> a;
	cout << "第二数字" << endl;
	cin >> b;

	cout << "最大的为:  " << max(a, b) << endl;                //打印输出

	system("pause");

	return 0;
}

3、指针

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

c语言是将所有的数据存放在内存上,而每一个数据都一个地址,用来索引和查找

那么如何快速,直接的访问内存?使用指针

#include 
using namespace std;

int main()
{
	//1、创建一个数据
	int a = 10;
	//2、使用指针:数据类型 *指针的变量名:
	int* p;
	//3、让指针记录变量A的地址
	p = &a;
	//4、打印变量的地址
	cout << "变量a 的内存地址:"<<&a << endl;
	system("pause");

	return 0;
}

4、指针占有的内存地址

#include 
using namespace std;

int main()
{
	//1、创建一个数据
	int a = 10;
	//2、使用指针:数据类型 *指针的变量名:
	int* p;
	//3、让指针记录变量A的地址
	p = &a;
	//4、打印变量的地址
	cout << "变量a 的内存地址:"<<&a << endl;
	cout << *p << endl; //* 解引用
	cout << sizeof(p) << endl;
	cout << sizeof(char*) << endl;
	cout << sizeof(float*) << endl;
	cout << sizeof(double*) << endl;

	system("pause");

	return 0;
}

day04 c++复习_第1张图片

5、空指针

空指针:指针变量指向内存中编号为0的空间,实际上并不存在

用途:初始化指针变量

注意:空指针指向的内存是不可以访问的

#include 
using namespace std;

int main()
{
	//指针变量p指向内存地址编号为0的空间
	int* p = NULL;

	//访问空指针报错 
	//内存编号0 ~255为系统占用内存,不允许用户访问
	cout << *p << endl;

	system("pause");

	return 0;
}

day04 c++复习_第2张图片

 6、野指针

顾名思义,不明指向,错误指向都叫野指针

int main() {

	//指针变量p指向内存地址编号为0x1100的空间
	int * p = (int *)0x1100;

	//访问野指针报错 
	cout << *p << endl;

	system("pause");

	return 0;
}

day04 c++复习_第3张图片

 7、const修饰指针

是将指针固定的方法,防止意外将其改变。

const修饰指针有三种情况

  1. const修饰指针 --- 常量指针day04 c++复习_第4张图片

锁死,不得更改指针指向

2、const修饰常量 --- 指针常量

day04 c++复习_第5张图片

锁死指针的常量

3、const即修饰指针,又修饰常量

 

day04 c++复习_第6张图片

 指向和常量都锁死

#include 
using namespace std;

int main()
{
	//1/创建变量
	int a = 10;
	int b = 20;

	//2、const修饰的是指针,指针指向可以改,指针指向的值不可以更改
	const int* p1 = &a;
	//指向的值不可以改
	//*p = 20;更改报错
	p1 = &b; //更改指向允许,正确

     //3、const修饰的是常量,指针指向不可以改,指针指向的值可以更改
	int * const p2 = &a;
	//p2 = &b; 更改报错
	*p2 = 100; //更改指向常量的值,正确


	//4、const既修饰指针又修饰常量
	const int* const p3 = &a;
	//p3 = &b;
	//*p2 = 100;


	system("pause");

	return 0;
}

8、指针和数组

#include 
using namespace std;

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

	int* p = arr;

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

	p++;
	//利用指针遍历数组
	int* p2 = arr;
	cout << "利用指针遍历数组:" << endl;
	for (int i = 0; i < 9; i++)
	{
		cout << *p2 << "    ";
		p2++;
	}

	system("pause");

	return 0;
}

9、

指针和函数

#include 
using namespace std;

void swap01(int a,int b) //交换用的函数
{
	int temp = a;
	a = b;
	b = temp;

	cout << "形参a = " << a << endl;//形参

	cout << "形参b = " << b << endl;

}
void swap02(int * p1, int* p2)//指针更改函数
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}
int main()
{
	int a = 10;
	int b = 20;
	swap01(a, b);
	//swap02(&a, &b);
	cout << "实参a = " << a << endl;//实参

	cout << "实参b = " << b << endl;


	system("pause");

	return 0;
}

指针函数未启用时,

输出结果

day04 c++复习_第7张图片

启用swap02

 day04 c++复习_第8张图片

 交换,改变了原值

总结,正常的函数,从原内存地址调用后,进行处理,输出新的数据,但是指针可以返回原内存地址,更改初始数据。

10.案列,同时访问数组和函数

#include 
using namespace std;
//2、创建冒泡排序的函数  
void maopaopaixu(int* arr, int len)  //*arr是数组的首地址,len是数组长度
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
void print_array(int * arr,int len)  //3、打印函数
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " \t";
	}
}
int main() {
	//1、创建数组
	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
	//数组长度
	int len = sizeof(arr) / sizeof(arr[0]);

	maopaopaixu(arr, len);
	//3.打印排序后的数组
	print_array(arr, len);

	system("pause");

	return 0;
}

用法参考本day8、9。

11.结构体

结构体基本概念

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

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

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

  • struct 结构体名 变量名

  • struct 结构体名 变量名 = { 成员1值 , 成员2值...}

  • 定义结构体时顺便创建变量

#include 
#include
using namespace std;

struct student//创建一个学生的结构体
{
	//姓名
	string name;
	//年龄
	int age;
	//分数
	int score;

};

//2通过学生类型创建具体学生



int main() 
{
	//2.1第一种结构体定义方式   学生1的属性
	struct student s1;
	s1.name = "张三";
	s1.age = 18;
	s1.score = 88;

	cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
	//2.2第一种结构体定义方式   学生2的属性
	struct student s2 = { "李四" ,20,99 };
	cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl;
	system("pause");

	return 0;
}

值得注意的是,使用第二种方法,要保证上下数据对应正确,否则报错,详见下图

day04 c++复习_第9张图片

12. 结构体数组

#include 
#include
using namespace std;
//结构体数组

//1、定义结构体
struct student
{
	//姓名
	string name;
	//年龄
	int age;
	//分数
	int score;
};

int main() 
{
	//2、创建结构体数组
	struct student std_arry[3] =
	{
		{"张三",18,99},
		{"李四",22,88},
		{ "赵四",23,77}
	};
	//3、改变结构体数组中的元素赋值
	std_arry[2].age = 88;
	std_arry[2].score = 100;
	//4.遍历结构体中的数组
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名:" << std_arry[i].name << "\t" << "年龄:" << std_arry[i].age << "\t" << "分数:" << std_arry[i].score << endl;
	}

	system("pause");

	return 0;
}

这里用的是一个二维数组,请注意命名方式

13.结构体指针

主要是讲述用->去访问结构体指针的属性。

#include 
#include
using namespace std;
struct student
{
	//姓名
	string name;
	//年龄
	int age;
	//分数
	int score;
};

int main() 
{
	//创建学生结构体变量
	struct student s = { "张三",18,100 };
	//通过指针指向结构体变量
	struct student *p = &s;    //此时的struct 可以省略

	//通过指针访问结构体变量中的数据
	cout << "姓名: " << p->name << "  " << "年龄:" << p->age << "  " << "分数:" << p->score << endl;
	//注意通过结构体指针,访问结构体中的的属性,需要利用“->”
	system("pause");
	return 0;
}

14.结构体嵌套结构体

一个结构体可以担当另外一个结构体的数据,用法非常简单粗暴,只需要在声明一个结构体,既可以在另外一个结构体中使用,来表明从属关系,但是有趣的是,测过测试,一个结构体一旦使用了数组,那么就不能在嵌套结构体。错误原因为数据类型不匹配。

看了下面的实际案例是应该是我的问题。我找个时间试试

#include 
#include
using namespace std;
//定义老师的结构体
struct student
{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

//教师结构体定义
struct teacher
{
	//成员列表
	int id; //职工编号
	string name;  //教师姓名
	int age;   //教师年龄
	struct student stu; //子结构体 学生
};
int main() {

	struct teacher t1;
	t1.id = 10000;
	t1.name = "老王";
	t1.age = 40;

	t1.stu.name = "张三";
	t1.stu.age = 18;           //此处不能使用数组来实现一对多,原因为数据类型不匹配
	t1.stu.score = 100;

	cout << "教师 职工编号: " << t1.id << " 姓名: " << t1.name << " 年龄: " << t1.age << endl;
	cout << "辅导学员 姓名: " << t1.stu.name << " 年龄:" << t1.stu.age << " 考试分数: " << t1.stu.score << endl;
	system("pause");

	return 0;
}

15、结构体做函数参数

在函数中访问结构体的数据,使用方法与在main中一致,创建函数后,讲数据传入函数中即可

void print_student1(struct student s)

在函数内部使用也是一样的,使用  .  即可快速链接结构体属性,详见代码

第二,有两种使用方法,有值传递和地址传递两种,其中要注意,使用地址传递,如果在函数内修改数值,原地址的数据随之改变。

#include 
#include
using namespace std;
//学生结构体定义
struct student
{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};
//打印学生信息函数
//值传递
void print_student1(struct student s)
{
	cout << "子函数中(值传递)姓名:" << s.name << " 年龄: " << s.age << " 分数:" << s.score << endl;
}
//地址传递
void print_student2(struct student * s)
{
	cout << "子函数中(地址传递)姓名:" << s->name << " 年龄: " << s->age << " 分数:" << s->score << endl;
	//测试改变原值代码
	s->age = 180;

}

int main() {

	//创建一个结构体变量
	struct student s = { "张三",18,100 };
	print_student1(s);
	print_student2(&s);

	//测试原值是否改变
	cout << "使用地址传递后的原数据是否被改变,原值为18。" << s.age << endl;
	system("pause");

	return 0;
}

16.const的用法

const是为了防止原数据发生变化用的。在函数引入数据后加上const 即可锁定,如果改数据,就会报错。

主要用途,使用值传递,在传输数据时会复制数据,但是在面对兆级数据时,内存占用过大,因此这个时候通常使用指针,但指针访问属性,使用地址访问,对原数据可能造成威胁,为避免改动原数据,在使用地址传递时,不对原属性做改变的,加上const锁死。

//学生结构体定义
struct student
{
	//成员列表
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

//const使用场景
void printStudent(const student *stu) //加const防止函数体中的误操作
{
	//stu->age = 100; //操作失败,因为加了const修饰
	cout << "姓名:" << stu->name << " 年龄:" << stu->age << " 分数:" << stu->score << endl;

}

int main() {

	student stu = { "张三",18,100 };

	printStudent(&stu);

	system("pause");

	return 0;
}

17.结构体实例

#include 
#include
using namespace std;
//学生的结构体
struct student
{
	//姓名
	string student_name;
	int score;
};
//老师的结构体
struct teacher
{
	//姓名
	string teacher_name;

   //学生数组
	struct student s_arry[5];
};
//随机给老师、学生的信息进行赋值
void all_ocate_space( teacher t_arry[], int len)
{
	string name_seed = "abcdef";   //随机的赋值
	//给老师来赋值
	for (int i = 0; i < len; i++)
	{
		t_arry[i].teacher_name = "老师_";  //老师姓名和abcde连接在一起,让他们循环衔接的
		t_arry[i].teacher_name += name_seed[i];
		for (int j = 0; j < 5; j++)
		{
			t_arry[i].s_arry[j].student_name = "学生_";
			t_arry[i].s_arry[j].student_name += name_seed[j];//学生姓名和abcde连接在一起,让他们循环衔接的
			int random = rand() % 61 + 40;               //使用了一个随机数
			t_arry[i].s_arry[j].score = random;
		}
	}
}

void print_all(struct teacher t_arry[], int len)
{
	for (int i = 0; i < len; i++)
	{
		//循环打印老师的信息
		cout << "老师的姓名:: " << t_arry[i].teacher_name << endl;    
		//循环打印学生的信息
		for (int j = 0; j < 5; j++)
		{
			cout << "学生姓名: " << t_arry[i].s_arry[j].student_name <<
				"   考试分数: " << t_arry[i].s_arry[j].score << endl;
		}
	}
}

int main()
{
	//1/创建3名老师的数组
	struct teacher t_arry[4];
	//2.通过函数给4名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(t_arry) / sizeof(teacher);
	//给老师和学生赋值
	all_ocate_space(t_arry, len);
	//打印所有的信息
	print_all(t_arry, len);
	system("pause");

	return 0;
}

分段讲解

第一创建老师和学生的结构体

struct student
{
	//姓名
	string student_name;
	int score;
};
//老师的结构体
struct teacher
{
	//姓名
	string teacher_name;

   //学生数组
	struct student s_arry[5];
};

学生结构体较为简单,和之前一样,由字符串和整形数字组成

但是老师要注意,构建学生结构体时,使用的数据类型为数组,这说明一个老师对应着五个学生。

在main函数中对老师和学生的结构体进行赋值

//1/创建3名老师的数组
	struct teacher t_arry[4];
	//2.通过函数给4名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(t_arry) / sizeof(teacher);
	//给老师和学生赋值
	all_ocate_space(t_arry, len);

首先制定了几名老师,这里经测试t_arry[ ]内的数据不可以是len,这是语序的问题,想要实现,需要用别的方法。

len是用t_arry和teacher比较出来的。

接下来进行两个函数的操作

allocateSpace(tArray, len); //创建数据

	printTeachers(tArray, len); //打印数据

创建数据

//随机给老师、学生的信息进行赋值
void all_ocate_space( teacher t_arry[], int len)
{
	string name_seed = "abcdef";   //随机的赋值
	//给老师来赋值
	for (int i = 0; i < len; i++)
	{
		t_arry[i].teacher_name = "老师_";  //老师姓名和abcde连接在一起,让他们循环衔接的
		t_arry[i].teacher_name += name_seed[i];
		for (int j = 0; j < 5; j++)
		{
			t_arry[i].s_arry[j].student_name = "学生_";
			t_arry[i].s_arry[j].student_name += name_seed[j];//学生姓名和abcde连接在一起,让他们循环衔接的
			int random = rand() % 61 + 40;               //使用了一个随机数
			t_arry[i].s_arry[j].score = random;
		}
	}
}

引入数据类型是struct 中的teacher中的数组,和len

然后给老师、学生的姓名随机赋值

随机来源为 name_seed,依序打印,这里是先创建一个老师_,再加上上面一次打印的name_seed。有另外一种方法

void allocateSpace(Teacher tArray[] , int len)
{
	string tName = "教师";
	string sName = "学生";
	string nameSeed = "ABCDE";
	for (int i = 0; i < len; i++)
	{
		tArray[i].name = tName + nameSeed[i];
		
		for (int j = 0; j < 5; j++)
		{
			tArray[i].sArray[j].name = sName + nameSeed[j];
			tArray[i].sArray[j].score = rand() % 61 + 40;
		}
	}
}

先创建数据后,在缝合即可

随后在老师的循环下,再去创建学生,这里要注意顺序问题,以防眼花输错,本人出现类似问题,修改半天。

要先找到对应的t_arry[ i ],在去对应student_name[ j ],

这里使用了一个rand函数去构建分数的随机值。

然后,打印数据

void print_all(struct teacher t_arry[], int len)
{
	for (int i = 0; i < len; i++)
	{
		//循环打印老师的信息
		cout << "老师的姓名:: " << t_arry[i].teacher_name << endl;    
		//循环打印学生的信息
		for (int j = 0; j < 5; j++)
		{
			cout << "学生姓名: " << t_arry[i].s_arry[j].student_name <<
				"   考试分数: " << t_arry[i].s_arry[j].score << endl;
		}
	}
}

同样简单,根据系统提示,找到想对应关系即可,但要注意其中的数据类型和对应关系,对应错误也可能不会报错,但运行的结果,会变成乱码的地址。

最后运行结果如图

day04 c++复习_第10张图片

 今日学习,结束,晚上进行通讯录管理系统的构建。

你可能感兴趣的:(c++,开发语言)