指针与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在定义后不能改变其指向的地址。

posted @   无情马里奥  阅读(17)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示