第一阶段C++基础入门(黑马程序员)——Day4

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

7 指针

7.1指针的基本概念

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

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

通过指针保存地址;指针就是一个地址;


7.2指针变量的定义和使用

指针变量定义语法:数据类型 * 变量名;

1、定义指针

int a = 10;

//1、定义指针
int * p;
p = &a;

cout << "a的地址为:" << &a <<endl;
cout << "指针p为:" << p << endl;  //两者都为a的地址

2、使用指针

int a = 10;

//2、使用指针
//可以通过解引用的方式找到指针指向的内存中的数据
//指针前加*代表解引用
*p = 1000;
cout << "a=" << a << endl;  //a=1000
cout << "*p=" << *p << endl;  //*p=1000

7.3指针所占内存空间 

在32位操作系统下,任何数据类型的指针都只占用4个字节空间;64位下占8个字节空间;

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

cout<<"int * 内存空间:"<<sizeof(p)<<endl;          //4字节
cout<<"int * 内存空间:"<<sizeof(int *)<<endl;      //4字节
cout<<"float * 内存空间:"<<sizeof(float *)<<endl;  //4字节
cout<<"double * 内存空间:"<<sizeof(double *)<<endl;  //4字节
cout<<"char * 内存空间:"<<sizeof(char *)<<endl;     //4字节

7.4空指针和野指针

空指针:指针变量指向内存中编号为0的空间

用途:初始化指针变量

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

//指针变量p指向内存地址为0的空间
	int * p = NULL;
  
	//访问空指针报错
	//0~255之间的内存编号是系统占用的,因此不可以访问
	cout << "*p" << endl;

野指针:指针变量指向非法的内存空间

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

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

总结:空指针和野指针都不是我们申请的空间,因此不要访问;


7.5const修饰指针

const修饰指针有三种情况:

  1.  const修饰指针——常量指针(const int * p)
  • 指针的指向可以修改,指针指向的值不可修改;
int a = 10;
int b = 20;
const int * p = &a;  //常量指针

*p=20; //错误,指针指向的值不可修改
p=&b;  //正确,指针的指向可以修改
  1. const修饰常量——指针常量(int * const p)
  • 指针的指向不可以修改,指针指向的值可以修改;
int a = 10;
int b = 20;
int * const p = &a; //指针常量

*p=20; //正确,指针指向的值可以修改
p=&b;  //错误,指针的指向不可以修改
  1. const即修饰指针,又修饰常量
  • 指针的指向不可以修改,指针指向的值不可以修改;
int a = 10;
int b = 20;
const int * const p = &a; //指针常量

*p=20; //错误,指针指向的值不可以修改
p=&b;  //错误,指针的指向不可以修改

7.6指针和数值

作用:利用指针访问数组中元素

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

	int* p = arr;  //arr是数组的首地址
	cout << "第一个元素:" << *p << endl;  //第一个元素:1

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

7.7指针和函数

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

#include <iostream>
using namespace std;

//两个数字交换
//值传递
void swap01(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
}

