user-0 提问: 指针与多维数组

回复:
user: user-1
content: 数组就是指针，指针就是数组。 int a[][]是一个双重指针，int *p只是一个单重指针。 当然会出错了。~

user: user-2
content: LZ,要注意的是，你定义的是一个二维数组a[3][3],int *p,p=&a,我想问下，LZ，p=&a，那么*p,表示的什么意思，是地址还是值，如果搞清楚了，这个问题应该很容易解决。其次，告诉一个小诀窍，便于记忆，*，[]，对于表示数组值是相同的，例如，打印一个值，1）两个*，如**a,2)一个*，一个[]搭配，如*a[0],3)连个[][].如，a[0][0].希望对你有帮助！

user: user-3
content: 不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。

user: user-3
content: //在堆中开辟一个4×5的二维int数组 #include <stdio.h> #include <malloc.h> int **p; int i,j; void main() {     p=(int **)malloc(4*sizeof(int *));     if (NULL==p) return;     for (i=0;i<4;i++) {         p[i]=(int *)malloc(5*sizeof(int));         if (NULL==p[i]) return;     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             p[i][j]=i*5+j;         }     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             printf(" %2d",p[i][j]);         }         printf("\n");     }     for (i=0;i<4;i++) {         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19  //在堆中开辟一个3×4×5的3维int数组 #include <stdio.h> #include <malloc.h> int ***p; int i,j,k; void main() {     p=(int ***)malloc(3*sizeof(int **));     if (NULL==p) return;     for (i=0;i<3;i++) {         p[i]=(int **)malloc(4*sizeof(int *));         if (NULL==p[i]) return;         for (j=0;j<4;j++) {             p[i][j]=(int *)malloc(5*sizeof(int));             if (NULL==p[i][j]) return;         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 p[i][j][k]=i*20+j*5+k;             }         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 printf(" %2d",p[i][j][k]);             }             printf("\n");         }         printf("---------------\n");     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             free(p[i][j]);         }         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //--------------- // 20 21 22 23 24 // 25 26 27 28 29 // 30 31 32 33 34 // 35 36 37 38 39 //--------------- // 40 41 42 43 44 // 45 46 47 48 49 // 50 51 52 53 54 // 55 56 57 58 59 //---------------  //在堆中开辟一个2×3×4×5的4维int数组 #include <stdio.h> #include <malloc.h> int ****p; int h,i,j,k; void main() {     p=(int ****)malloc(2*sizeof(int ***));     if (NULL==p) return;     for (h=0;h<2;h++) {         p[h]=(int ***)malloc(3*sizeof(int **));         if (NULL==p[h]) return;         for (i=0;i<3;i++) {             p[h][i]=(int **)malloc(4*sizeof(int *));             if (NULL==p[h][i]) return;             for (j=0;j<4;j++) {                 p[h][i][j]=(int *)malloc(5*sizeof(int));                 if (NULL==p[h][i][j]) return;             }         }     }     for (h=0;h<2;h++) {         for (i=0;i<3;i++) {             for (j=0;j<4;j++) {                 for (k=0;k<5;k++) {                     p[h][i][j][k]=h*60+i*20+j*5+k;                 }             }         }     }     for (h=0;h<2;h++) {         for (i=0;i<3;i++) {             for (j=0;j<4;j++) {                 for (k=0;k<5;k++) {                     printf(" %3d",p[h][i][j][k]);                 }                 printf("\n");             }             printf("--------------------\n");         }         printf("=======================\n");     }     for (h=0;h<2;h++) {         for (i=0;i<3;i++) {             for (j=0;j<4;j++) {                 free(p[h][i][j]);             }             free(p[h][i]);         }         free(p[h]);     }     free(p); } //   0   1   2   3   4 //   5   6   7   8   9 //  10  11  12  13  14 //  15  16  17  18  19 //-------------------- //  20  21  22  23  24 //  25  26  27  28  29 //  30  31  32  33  34 //  35  36  37  38  39 //-------------------- //  40  41  42  43  44 //  45  46  47  48  49 //  50  51  52  53  54 //  55  56  57  58  59 //-------------------- //======================= //  60  61  62  63  64 //  65  66  67  68  69 //  70  71  72  73  74 //  75  76  77  78  79 //-------------------- //  80  81  82  83  84 //  85  86  87  88  89 //  90  91  92  93  94 //  95  96  97  98  99 //-------------------- // 100 101 102 103 104 // 105 106 107 108 109 // 110 111 112 113 114 // 115 116 117 118 119 //-------------------- //======================= //

