C++学习之指针

指针的作用:存储内存地址,我们可以通过指针间接访问内存

内存的编号是从0开始的,一般用十六进制数字表示,我们可以利用指针变量来保存内存的地址

指针变量的定义和使用

指针的定义

语法:

数据类型 * 指针变量名 ;

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	int* p;			// 定义指针变量p,该变量只能存内存地址    
	//p = a;		// 报“不能将int类型的值,分配到“int *”类型的实体
	p = &a;			// &符号可以取出变量a的内存地址,然后赋值给指针变量p

	system("pause");
	return 0;
}

指针的使用

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	int* p;			// 定义指针变量p,该变量只能存内存地址	
	//p = a;		// 报“不能将int类型的值,分配到“int *”类型的实体
	p = &a;			// &符号可以取出变量a的内存地址,然后赋值给指针变量p
    
	system("pause");
	return 0;
}

例2:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	// 指针的定义
	int* p;			// 定义指针变量p,该变量只能存内存地址
	//p = a;		// 报“不能将int类型的值,分配到“int *”类型的实体
	p = &a;			// &符号可以取出变量a的内存地址,然后赋值给指针变量p

	// 指针的使用
	cout << "指针变量p的值是:" << p << endl;		// 打印指针变量p的值,即变量a的内存地址
	cout << "变量a的内存地址是:" << &a << endl;
	cout << "获取指针p指向的值:" << *p << endl;	// *p进行解指针操作,获取指针变量直线地址的值

	system("pause");
	return 0;
}

指针所占的内存空间

指针存储的是内存地址,所占内存空间为:32位操作系统4个字节(不区分数据类型都一样),64位系统站8个字节(不区分数据类型都一样)

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	// 指针的定义
	int* p;			// 定义指针变量p,该变量只能存内存地址
	cout << "指针类型所占内存空间为:" << sizeof(int *) << endl;		// 64位为8,32位为4
	cout << "指针类型所占内存空间为:" << sizeof(p) << endl;

	system("pause");
	return 0;
}

空指针和野指针

空指针

空指针是指针变量指向的内存编号为0的空间,一般用于初始化指针变量,必须注意的是空指针指向的内存是不可访问的

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	// 指针的定义
	int* p = NULL;
	//cout << *p << endl;		// 获取空指针的值,报“空指针异常错误”
	cout << p << endl;			// 打印指针p的内存地址:结果全是0
    
	system("pause");
	return 0;
}

运行例1代码出现的空指针异常截图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FPcK4aRu-1594202837509)(C:\Users\PC\AppData\Roaming\Typora\typora-user-images\image-20200708155923344.png)]

野指针

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

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	// 指针的定义
	int* p = (int *)0x1100;			// 该内存是随便写的,语法和编译都没问题
	cout << *p << endl;	

	system("pause");
	return 0;
}

例1运行结果报错截图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwuB4mlJ-1594202837514)(C:\Users\PC\AppData\Roaming\Typora\typora-user-images\image-20200708161128031.png)]

const修饰指针

const修饰指针有三种情况:

  1. const修饰指针 常量指针
  2. const修饰常量 指针常量
  3. const既修饰指针,又修饰常量

const修饰指针

常量指针:指针变量的指向可以修改,但是指针变量指向的值不能修改==

语法:

const 数据类型 * 指针变量名; // 常量指针

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	int b = 20;
	const int * p = &a;		// const定义常量指针
	cout << p << endl;
	//*p = 30;				// 修改常量指针指向地址的值,报错“表达式必须是可修改的左值”
	p = &b;					// 修改常量指针指向的地址
	cout << p << endl;
	

	system("pause");
	return 0;
}

const修饰常量

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

语法:

数据类型 * const 指针变量名 ; // 指针常量

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	int b = 20;
	int * const p = &a;		// const定义指针常量
	cout << *p << endl;
	*p = 30;
	//p = &b;				// 修改指针常量指向地址的值,报错“表达式必须是可修改的左值”
	cout << *p << endl;
	

	system("pause");
	return 0;
}

const既修饰了指针也修饰了常量

指针指向的和指针指向的值都不能更改

语法:

const 数据类型 * const 指针变量名 ;

例1:

#include <iostream>
using namespace std;

int main() {
	int a = 10;
	int b = 20;
	const int * const p = &a;		// const定义指针常量
	cout << *p << endl;
	// *p = 30;				// 修改常量指针指向地址的值,报错“表达式必须是可修改的左值”
	// p = &b;				// 修改指针常量指向地址的值,报错“表达式必须是可修改的左值”
	cout << *p << endl;
	

	system("pause");
	return 0;
}

指针和数组

利用指针访问数组中的元素。

例1:

#include <iostream>
using namespace std;

int main() {
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int* p = arr;		// 将数组arr的地址赋值给指针变量p
	cout << "正常使用for循环取出所有的值:" << endl;
	for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++)
	{
		cout << arr[i] << endl;
	}
	cout << "利用指针取出所有的值:" << endl;
	for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++)		// sizeof(arr) / sizeof(arr[0])计算出数组长度
	{
		cout << *p << endl;		// 打印值
		p++;					// 指针自增,每次增加四个字节
	}

	system("pause");
	return 0;
}

指针和函数

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

例1:

在前面我们创建过一个函数,交换两个变量的值,在函数内部形参进行了交换,而在函数外部的实参没有任何改变,利用指针作为形参,可以改变实参的值

#include <iostream>
using namespace std;


void swap01(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;
}

void swap02(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;
}

int main() {
	int a = 100;
	int b = 200;
	cout << "调用前:" << endl;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	cout << "值传递:" << endl;
	swap01(a, b);
	cout << "——————————华丽的分割线——————————" << endl;
	cout << "指针地址传递:" << endl;
	swap02(&a, &b);
	cout << "调用后:" << endl;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;

	system("pause");
	return 0;
}

指针配合函数和数组综合案例

例1:

#include <iostream>
using namespace std;

void Bubblesort(int* arr, int 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 PrintArr(int* arr, int len)		// 定义数组打印函数
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}

int main() {
	// 定义数组
	int arr[] = { 4,2,5,8,1,3,6,9,7 };
	int len = sizeof(arr) / sizeof(arr[0]);		// 获取数组的长度
	cout << "冒泡排序前:" << endl;
	PrintArr(arr, len);							// 打印排序前的数组
	Bubblesort(arr, len);						// 进行冒泡排序
	cout << "冒泡排序后:" << endl;
	PrintArr(arr, len);							// 打印排序前的数组

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/z929162742/article/details/107211979