指针与const,指针与数组
指针与const,指针与数组
什么是常量指针和指针常量
常量指针是指const来修饰定义一个指针,而指针常量则是定义一个const修饰的指针。
代码示例:
#include <iostream>
using namespace std;
int main(){
int a1=1,a2=2,b1=3,b2=4;
//常量指针
const int *pb=&b1;
cout<<"pb="<<pb<<" &b1="<<&b1<<" &pb="<<&pb<<" b1="<<b1<<endl;
//*pb=9;提示报错
pb=&b2;
cout<<"pb="<<pb<<" &b2="<<&b2<<" &pb="<<&pb<<" b2="<<b2<<endl;
b2=5;
cout<<"pb="<<pb<<" &b2="<<&b2<<" &pb="<<&pb<<" b2="<<b2<<endl<<endl;
//指针常量
int *const pa=&a1;
cout<<"pa="<<pa<<" &pa="<<&pa<<" &a1="<<&a1<<" a1="<<a1<<endl;
*pa=9;
//pa=&a2;
cout<<"pa="<<pa<<" &pa="<<&pa<<" &a1="<<&a1<<" a1="<<a1<<endl;
return 0;
}
运行结果为:
pb=0x7ffe9220d89c &b1=0x7ffe9220d89c &pb=0x7ffe9220d8a8 b1=3
pb=0x7ffe9220d8a0 &b2=0x7ffe9220d8a0 &pb=0x7ffe9220d8a8 b2=4
pb=0x7ffe9220d8a0 &b2=0x7ffe9220d8a0 &pb=0x7ffe9220d8a8 b2=5
pa=0x7ffe9220d898 &pa=0x7ffe9220d8b0 &a1=0x7ffe9220d898 a1=1
pa=0x7ffe9220d898 &pa=0x7ffe9220d8b0 &a1=0x7ffe9220d898 a1=9
常量指针是pb指向一个const int,指针指向一个常量对象,可以防止指针修改指向的值。在实例里可以看到可以防止通过指针修改b1的值。它可以直接修改指向的对象。pb指向的对象不是一个常量,是可以被修改的(可以通过将新地址赋值改变指向对象:pb=0x7ffe9220d89c被pb=&b2修改成pb=0x7ffe9220d8a0),而对于pb这个指向的是对象的值是常量,是不可以通过pb指针来修改指向值。
指针常量是定义一个const修饰的指针,它可以通过指针来修改pa来修改指向对象的值。但pa指向的对象是不可更改。
分析指针、数组、指针算数
分别定义double和short类型的两个大小为3的数组并复制,定义一个指针pw指向double类型的数组,一个指针ps指向short类型的数组。可知pw指针因为指向double类型的数据,大小为8字节,ps则为2字节。
(巩固一下数据类型,字节大小int为4字节,float为4字节,double为8字节,char为1字节,short为2字节,long为8字节)
代码示例:
#include <iostream>
using namespace std;
int main(){
double wages[3] = {1000.0, 2000.0, 3000.0};
short stacks[3] = {3, 2, 1};
double *pw=wages;
short *ps=&stacks[0];
cout << "pw="<< pw << " *pw=" << *pw << endl;
pw = pw + 1;
cout << "pw="<< pw << " *pw=" << *pw << endl;
cout <<"wages字节大小:"<< sizeof(wages)<<endl;
cout <<"wages[0]字节大小:"<< sizeof(wages[0])<<endl;
cout << "wages[0]="<<wages[0]<<" wages[1]="<<wages[1]<<endl;
cout << "*(wages+1)="<<*(wages+1)<<endl;
cout << "sizeod(*pw)="<< sizeof(*pw)<<endl;
cout <<endl;
cout << "ps=" << ps << " *ps=" <<*ps<<endl;
ps = ps + 1;
cout << "ps=" << ps << " *ps=" <<*ps<<endl;
cout <<"stacks字节大小:"<<sizeof(stacks)<<endl;
return 0;
}
运行结果为:
pw=0x7ffc39e93580 *pw=1000
pw=0x7ffc39e93588 *pw=2000
wages字节大小:24
wages[0]字节大小:8
wages[0]=1000 wages[1]=2000
*(wages+1)=2000
sizeod(*pw)=8
ps=0x7ffc39e9357a *ps=3
ps=0x7ffc39e9357c *ps=2
stacks字节大小:6
定义指针指向一个数组时,一般情况都是指向数组的第一个元素的地址。
wage[0],wage[1]的地址是紧接着的相隔8个字节,stacks是相隔的2字节,指针运算,当使用pw+1时,指针加1,它的值由于是指向double类型,所以它的值加8(可见第一、二行输出的pw的值作为印证)。short类型的指针加1,则其值加2。
归类可知:增加的值为其指向的数据类型所占字节数。
wages[1]和*(wages+1)的值是一样的,由于wages是指向wages[]第一个元素的指针地址,那么wages+1就是相当于pw+1,在进行解引,得到的就是wages[1]的值2000,意味着的是先找到第二个元素的地址再取值。
由此可知,在很多情况下,可以用相同的方式使用数组名和指针。但他们之间也是有区别的。
int a[]={1, 2, 3};
int *pa=a;
pa=pa+1;
a=a+1;//表达式必须是可修改的左值
因为 a 是一个数组名,它代表一个常量地址,不能被赋值。尝试这样做会导致编译错误。数组名a在定义后不能改变其指向的地址。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人