【摘要】
本文首先给出高维指针数组 与 高维数组指针的代码实现,然后,通过取址操作与移址操作说明,移位、移行、移数组的操作方式。
【特】
高维数组指针存放的是数组首个元素的地址而不是首元素地址本身,这一点跟一维数组指针和一维数组以及高高数组要区别开来。
【正文】
#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 自然得到如下结论 。