//地址传递
void swap02(int *p1, int *p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

int main()
{

	int a = 10;
	int b = 20;

	//1、值传递:不会改变实参
	swap01(a, b);

	//2、地址传递:会改变实参
	swap02(&a, &b);
	
	system("pause");
	return 0;
}

7.8指针、数组、函数

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

如数组:int arr[10]=(4,3,6,9,1,2,10,8,7,5)

#include <iostream>
using namespace std;

//参数1 数组的首地址  参数2 数组长度
void bubbleSort(int *arr,int len)
{
	for(int i=0;i<len-1;i++)
	{
		for (int j = 0; j < len - i - 1; 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; i++)
	{
		cout << arr[i] << endl;
	}
}
int main()
{
	
	//1、创建数组
	int arr[10] = {4,3,6,9,1,2,10,8,7,5 };
	//数组长度
	int len = sizeof(arr) / sizeof(arr[0]);

	//2、创建函数,实现冒泡排序
	int end = sizeof(arr) / sizeof(arr[0])-1;
	bubbleSort(arr,len);

	//3、打印排序后的数组
	printArray(arr, len);

	system("pause");
	return 0;
}

8结构体

8.1结构体基本概念

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


8.2结构体定义和使用

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

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

  •  struct 结构体名 变量名
  •  struct 结构体名 变量名 = { 成员1值, 成员2值... }
  • 定义结构体时顺便创建变量
//结构体定义
//1、创建学生数据类型: 学生(姓名,年龄,分数)
struct Student
{
	//成员列表
	string name; 
	int age;     
	int score;   
}s3;  //方式3


int main()
{
	//2、通过学生类型创建具体学生
	//方式1
	struct Student s1;
	s1.name = "张三";
	s1.age = 18;
	s1.score = 100;

	//方式2
	struct Student s2 = { "李四",19,80 };

	system("pause");
	return 0;
}
  • 创建结构体变量时,struct关键字可省略;
  • 结构体变量利用操作符"."访问成员;
Student s1;
s1.age = 13;

8.3结构体数组

作用:将自定义的结构体放入到数组中方便维护

语法: struct 结构体名 数组名[元素个数] = { {},  {},  ...{} }

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

//1、定义结构体
struct Student
{
	string name; 
	int age;     
	int score;   
}; 

int main()
{
	//2、创建结构体数组
	struct Student stdArray[3]=
	{
		{"张三",18,100},
		{"李四",28,99},
		{"王五",38,66}
	};
	
	//3、给结构体数组中的元素赋值
	stdArray[2].name = "赵六";
	stdArray[2].age = 80;
	stdArray[2].score = 60;

	//4、遍历结构体数组
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名:" << stdArray[i].name 
			<<"年龄:"<<stdArray[i].age
			<<"分数:"<<stdArray[i].score<<endl;
	}
	system("pause");
	return 0;
}

8.4结构体指针

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

  • 利用操作符 -> 可以通过结构体指针访问结构体属性
#include <iostream>
using namespace std;
#include<string>

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

int main()
{
	//1、创建结构体变量
	//struct可以省略;
	struct Student s = {"张三",18,100}; 
	
	//2、通过指针指向结构体变量
	//struct可以省略;
	struct Student * p = &s;  
	

	//3、通过指针访问结构体变量中的数据
	cout << "姓名:" << p->name 
		<< "年龄:" << p->age 
		<< "分数:" << p->score << endl;

	system("pause");
	return 0;
}

8.5结构体嵌套结构体

作用结构体中的成员可以是另一个结构体

例如:每个老师辅导一个学员。一个老师的结构体中,记录一个学生的结构体

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

//学生结构体定义
struct Student
{
	string name; 
	int age;     
	int score;   
}; 

//老师结构体定义
struct teacher
{
	int id;
	string name;
	int age;
	struct Student stu;
};

int main()
{
	//创建老师
	teacher t;
	t.id = 1000;
	t.name = "老王";
	t.age = 50;
	t.stu.name = "张三";
	t.stu.age = 20;
	t.stu.score = 60;
	
	cout << "老师姓名:" << t.name 
		<< "老师编号:" << t.id
		<< "老师年龄:" << t.age 
		<< "老师辅导的学生分数:" << t.stu.score << endl;

	system("pause");
	return 0;
}

8.6结构体做函数参数

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

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

//学生结构体定义
struct Student
{
	string name; 
	int age;     
	int score;   
}; 

//打印学生信息函数
//1、值传递
void printStudent1(Student s)
{
	s.name = "李四"; //主函数中数据不会修改
}

//2、地址传递
void printStudent2(Student *s)
{
	s->name = "李四"; //主函数中数据会修改
}

int main()
{
	 Student s;
	s.name = "张三";
	s.age = 20;
	s.score = 85;

	printStudent1(s);
	printStudent2(&s);

	system("pause");
	return 0;
}

总结如果不想修改主函数中的数据,用值传递,反之用地址传递。


8.7结构体中const便用场景

作用:用const来防止误操作

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

//const使用场景
struct Student
{
	string name; 
	int age;     
	int score;   
}; 

//将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来
void printStudents(const Student *s)
{
	// s->age = 150;  
	//加入const后,一旦有修改的操作会报错,可以防止误操作
	cout << "姓名:" << s->name 
		<< "年龄:" << s->age 
		<< "分数:" << s->score << endl;
}
int main()
{
	Student s = {"张三",15,70};
	
	//通过函数打印结构体变量信息
	printStudents(&s);
	

	system("pause");
	return 0;
}

8.8结构体案例

8.8.1案例1

案例描述

学校正在做毕设项目。每名老师带领5个学生,总共有3名老师,需求如下:

设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员;学生的成员有姓名、考试分数。创建数组存放3名老师,通过函数给每个老师及所带的学生赋值;最终打印出老师数据以及老师所带的学生数据。

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

struct Student
{
	string sName;
	int score; 
};
struct Teacher
{
	string tName;
	Student sArray[5];
};

void allocateSpace(struct Teacher tArray[], int len)
{
	string nameSeed = "ABCDE";
	//给老师赋值
	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() % 60 +40;  //0~59分 + 40 = 40~99分
			int random = rand() % 61 +40;  //0~60分 + 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;
			cout <<" 学生分数:" << tArray[i].sArray[j].score<<endl;
		}
	}
}

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

	//创建3名老师的数组
	struct Teacher tArray[3];  

	//通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(tArray) / sizeof(tArray[0]);
	allocateSpace(tArray,len);
	//打印所有老师及所带的学生信息
	printInfo(tArray,len);
	system("pause");
	return 0;
}


8.8.2案例2

案例描述

设计—个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。通过冒泡排序的算法,将数组中的英雄按年龄进行升序排序,最终打印排序后的结果。

五名英雄信息如下:

{"刘备",23,"男"},
{"关羽",22,"男"},
{"张飞",20,"男"},
{"赵云",21,"男"},
{"貂蝉",19,"女"},
#include<iostream>
using namespace std;
#include<string>

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

void bubbleSort(Hero hero[], int len)
{
	for (int i = 0; i < len-1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			if (hero[j].age > hero[j + 1].age)
			{
				Hero temp = hero[j];
				hero[j] = hero[j+1];
				hero[j+1] = temp;
			}
		}
	}
}

void printSort(Hero hero[],int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << hero[i].name << " "
			<< hero[i].age << " "
			<< hero[i].sex << endl;
	}
}

int main()
{
	Hero heroArray[5] =
	{
		{"刘备",23,"男"},
		{"关羽",22,"男"},
		{"张飞",20,"男"},
		{"赵云",21,"男"},
		{"貂蝉",19,"女"},
	};

	int len = sizeof(heroArray) / sizeof(heroArray[0]);
	bubbleSort(heroArray, len);
	printSort(heroArray, len);
	
	system("pause");
	return 0;
}


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: C++

“第一阶段C++基础入门(黑马程序员)——Day4” 的相关文章