C++中的指针

1 指针是什么

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。 本质上, 指针和普通的变量没有什么区别, 只是它的值稍微特殊一点, 是一个地址, 通过这个地址我们就可以访问到实际的值。
指针即地址,指针即地址, 指针即地址, 记住这句话, 就能非常容易理解指针。

2 指针的定义及操作

2.1 一级指针

指针的一般定义为:指针类型 *指针变量名;
其中指针的类型是指指针所指向的地址中存放的值的类型, 因为指针本身是个地址值,数据类型是固定的; *是指针的标识符, 指针变量名是指针变量的名字。
例如:

int *pt1; //定义了一个int型的指针pt1, 它指向的地址中存放的值是int型
double *pt2; //定义了一个double型的指针pt2, 它指向的地址中存放的值是double型

上面定义的指针没有初始化, 一个没有初始化的指针用起来是比较危险的, 因为不知道指向了哪里。所以用指针之前一定要初始化。 可以初始化为NULL值, 编译器会特殊处理。
下面是一个初始化的例子, 其中&是取地址运算符。

int val=1; 
int *pt1 = &val;  //pt1指向val
int *pt2 = NULL

数组的名字就是地址, 所以可以把数组名赋值给一个指针。 那么指针就指向了数组的首元素地址。 但是字符串或者字符数组比较特殊,数组名不仅是地址, 而且也是字符串的值(实际上, 字符串或字符数组没有特殊之处, 名字也和普通数组名一样是个地址, 只是cout输出时做了特殊处理, 名字可以直接输出字符串的值)。

#include <iostream>
using namespace std;


int main()
{	
	int arr[3] ={1, 2, 3};
	char  chs[4]={'a','b','c', '\0'};  // "abc"
	int *pt = arr;
	char *pt_s = chs;
	cout<<"the arr is :"<<arr<<endl;
	cout<<"the pointer is :"<<pt<<endl;
	cout<<"the value of pointer is :"<<*pt<<endl;
	cout<<"the string is:"<<chs<<endl;
	cout<<"the pointer of string is:"<<pt_s<<endl;
	cout<<"the value of the string pointer is:"<<*pt_s<<endl;
	return 0;	
}

输出:

the arr is :0x72fdf0
the pointer is :0x72fdf0
the value of pointer is :1
the string is:abc
the pointer of string is:abc
the value of the string pointer is:a

2.2 二级指针

所谓二级指针就是指向指针的指针, 也就是指针中存放的是另一个指针的地址。 一个形象的比喻就是套娃。
在这里插入图片描述

只要理解了指针即地址这句话, 多级指针理解起来也没有难度。
二级指针定义时需要2个*
例如:

int **pt;  //定义了一个指向int型指针的指针

3 指针的操作

3.1 访问指针的值

访问指针的值是指针最常见的操作了。指针本身只是个地址, 我i们一般不关心这个地址本身, 我们关心的是这个地址位置上存放的实际值。
通过*可以访问指针的值。
例如:

#include <iostream>
using namespace std;


int main()
{	
	int val=1;
	int *pt1=&val;
	cout<<"the point is:"<<pt1<<endl;
	cout<<"the value of the point is:"<<*pt1<<endl;
	return 0;	
}

输出

the point is:0x72fe04
the value of the point is:1

可以看到, 如果直接输出指针本身, 它就是个地址, 这也印证了我一直强调的指针即地址这句话。 用*就可以访问指针所存放的实际值。

3.2 指针的数学运算

指针既然也是个值, 就支持基本的数学运算, 像++, --, +, -这些操作。
需要注意的是, 指针加1并不是地址值加1, 取决于指针的类型, 如int型指针, 指针加1实际上指针的值是加了4。 因为一个int型占4个字节。 要理解这一点,核心还是指针即地址这句话。 我们关心的是地址中存放的实际值, 而不是关心地址本身。 那么指针加1, 我们实际要想的是指向下一个值, 所以得加4。 如果指针只是加1的话, 实际上指向了一个int型值的中间一些bit位, 显然不是我们想要的。

例如:

#include <iostream>
using namespace std;


int main()
{	
	int val=1;
	double val2 = 2;
	int *pt1=&val;
	double *pt2=&val2;
	cout<<"the int point is:"<<pt1<<endl;
	cout<<"the int point +1 is:"<<pt1+1<<endl;
	cout<<"the int point + 2 is:"<<pt1+2<<endl;
	pt1++;
	cout<<"the int point ++ is:"<<pt1<<endl;
	cout<<"the double point is:"<<pt2<<endl;
	cout<<"the double point +1 is:"<<pt2+1<<endl;
	return 0;	
}

输出:

the int point is:0x72fdfc
the int point +1 is:0x72fe00
the int point + 2 is:0x72fe04
the int point ++ is:0x72fe00
the double point is:0x72fdf0
the double point +1 is:0x72fdf8

3.3 把指针作为参数传递给函数

C++函数可以接受指针作为参数, 只需要在定义函数时把形参声明为指针类型即可。

#include <iostream>
using namespace std;

void func1(int *pt)
{
	*pt = 1;
}

int main()
{
	int val=2;
	int *pt = &val;
	cout <<"the value before func1:"<<val<<endl;
	func1(&val);  //与func1(pt)是等价的, 因为指针实际上就是个地址
	cout <<"the value after func1:"<<val<<endl;
}

the value before func1:2
the value after func1:1

需要注意的是, 由于传递的是地址, 所以对形参值的改变是影响到实参值的。

3.4 把指针作为函数的返回值

C++可以把指针作为函数的返回值, 只需要在定义函数时声明返回值是指针类型即可。

#include <iostream>
using namespace std;

int * func1()
{
	static int val=1;
	return &val;
}

int main()
{
	cout <<"the value of the return is:"<<func1()<<endl;
	cout<<"the value is:"<<*func1()<<endl;
}

输出:

the value of the return is:0x4a7010
the value is:1

如结果所示,函数返回了一个指针。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值