user: user-4
content: int *p ;   *(*(p+i)+j);//这个写法有问题。  二维数组元素a[i][j],在内存中是连续存放的。不能看作双重指针。 双重指针模拟的二维数组不是连续存放的。   int (*p)[3];//用一个指向二维数组的指针,用法上就自然得多。 int a[3][3]; int b[3][3]; p=a; for(int i=0;i<3;i++) for(int j=0;j<3;j++)   b[j][i]=*(*(p+i)+j);//或者b[j][i]=p[j][i];

user: user-5
content: 引用 5 楼 changliangdoscript 的回复:int *p;int a[3][3]={1,2,3,4,5,6,7,8,9}; p=a; p只要赋一个地址值就应该可以，为什么这种情况下就不行呢 一维数组就要用一级指针，二维数组用二级指针，你定义数组的时候用2维的去接一维的数据，本来就会导致取值出错，当指针指向一块地址时，它指向的是一种类型，int*p 的类型是 int *   a 的类型是 int [3][3] ,不是一个类型的，明白？

user: user-6
content: 引用int *p;int a[3][3]={1,2,3,4,5,6,7,8,9}; p=a; p只要赋一个地址值就应该可以，为什么这种情况下就不行呢 我的理解a表示数组，而p是指针，所以，你只能先把a转为数组首地址（int *)a，或者是直接用数组首地址&a[0][0]。其实没必要纠结于这个，只要理解指针是指向内存地址的，*取地址里的内容，想怎么用就怎么用。

user: user-0
content: int *p;int a[3][3]={1,2,3,4,5,6,7,8,9}; p=a; p只要赋一个地址值就应该可以，为什么这种情况下就不行呢

user: user-0
content: 为什么用普通指针不行，用指向数组的指针就可以呢？跟编译环境或者语言有关系？ #include <stdio.h> void main ( ) { 	int (*p)[3];int a[3][3]={1,2,3,4,5,6,7,8,9}; 	p=a; 	int b[3][3]; 	for(int i=0;i<3;i++) 		for(int j=0;j<3;j++) 		{               b[j][i]=*(*(p+i)+j); 			  printf("%d",b[j][i]); 		} }

user: user-6
content: p=a改为p=(int *)a就可以了。指针指向数组首地址没什么问题。 *(*(p+i)+j)是有问题的，指针前加*是获取指针所指内存的内容。因此如果p=(int *)a，那么*(p + i*3 +j)就表示a[i][j]的内容。所以代码该位如下就能得到把数组a复制到数组b的结果。 #include <stdio.h> void main ( ) { int *p;int a[3][3]={1,2,3,4,5,6,7,8,9}; p=(int *)a; int b[3][3]; for(int i=0;i<3;i++) for(int j=0;j<3;j++) {               b[i][j]=*(p + i * 3 + j);   printf("%d\n",b[i][j]); }  }

user: user-7
content: 第一个没有看出来问题 第二个知道有问题，但是我解释不了，等大神的解释

user: user-8
content: 首先楼主你定义的是一维指针int*而不是二维指针int** 我想你记错了你转述的这个说法  然后从for(int i = 0;这行来看，我猜你使用的可能是C++编译器 C++在类型转换上比C严格许多，所以int ** p = a;也是不一定行得通的  再然后a[b]和*(a+b)完全等价，a[3]和3[a]完全等价，这是语言标准规定的 所以a[2][3]==*(a[2]+3)==*(*(a+2)+3)==(*(a+2))[3]