在练习一些简单的数组和指针基础知识时,我遇到了一些我无法理解的事情:
在我能找到的所有书面资料中,他们说二维数组的名称实际上是二维指针,这意味着如果我写:
int a[3][4];
Run Code Online (Sandbox Code Playgroud)
并声明一个指针:
int **d2;
Run Code Online (Sandbox Code Playgroud)
它们都是同一类型,我可以安全地分配:
d2 = a;
Run Code Online (Sandbox Code Playgroud)
使指针指向第一行的开头。
但最令人惊讶的是,这不起作用,我的问题是——为什么?
我会为您复制代码和我收到的警告:
#include <stdio.h>
int main() {
int **d2;
int a[5][2] = { {1, 2}, {3, 4}, {5, 7}, {7, 8}, {9, 11} };
d2 = a;
while (d2 < a + 2) {
printf("%d", **d2);
d2++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到这个诊断:
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
d=a;
^
ptr.c:11:9: warning: comparison of distinct pointer types lacks a cast
while(d<a+2)
Run Code Online (Sandbox Code Playgroud)
它们的内部结构完全不同,因此不能互换。
二维数组是这样的:
p[3][3]
|
v
+---------+---------+---------+---------+---------+---------+---------+
| p[0][0] | p[0][1] | p[0][2] | p[1][0] | p[1][1] | p[1][2] | ... |
+---------+---------+---------+---------+---------+---------+---------+
Run Code Online (Sandbox Code Playgroud)
一个连续的空间。
指针是这样的:
**p
|
v
+------+ +---------+---------+---------+---------+---------+
| p[0] |-->| p[0][0] | p[0][1] | p[0][2] | p[0][3] | ... |
+------+ +---------+---------+---------+---------+---------+
| p[1] |-->| p[1][0] | p[1][1] | p[1][2] | p[1][3] | ... |
+------+ +---------+---------+---------+---------+---------+
| p[2] |-->| p[2][0] | p[2][1] | p[2][2] | p[2][3] | ... |
+------+ +---------+---------+---------+---------+---------+
| .... |
+------+
Run Code Online (Sandbox Code Playgroud)
其中每个p[i]可能指向不同大小的不同空间。