C++ 高维指针数组 与 高维数组指针(二)

【摘要】

本文首先给出高维指针数组 与 高维数组指针的代码实现,然后,通过取址操作与移址操作说明,移位、移行、移数组的操作方式。

【特】

高维数组指针存放的是数组首个元素的地址而不是首元素地址本身,这一点跟一维数组指针和一维数组以及高高数组要区别开来。

【正文】

#include<iostream>

#include<stdio.h>
using namespace std;
int main()
{
int arr[2][4] = {{1,3,5,7},{2,4,6,8}};
// 声明多维数组
// (1) int arr = {{1,3,5,7},{2,4,6,8}};
// (2) int arr[][] = {{1,3,5,7},{2,4,6,8}};
// 两种方式都是错的,为什么 !!!
cout<<"********************************************************"<<endl;
cout<<"现在声明一个 高维数组 arr "<<endl;
cout<<"int arr[2][4] = {{1,3,5,7},{2,4,6,8}};"<<endl;
cout<<"arr is :"<<arr<<endl;
cout<<"arr addr is :"<<&arr<<endl;
cout<<"*arr is :"<<*arr<<endl;
cout<<"arr[0] is :"<<arr[0]<<endl;
cout<<"arr[0] addr is :"<<&arr[0]<<endl;
cout<<"arr[0][0] addr is :"<<&arr[0][0]<<endl;
cout<<"arr[0][0] is :"<<arr[0][0]<<endl;
cout<<"*arr[0] is :"<<*arr[0]<<endl;
cout<<"**arr is :"<<**arr<<endl;
cout<<"********************************************************"<<endl;
cout<<"现在对数组地址进行移位操作"<<endl;
cout<<"********************************************************"<<endl;
cout<<"arr+1 is :"<<arr+1<<endl;
cout<<"arr addr +1 is :"<<&arr+1<<endl;
cout<<"*arr +1 is :"<<*arr+1<<endl;
cout<<"arr[0]+1 is :"<<arr[0]+1<<endl;
cout<<"arr[0] addr +1 is :"<<&arr[0]+1<<endl;
cout<<"arr[0][0] addr +1 is :"<<&arr[0][0]+1<<endl;
cout<<"********************************************************"<<endl;
cout<<"现在对数组地址进行变态操作操作"<<endl;
cout<<"********************************************************"<<endl;
cout<<"&*arr[0] is :"<<&*arr[0]<<endl;
cout<<"*&arr[0] is :"<<*&arr[0]<<endl;
cout<<"&*arr[0]+1 is :"<<&*arr[0]+1<<endl;
cout<<"*&arr[0]+1 is :"<<*&arr[0]+1<<endl;
//cout<<"&(*arr[0]+1) is :"<<&(*arr[0]+1)<<endl;
//cout<<"&((*arr[0])+1) is :"<<&((*arr[0])+1)<<endl;
cout<<"(*arr[0]+1) is :"<<(*arr[0]+1)<<endl;
cout<<"&(*(arr[0]+1)) is :"<<&(*(arr[0]+1))<<endl;
cout<<"*(&arr[0]+1) is :"<<*((&arr[0])+1)<<endl;
cout<<"********************************************************"<<endl;
cout<<"现在声明一个指针 P1 指向 数组 arr "<<endl;
cout<<"int *p1 = arr;"<<endl;
cout<<"编译器给出错误提示:"<<endl;
cout<<"error C2440: 'initializing' : cannot convert from 'int [2][4]' to 'int *' "<<endl;
cout<<"********************************************************"<<endl;
cout<<"现在声明一个指向指针的指针 P2 指向 数组 arr "<<endl;
cout<<"int **p2 =arr;"<<endl;
cout<<"编译器给出错误提示:"<<endl;
cout<<"error C2440: 'initializing' : cannot convert from 'int [2][4]' to 'int **' "<<endl;
cout<<"********************************************************"<<endl;\
cout<<"现在声明一个指向数组的指针 P3 "<<endl;
cout<<"int (*p3)[4] = arr;"<<endl;
int (*p3)[4] = arr;
cout<<"p3 is :"<<p3<<endl;
cout<<"p3 addr is :"<<&p3<<endl;
cout<<"*p3 is :"<<*p3<<endl;
cout<<"p3[0] is :"<<p3[0]<<endl;
cout<<"p3[0] addr is :"<<&p3[0]<<endl;
cout<<"p3[0][0] addr is :"<<&p3[0][0]<<endl;
cout<<"p3[0][0] is :"<<p3[0][0]<<endl;
cout<<"*p3[0] is :"<<*p3[0]<<endl;
cout<<"**p3 is :"<<**p3<<endl;
cout<<"p3[1][0] is :"<<p3[1][0]<<endl;
cout<<"**(p3+1) is :"<<**(p3+1)<<endl;
cout<<"*(p3+1)[1] is :"<<*(p3+1)[1]<<endl;
cout<<"(*(p3+1))[1] is :"<<(*(p3+1))[1]<<endl;
cout<<"*(*(p3+1)+1) is :"<<*(*(p3+1)+1)<<endl;
cout<<"********************************************************"<<endl;
cout<<"现在对数组地址进行移位操作"<<endl;
cout<<"********************************************************"<<endl;
cout<<"p3+1 is :"<<p3+1<<endl;
cout<<"p3 addr +1 is :"<<&p3+1<<endl;
cout<<"*p3 +1 is :"<<*p3+1<<endl;
cout<<"p3[0]+1 is :"<<p3[0]+1<<endl;
cout<<"p3[0] addr +1 is :"<<&p3[0]+1<<endl;
cout<<"p3[0][0] addr +1 is :"<<&p3[0][0]+1<<endl;
return 0;
/*
// 理解 !!!
int arr1[3]; 
    int arr2[3]; 
    int arr3[3]; 
    int * ptr; 
    // ptr1是一个指向 int [3] 的指针,即ptr的类型和&arr1的类型是一样的,注意:arr1指向的内存区域定长 
    int ptr1[3][3]={{1,2,3},{1,2,3},{1,2,3}}; 
    // ptr2是一个指向 int * 的指针,即ptr2的类型和&ptr是一样的,注意:ptr指向的内存区域不定长 
    int * ptr2[3]={arr1,arr2,arr3}; 
    // ptr3是一个指向 int [3] 的指针,即ptr3的类型和&arr1的类型是一样的,注意:arr1指向的内存区域定长 
    int(* ptr3)[3]=&arr1; 
    ptr3=ptr1; // 没错,他们的类型相同 
// ptr3=ptr2;//error 无法从“int *[3]”转换为“int (*)[3] 
// ptr4是一个指向 int * 的指针,即ptr4的类型和&ptr是一样的,注意:ptr指向的内存区域不定长 
    int ** ptr4; 
    //ptr4=&arr1; //error 无法从“int (*)[3]”转换为“int ** 
    ptr4=ptr2; // 没错,他们的类型相同 
//ptr4=ptr3; // error 无法从“int (*)[3]”转换为“int ** 
    return 0;
*/
}


