C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针

1. 什么是指针变量?

指针变量是专门有一个变量来存放指针。

int main(int argc, char *argv[])
{
    
    
    int a = 10;
    int *p = &a;    //通过取地址符号 & 把 a 变量的地址传给指针变量 p
    std::cout << "p is " << p << std::endl;     // p is 0x7fffe740301c
    std::cout << "&a is " << &a << std::endl;   //&a is 0x7fffe740301c
    std::cout << "*p=" << *p << std::endl;      // *p=10
    return 0;
}

通过符号 *p 获取指针变量 p 指向的地址的存放的值。我们可以理解为通过变量 p 我们拿到抽屉的钥匙(地址)打开抽屉取出数据。

2. 数组和指针

int main(int argc, char *argv[])
{
    
    
    int a[3] = {
    
    1,2,3};
    int *p = a;
    std::cout << "p is " << p << std::endl;    
    std::cout << "&a is " << &a << std::endl;   
    std::cout << "a is " << a << std::endl;    
    std::cout << "&a[0] is " << &a[0] << std::endl;     
    std::cout << "*p=" << *p << std::endl;      
    std::cout << "*(p+1)=" << *(p+1) << std::endl;     
    std::cout << "a[1]=" << a[1] << std::endl;  
    return 0;
}

执行输出结果:

p is 0x7fff7b96be40
&a is 0x7fff7b96be40
a is 0x7fff7b96be40
&a[0] is 0x7fff7b96be40
*p=1
*(p+1)=2
a[1]=2

a 的值就是数组 a 第一个元素的地址,与 &a[0]&a 等价。

而 p+1 表示的是数组 a 的第二个元素的地址,以此类推。

获取数组的第二个元素可以是 a[1],也可以是 *(p+1)。

3. 指针数组

表示数组内存放的是指针类型的数据。

定义方式

int *p[]

示例:

int main(int argc, char *argv[])
{
    
    
    int a[3] = {
    
    1,2,3};
    int *p[3] = {
    
    a,a+1,a+2};
    std::cout << "a= " << a << std::endl;     
    std::cout << "a+1= " << a+1 << std::endl;   
    std::cout << "a+2= " << a+2 << std::endl;  
   
    std::cout << "*p=" << *p << std::endl;      
    std::cout << "*(p+1)=" << *(p+1) << std::endl;   
    std::cout << "p[1]=" << p[1] << std::endl;    
    std::cout << "**p=" << **p<< std::endl;  
    std::cout << "**(p+1)=" << **(p+1) << std::endl;  
    return 0;
}

输出:

a= 0x7ffd747a1b70
a+1= 0x7ffd747a1b74
a+2= 0x7ffd747a1b78
*p=0x7ffd747a1b70
*(p+1)=0x7ffd747a1b74
p[1]=0x7ffd747a1b74
**p=1
**(p+1)=2

aa+1a+2 分别表示数组 a 第一个、第二个、第三个元素的地址。

p+1 指的是指针数组 p 的第二个元素的地址,而 *(p+1)(等价于 p[1])指的就是第二个元素地址存放的值,也就是 a+1

a+1*(p+1) 值是相等的。

4. 数组指针

表示指针是数组类型的,就像 int 类型指针,char 类型指针一样。
定义方式:

int (*p)[n]

() 优先级高,首先说明 p 是一个指针,指向一个整型的一维数组,这个一维数组的长度是 n,也可以说是 p 的步长。

示例:

int main(int argc, char *argv[])
{
    
    
    int a[3] = {
    
    1,2,3};
    int (*p)[3] = &a;   //定义一个指向长度为 3 的 int 数组的指针
    std::cout << "a  = " << a << std::endl;     
    std::cout << "a+1= " << a+1 << std::endl;   
    std::cout << "p+1= " << p+1 << std::endl; 
    std::cout << "a+2= " << a+2 << std::endl;  
   
    std::cout << "&a= " << &a << std::endl; 
    std::cout << " p= " << p << std::endl;  
    std::cout << "*p= " << *p << std::endl;  
    return 0;   
}

