c++指向指针的指针 **p,指向指针数组的指针数组

本文详细解析了一阶指针与二阶指针的概念及应用,通过实例演示了整型指针、字符型指针以及字符串指针的不同表示方式,揭示了它们在内存中的存储原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

** p——指向指针的指针

指针是一种特殊的数据类型,也是占内存的能寻址的,这跟电脑的操作系统的位数有关,我是64位的。

int 类型

以整型指针数组为例,先定义一组指向整型的指针数组*p,再定义一组指向整形指针的指针数组**p:

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
int main()
{
    int val[5]={1,2,3,5};
    int *p[5];
    int **pp[5];
    for(int i=0;i<5;i++)
    {
        p[i]=&val[i];//一阶指针指向数组的各个元素
        pp[i]=&p[i];//二阶指针指向各个一阶指针
        cout<<p[i]<<setw(20)<<pp[i]<<setw(7)<<*p[i]<<setw(7)<<**pp[i]<<endl;
    }
    
    return 0;
}

运行结果为

0x7ffe6cfddfe0      0x7ffe6cfde000      1      1                                                                        
0x7ffe6cfddfe4      0x7ffe6cfde008      2      2                                                                        
0x7ffe6cfddfe8      0x7ffe6cfde010      3      3                                                                        
0x7ffe6cfddfec      0x7ffe6cfde018      5      5                                                                        
0x7ffe6cfddff0      0x7ffe6cfde020      0      0

可以看出,p[i]输出的是数组元素的存储地址,pp[i]输出的是指针元素的存储地址,发现一个整型数据需要4个字节的存储空间,而一个指针需要8个字节的存储空间;同时,可以知道*p[i]和**pp[i]最终指向一个地址,他们的值是一样的。二阶指针沿着一阶指针找到val[]。

字符型指针的指针

字符数组的每一个元素都是一个字符,占一个字节
pp[i]输出的是一阶指针的地址,而**pp[i]输出的和*p[i]输出的是一样的,都是所指向元素的字符的值。
对于字符数组,和整形数组在一阶指针上有所区别,如下:

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;
int main()
{
    char val[5]={'1','2','3','5'};
    char *p[5];
    char **pp[5];
    cout<<val<<endl;
    cout<<&val<<endl;
    for(int i=0;i<5;i++)
    {
        p[i]=&val[i];//一阶指针指向数组的各个元素
        pp[i]=&p[i];//二阶指针指向各个一阶指针
        cout<<setw(7)<<p[i];//输出的p[i]与整型数组有所不同,不再是地址
        cout<<setw(20)<<pp[i];//输出一阶指针的存储地址
        cout<<setw(7)<<*p[i];
        cout<<setw(7)<<**pp[i];
        cout<<setw(20)<<static_cast<void *>(p[i])<<endl;//输出每一个元素的存储地址
        
    }
    return 0;
}

运行结果如下

1235                                                                                                                    
0x7ffd7b4acac3                                                                                                          
   1235      0x7ffd7b4aca60      1      1      0x7ffd7b4acac3                                                           
    235      0x7ffd7b4aca68      2      2      0x7ffd7b4acac4                                                           
     35      0x7ffd7b4aca70      3      3      0x7ffd7b4acac5  
       5      0x7ffd7b4aca78      5      5      0x7ffd7b4acac6                                                           
                0x7ffd7b4aca80                     0x7ffd7b4acac7 

可以看出,cout<<val,直接输出字符数组的内容;
cout<<&val,输出的是字符串的首地址,也就是数组中第一个元素,第一个字符的存储地址;
cout<<p[i],输出的是所指地址的元素及其后面的元素,直到读到\0的时候停止读取;
cout<<pp[i],输出的是一阶指针的存储地址,每个指针占八个字节;
cout<<*p[i]和**pp[i],输出的都是所指地址的那个元素;
cout<<static_cast<void *>(p[i]),可以输出每一个元素的存储地址。

指向字符串指针的指针

和指向字符的指针用法是一样的,不同的是,一个字符串包含多个字符,占多个字节,但是
cout<<*p[i]和**pp[i]输出的都是所指地址的字符串中第一个字符的值。
cout<<p[i]会输出每一个字符串的值
cout<<static_cast<void *>(p[i]),可以输出每一个字符串的存储首地址。

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
    char *pc[5]={"happy","wife","happy","life","haha"};
    char **pcc[5];
    for(int i=0;i<5;i++)
    {
        pcc[i]=&pc[i];
        cout<<setw(7)<<pc[i];//输出的是每一个字符串的值
        cout<<setw(20)<<pcc[i];//输出一阶指针的存储地址
        cout<<setw(7)<<*pc[i];
        cout<<setw(7)<<**pcc[i];
        cout<<setw(20)<<static_cast<void *>(pc[i])<<endl;//输出每一个元素的存储地址
    }
    return 0;
}

运行结果如下

happy      0x7fff567d6170      h      h            0x400bf7                                                           
   wife      0x7fff567d6178      w      w            0x400bfd                                                           
  happy      0x7fff567d6180      h      h            0x400bf7                                                           
   life      0x7fff567d6188      l      l            0x400c02                                                           
   haha      0x7fff567d6190      h      h            0x400c07 

自己在学的过程中终于弄懂了指针在各种数据类型中的各种表示所代表的数据是什么,以上内容如有错误,欢迎评论指正哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值