int main(){
int a[10][10];
int **ptr =(int **)a;
cout<<a<<endl<<ptr<<endl;
cout<<*a<<endl<<*ptr<<endl;
return 0;
}
这段代码在我的电脑上的输出结果是
0021FC20
0021FC20
0021FC20
CCCCCCCC
为什么"a"等于"*a"? 为什么"*a"不等于"*ptr"?
int main(){
int a[10][10];
int **ptr =(int **)a;
cout<<a<<endl<<ptr<<endl;
cout<<*a<<endl<<*ptr<<endl;
return 0;
}
这段代码在我的电脑上的输出结果是
0021FC20
0021FC20
0021FC20
CCCCCCCC
a
等于*a
?a
是一个数组的数组;因此它会衰减为指向第一个数组的指针。*a
是第一个数组,并且会衰减为指向该数组中第一个整数的指针。这两个存在于同一位置,因此这两个指针将具有相等的值。*a
不等于*ptr
?reinterpret_cast
- 因此*ptr
将读取数组的前几个字节,并将其解释为指针(可能-这里的行为是未定义的,因此原则上任何事情都可能发生)。在ptr
指向的内存中没有指针,因此*ptr
肯定不会给您有效的指针。int main(){
int a[10][10];
int *ptr =(int *)a;
cout<<a<<endl<<ptr<<endl;
cout<<*a<<endl<<*ptr<<endl;
return 0;
}
以上代码将会给你想要的结果。
但是当你解引用 a 或 ptr 时,你会发现得到了一个“未定义的值”。
如果你将 a[4][4] 设置为 5
那么你会发现存储在 ptr[(row * 10) + column] 中的值将返回 row = 4 和 column = 4 的值。
int *ptr =(int *)a;
这种写法是不合法的。你可以选择写成 int *ptr = a[0];
或者 int (*ptr)[10] = a;
。 - fredoverflow// Note: The size of the array, 5, can be omitted
int a[5] = {5, 10, 15, 20, 25};
下标操作将产生以下结果:
a[0] = 5
a[1] = 10
a[2] = 15
a[3] = 20
a[4] = 25
这很容易,大多数人都能理解。但是如果你现在这样做:
// Note: Like above, the size of the array, 5, can be omitted
int a[5][10] = {{ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50},
{ 55, 60, 65, 70, 75, 80, 85, 90, 95, 100},
{105, 110, 115, 120, 125, 130, 135, 140, 145, 150},
{155, 160, 165, 170, 175, 180, 185, 190, 195, 200},
{205, 210, 220, 225, 230, 235, 240, 245, 250, 255}};
你仍然有一个由5个元素组成的一维数组,你可以像之前的例子一样对其进行下标操作,得到以下结果(不是真正的语法,只是你应该这样考虑):
a[0] = 5 10 15 20 25 30 35 40 45 50
a[1] = 55 60 65 70 75 80 85 90 95 100
a[2] = 105 110 115 120 125 130 135 140 145 150
a[3] = 155 160 165 170 175 180 185 190 195 200
a[4] = 205 210 220 225 230 235 240 245 250 255
这里唯一的区别是,每个元素不像前面的例子那样是一个“int”,而是一个数组(由10个整数组成)。因此,当您像所示那样进行下标操作时,每个索引(0到4)都会返回该行的10个整数的数组。例如,a [3] 返回包含值155到200的10个整数的数组。元素本身是“int [10]”,因此您可以将其视为这样的方式。换句话说,您得到的相当于:
int b[10] = {155, 160, 165, 170, 175, 180, 185, 190, 195, 200};
int *p = b; // "b" decays into a pointer to its first element (an "int")
int val = *p; // Equals 155
这也是正确的:
int *p = a[3]; // a[3] returns the equivalent of "b", an int[10], and this decays into a pointer to its first element, just like "b"
int val = *p; // Equals 155
int (*p)[10] = a;
int *p[10] = a; // Compiler error!
这个声明将“p”声明为一个包含10个元素的数组,其中每个元素都是指向int类型的指针。它不同于IOW,因此需要使用括号来改变优先级(从而改变此声明的含义)。使用先前显示的正确语法,“p”将指向第一个元素(包含元素5到50的“int [10]”数组),p + 1将指向第二个元素(包含元素55到100的“int [10]”数组),以此类推。额外加分:因此以下代码会做什么?
(*(p + 3))[5]
它返回180,因为(p + 3)返回指向位于"a[3]"的10个整数数组的指针,当使用*运算符进行解引用时,您会得到实际位于此位置的"int [10]"数组。然后,[5]下标在此数组中产生值180。
毫无疑问,仍需要大量练习才能理解这一点,但我希望这有所帮助。
int **ptr = (int **)a;
是一种非法的类型转换。嵌套数组和嵌套指针之间不存在转换关系。请参考我们的相关常见问题解答。 - fredoverflow(cast)
语法。如果您使用正确的static_cast<int**>
语法,编译器会立即告诉您转换无效。 - R. Martinho Fernandes