C++指针

地址的概念

字节是计算机管理内存的最小单位,每一个字节在内存中都有一个编号,这个编号以数字的形式保存,叫做地址。

在程序中定义所有的变量,在内存都需要分配相应的存储单元,不同类型所需要的存储空间大小是不一样的,比如int型的变量,需要占四个连续的存储单元,也就是需要占四个字节。系统给变量内存空间的其实单元地址称为该变量的地址。

指针变量

在程序中,存放地址的变量也叫做指针变量,用于存放其他变量的地址。

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

int*p;//定义了一个int型的变量p1,用来保存int类型变量的地址

可以使用取址运算符(&)来获取变量的地址

int a=1;
cout << &a << " ";

 指针的解引用

使用指针运算符“*”来获取地址中的内容

int a=5;
int*p=&a;
cout<<*p<<endl;

 输出结果就是5

字符指针

字符指针可以使用指针或者&输出字符串,如果需要获取字符指针的具体地址,需要使用int*强转,如果不使用强转,会出现乱码。

char ch = 'a';
char* p = &ch;
cout << p << endl;

正确写法应该是

char ch = 'a';
char* p = &ch;
cout << (int*)p << endl;

指针的运算

由于指针存放变量的是地址,因此指针运算就是地址的运算,指针运算主要有算数运算和关系运算。

算数运算

指针可以和整数进行加减法运算,也可以进行自增++和自减--运算,进行运算的结果和该指针指向的数据类型有关,例如指针p是int类型的指针变量,则p+1就是向后移动了四个字节。

int* p, a = 5;
p = &a;
cout << p << endl;
cout << p + 1 << endl;

关系运算

指向同一类型的指针可以进行关系运算,如果两个类型的指针是相等的,则这两个指针指向的是同一个地址。

	int arr[10] = { 10,20,30,40,50,60,70,80,90,100 };
	int* p1, * p2;
	// 将第2个元素的地址赋值给p1
	p1 = &arr[1];
	// 将第4个元素的地址赋值给p2
	p2 = &arr[3];

	cout << p1 << " " << p2 << endl;

	cout << "p1 > p2 ? " << (p1 > p2) << endl; // 0
	cout << "p1 < p2 ? " << (p1 < p2) << endl; // 1
	cout << "p1 == p2 ? " << (p1 == p2) << endl; // 0
	cout << "p1 != p2 ? " << (p1 != p2) << endl; // 1

指针可以用NULL(0)来比较,如果p==0成立,我们把p叫做空指针。

	int* p3 = NULL;
	if (p3 == NULL)
	{
		cout << p3 << endl; // 输出的结果是00000000
		cout << "p3是空指针" << endl;
	}
	else
	{
		cout << *p3 << endl;
	}
	return 0;
}

指针和数组

数组在内存是连续存放的,所以数组名就是数组的第一个元素的地址,所以数组不需要使用取值符就可以将地址赋值给指针变量来使用。

int arr[5] = { 10,20,30,40,50 };
cout << arr << endl;
cout << *arr;

*p++运算符可以输出数组的第二个元素

int arr[5] = { 10,20,30,40,50 };
int* p = arr;
*p++;
cout << *p << endl;

可以利用指针变量来遍历输出数组中的所有元素

int* p = arr;
for (int i = 0; i < 5; i++)
{
	cout << *p << " ";
	p++;
	//cout << *(p + i) << " ";
	// p和arr实际上是一样的,所以arr[i]可以 p[i]也可以
	//cout << p[i] << " ";
}

指针数组

数组元素是指针变量的数组叫做指针数组

定义方式:类型名*数组名[数组长度]

int arr1[2]={10,20};
int*p=arr1;
int n=10;
p1[0]=&n;
cout<<*p1[0]<<endl;

也可以使用指针数组处理二维数组

int arr[2][3]={1,2,3,4,5,6};
int*p[2]
p2[0]=arr[0];
p2[1]=arr[1];

例如: 遍历一个二维数组

int arr[2][3] = { 
	{10,20,30},
	{40,50,60}
};
int* p2[2];
for (int i = 0; i < 2; i++)
{
	for (int j = 0; j < 3; j++)
	{
		//p2[i]相当于获取二维数组中的每一行一维数组的首地址 p2[i][j]就是获取每一行的元素
		//cout << p[i][j] << " ";

		// p2[i]相当于获取的是二维数组的每一行的首地址,p[i]+j就是每一行的首地址来进行指针运算
		// *(p2[i] + j) 是对指针运算完的结果进行解引用的操作,才能获取到元素值
		//cout << *(p2[i] + j) << endl;
	}
}

多级指针

如果一个指针变量保存的是另外一个指针变量的地址,我们就称之为指向指针的指针,也叫做多级指针。

语法:三级指针:数据类型 ***指针变量名;

           二级指针:数据类型 **指针变量名;

	int a, * p1, ** p2;
	a = 10;
	p1 = &a;
	p2 = &p1;
	cout << a << endl << *p1 << endl << **p2 << endl;

得到的结果是三个10。

分别对其取地址:

int a, * p1, **p2;
a = 10;
p1 = &a;
p2 = &p1;
cout << p1 << endl << *p2 << endl << &a << endl;

利用指针变量来处理二维数组的地址问题

例如:利用指针变量来遍历一个二维数组:

使用一层for循环就可以解决

#include<iostream>
using namespace std;
int main()
{
	int arr[3][4] =
	{
		{10,20,30,40},
		{20,30,40,50},
		{30,40,50,60}
	};
	for (int i = 0; i < 12; i++)
	{
		cout << *(*(arr)+i) << endl;//*arr是取数组第一行首地址,*(*arr+i)对每个元素的地址解引用
	}

也可以使用双重for循环来处理这个问题

#include<iostream>
using namespace std;
int main()
{
	int arr[3][4] =
	{
		{10,20,30,40},
		{20,30,40,50},
		{30,40,50,60}
	};
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			//cout << *(arr[i] + j);这两种方法都可以实现对二维数组的遍历
			cout << *(*(arr + i) + j);
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值