输出:

a  = 0x7ffd63226b30
a+1= 0x7ffd63226b34
p+1= 0x7ffd63226b3c
a+2= 0x7ffd63226b38
&a= 0x7ffd63226b30
 p= 0x7ffd63226b30
*p= 0x7ffd63226b30

&aap 值是相等的,都是指数组 a 的第一个元素的地址。

仔细看两个值,可以发现 p+1(0x7ffd63226b3c)是 p(0x7ffd63226b30)再加 12,也就是数组 a 所有元素加起来的长度(长度 3*int 类型的 4 个字节),所以数组指针 p 再加 1,这里的 1 指的就是数组 a 所有元素加起来的长度,而不是数组元素的长度。

p*p 两个值是一样的。*p 的值是数组 a 第一个元素的地址,而 p 虽然也是数组 a 第一个元素的地址,但是 p 指的是整个数组的地址,只是用了数组 a 的第一个元素地址来替代,而 *p 是指这个数组的地址对应的值,就是数组本身,
也就是 a,而 a 的值也就是数组 a 第一个元素的地址,所以 *p 等于 a

int a[3] = {
    
    1,2,3};
int (*p)[3] = &a;
cout<<**p<<endl;
cout<<*(*p+1)<<endl;
cout<<(*p)[1]<<endl;

输出:

1
2
2

*p 表示数组第一个元素地址,**p 表示数组第一个元素地址存放的值也就是 1;p+1 表示数组第二元素地址,(*p+1) 表示数组第二个元素地址存放的值也就是 2。(*p)[1] 与 *(*p+1) 值一样,都是表示数组第二个元素值,即 a[1]。

如果改成下面:

int main(int argc, char *argv[])
{
    
    
    int a[3] = {
    
    1,2,3};
    int (*p)[3] = a;   
    return 0;
}

会编译报错:

cannot convert ‘int*’ to ‘int (*)[3]in initialization

因为 a 这里是一维数组,a 代表的是数组 a 首个元素地址,而不是整个数组地址。

假设 a 数组是二维数组,如下定义:

int main(int argc, char *argv[])
{
    
    
    int a[2][3] = {
    
    {
    
    1,2,3},{
    
    4,5,6}};
    int (*p)[3] = &a; 
    return 0;
}

会编译报错:

cannot convert ‘int (*)[2][3]’ to ‘int (*)[3]in initialization

因为这里 a 是二维数组,而 &a 表示整个二维数组的地址,是包含 2*3=6 个元素的数组。那要怎么改才可以呢?

可以改成:

int (*p)[3] = a; // 这里 a 理解为二维数组 a 第一维 a[0][]数组的地址。

或者改为:

int (*p)[2][3] = &a; // 表示2行3列的二维数组地址

完整代码:

int main(int argc, char *argv[])
{
    
    
    int a[2][3] = {
    
    {
    
    1,2,3},{
    
    4,5,6}};
    int (*p)[3] = a;   
    std::cout << "a= " << a << std::endl;     
    std::cout << "a+1= " << a+1 << std::endl;   
    std::cout << "a+2= " << a+2 << std::endl;  
   
    std::cout << "&a=" << &a << std::endl; 
    std::cout << "p=" << p << std::endl;      
    std::cout << "*(p+1)=" << *(p+1) << std::endl;   
    std::cout << "p[1]=" << p[1] << std::endl;    
    std::cout << "**p=" << **p<< std::endl;  
    std::cout << "**(p+1)=" << **(p+1) << std::endl;     
    return 0;
}

输出结果:

a= 0x7ffe52d671f0
a+1= 0x7ffe52d671fc
a+2= 0x7ffe52d67208
&a=0x7ffe52d671f0
p=0x7ffe52d671f0
*(p+1)=0x7ffe52d671fc
p[1]=0x7ffe52d671fc
**p=1
**(p+1)=4

猜你喜欢

转载自blog.csdn.net/wohu1104/article/details/112503395