代码输出如下 :


********************************************************

现在声明一个 高维数组 arr

int arr[2][4] = {{1,3,5,7},{2,4,6,8}};

arr is :0018FF28

arr addr is :0018FF28

*arr is :0018FF28

arr[0] is :0018FF28

arr[0] addr is :0018FF28

arr[0][0] addr is :0018FF28

arr[0][0] is :1

*arr[0] is :1

**arr is :1

********************************************************

现在对数组地址进行移位操作

********************************************************

arr+1 is :0018FF38

arr addr +1 is :0018FF48

*arr +1 is :0018FF2C

arr[0]+1 is :0018FF2C

arr[0] addr +1 is :0018FF38

arr[0][0] addr +1 is :0018FF2C

********************************************************

现在对数组地址进行变态操作操作

********************************************************

&*arr[0] is :0018FF28

*&arr[0] is :0018FF28

&*arr[0]+1 is :0018FF2C

*&arr[0]+1 is :0018FF2C

(*arr[0]+1) is :2

&(*(arr[0]+1)) is :0018FF2C

*(&arr[0]+1) is :0018FF38

********************************************************

现在声明一个指针 P1 指向 数组 arr

int *p1 = arr;

编译器给出错误提示:

error C2440: 'initializing' : cannot convert from 'int [2][4]' to 'int *'

********************************************************

现在声明一个指向指针的指针 P2 指向 数组 arr

int **p2 =arr;

编译器给出错误提示:

error C2440: 'initializing' : cannot convert from 'int [2][4]' to 'int **'

********************************************************

现在声明一个指向数组的指针 P3

int (*p3)[4] = arr;

p3 is :0018FF28

p3 addr is :0018FF24

*p3 is :0018FF28

p3[0] is :0018FF28

p3[0] addr is :0018FF28

p3[0][0] addr is :0018FF28

p3[0][0] is :1

*p3[0] is :1

**p3 is :1

p3[1][0] is :2

**(p3+1) is :2

*(p3+1)[1] is :1638280

(*(p3+1))[1] is :4

*(*(p3+1)+1) is :4

********************************************************

现在对数组地址进行移位操作

********************************************************

p3+1 is :0018FF38

p3 addr +1 is :0018FF28  

// 自己查找不难发现 P3 的地址 , 答案自然出现 ???

*p3 +1 is :0018FF2C

p3[0]+1 is :0018FF2C

p3[0] addr +1 is :0018FF38

p3[0][0] addr +1 is :0018FF2C


小结分析:


1)表示arr[0][0]地址的方式

arr,&arr,*arr,arr[0],&arr[0],&arr[0][0] ;


2)单元素移址操作

表示 地址 偏移至 下一元素单元

cout<<"*arr +1 is :"<<*arr+1<<endl;

cout<<"arr[0]+1 is :"<<arr[0]+1<<endl;

cout<<"arr[0][0] addr +1 is :"<<&arr[0][0]+1<<endl;


3)单行移址操作

表示 地址 偏移至 次行:arr+1


4)数组移址操作

表示 地址 偏移至 全部数组 末尾 :& arr+1


5)指针和数组名的地址移址操作

arr addr +1 is :0018FF48

p3 addr +1 is :0018FF28  


6)指针的地址和指针本身

p3 is :0018FF28

p3 addr is :0018FF24

这说明变量高维数组指针p3存放的是第一个元素的地址,它指向第一个矩阵元素的地址。


遗留问题:

1)指针数组与数组指针区别;

  见下文

2)如代码显示:

// (1) int arr = {{1,3,5,7},{2,4,6,8}};
// (2) int arr[][] = {{1,3,5,7},{2,4,6,8}};
// 两种方式都是错的,为什么 !!!

  高维数组 简洁表示 为  int arr[][4] = {{1,3,5,7},{2,4,6,8}};

3)p3 addr +1 is :0018FF28 ???

P3 地址为 0018FF24 自然得到如下结论 。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值