C++指针

指针

指针的基本概念

1、指针的作用:可以通过指针间接访问内存 (指针就是内存地址

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

指针变量定义的语法

#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;

	return 0;
}

output:

a的地址为:00EFFA1C
指针p为:00EFFA1C
a = 1000
*p = 1000
请按任意键继续. . .

指针所占的内存空间

指针也是种数据类型

指针在32位操作系统下:占4个字节空间

指针在64位操作系统下:占8个字节空间

这里都是用32位操作系统演示

int b = 20;
	int* p2 = &b;
	cout << sizeof(p2) << endl;  // cout << sizeof(int *) << endl;  // 这里效果等价
	cout << sizeof(int*) << endl;

output

4
4

空指针和野指针

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

用途:初始化指针变量

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

#include <iostream>
using namespace std;



int main() {
	//空指针
	// 1、空指针用于给指针变量进行初始化
	int* p = NULL;

	// 2、空指针是不可以进行访问
	// 0~255之间的内存编号是系统占用的,因此不可以访问
	*p = 100;
	return 0;
}

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

#include <iostream>
using namespace std;



int main() {
	// 野指针
	// 在程序中,尽量避免出现野指针
	int* p = (int *)0x1100;

	cout << *p << endl;

	return 0;
}

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

const修饰指针

小技巧 * 读指针 ,const 读 常量
记忆方法:指针常量int * const a; * 是指针,const是常量;同理 const int * a:这就是常量指针;那么怎么记忆这两的不同呢,指针常量和常量指针,都是四个字两个词,那个词在前哪个词就不可以修改,例如指针常量,你指针不是在前面吗,那指针就不可以修改,思考一下指针本质能改什么?那就是地址咯即指针的指向,所以指针常量就是指针指向不变,"常量"值可变。常量指针亦然。

#include <iostream>
using namespace std;



int main15() {
	// 1、const修饰指针   常量指针
	int a = 10;
	int b = 20;

	const int* p = &a;
	// 指针指向的值不可以改,指针的指向可以改
	// *p = 20;  错误
	p = &a;  // 正确


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


	// 3、const修饰常量和指针
	// 指针的指向,和指针指向的值 都不可以改
	const int* const p3 = &a;
	// *p3 = 100;  // 错误
	// p3 = &b;	// 错误

	return 0;
}

1、常量指针

2、指针常量

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

指针和数组

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

#include <iostream>

using namespace std;



int main() {
	// 指针和数组
	// 利用指针访问数组中的元素

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

	cout << "第一个元素为:" << arr[0] << endl;

	int* p = arr;  // arr就是数组首地址

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

	p++; // 让指针向右偏移4个字节

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

	cout << "利用指针遍历数组" << endl;

	int* p2 = arr;   // 新定义指针p2

	for (int i = 0; i < 10; i++)
	{
		cout << *p2 << endl;
		p2++;   // 指针偏移
	}



	return 0;
}

output:

第一个元素为:1
利用指针访问第一个元素:1
利用指针访问第二个元素:2
利用指针遍历数组
1
2
3
4
5
6
7
8
9
10
请按任意键继续. . .

指针和函数

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

#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() {
	// 指针和函数
	// 1、值传递
	/*int a = 10;
	int b = 20;
	swap01(a, b);*/  // 值传递不会改变实参

	// 2、地址传递
	//如果是地址传递,可以修饰实参
	int a = 10;
	int b = 20;
	swap02(&a, &b);   // 地址传递会改变实参
	cout << a << endl;
	cout << b << endl;


	return 0;
}

总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递

指针、数组、函数

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

例如数组: 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] << " ";
	}
}

int main() {
	// 1、先创建数组
	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };

	// 数组长度
	int len = sizeof(arr) / sizeof(arr[0]);

	// 2、创建函数,实现冒泡排序
	bubbleSort(arr,len);

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

	return 0;
}

result:

1 2 3 4 5 6 7 8 9 10 请按任意键继续. . .
posted @ 2023-04-09 23:49  __username  阅读(85)  评论(0编辑  收藏  举报

本文作者:DIVMonster

本文链接:https://www.cnblogs.com/guangzan/p/12886111.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。