混淆显式衰减;int[]的数组;至;指向int";的指针;? 我是一个新手,正在学习随机顺序的C++。
在下面的前三种情况中,我可以理解正在发生的事情,因为隐式衰减的模式是明确的 “一个混淆显式衰减;int[]的数组;至;指向int";的指针;? 我是一个新手,正在学习随机顺序的C++。,c++,C++,在下面的前三种情况中,我可以理解正在发生的事情,因为隐式衰减的模式是明确的 “一个X数组”隐式衰减为“指向X的指针” 欢迎任何简单的解释 “int[]数组”如何显式衰减为“指向int的指针” 学究式地使用术语:“明显地衰退”是一种矛盾修饰法。根据定义,衰减是一种隐式转换 要回答“如何将[array]显式地[转换]为[不是第一个元素类型的指针]?”: 这是因为数组可以衰减为指针,所有数据指针都可以显式转换(重新解释)为任何其他数据指针类型。在这种情况下,input衰减为int(*)[3]然后显式转
X
数组”隐式衰减为“指向X
的指针”
欢迎任何简单的解释
“int[]数组”如何显式衰减为“指向int的指针”
学究式地使用术语:“明显地衰退”是一种矛盾修饰法。根据定义,衰减是一种隐式转换
要回答“如何将[array]显式地[转换]为[不是第一个元素类型的指针]?”:
这是因为数组可以衰减为指针,所有数据指针都可以显式转换(重新解释)为任何其他数据指针类型。在这种情况下,input
衰减为int(*)[3]
然后显式转换为int*
虽然它的格式肯定是好的,但另一个问题是通过显式重新解释的指针间接执行是否定义了行为。重新解释指针的规则是复杂而微妙的——假设指针的行为保证与您观察到的方式一致是很难安全的。我会更自信地写:
aux[0] = *input;
这里,输入
数组衰减为指向第一个子数组的指针,该指针被间接指向以获得左值,然后该左值衰减为指向子数组元素的指针
更一般地说,在使用显式转换
(T)expr
或函数转换T(expr)
或重新解释转换重新解释转换(expr)
时要非常小心。除非你能引用标准规则来定义它们的用法,否则不要使用它们。嗯,这听起来很有效,但合法吗
众所周知,数组的第一个元素和数组本身在内存中共享相同的地址
在常见的实现中,所有指针共享相同的表示形式,并且该表示形式只是它们的第一个字节的内存地址。简单地说,该标准并不能保证这一点
但它足以成功地将数组的地址转换为其第一个元素的地址。显式cast将数组地址的表示形式重新解释为第一个元素的地址,并且由于实现的原因,它恰好工作
这就是未定义行为的伟大之处:它不禁止自然行为,但也不保证自然行为
因此,根据标准的字符串读取,特别是严格的别名规则,将指向数组的指针转换为指向其第一个元素的指针,并使用该指针取消引用元素是UB,因为数组及其元素类型是不同的类型。简单地说,它适用于所有常见的实现
TL/DR:它适用于所有常见的实现,但如果您想编写符合标准的程序,请不要使用它。
(int*)input
,这是错误的。它不是那样工作的。请参阅副本。添加(int*)
意味着您不再处理隐式转换。@Godsmustbecrazy Right,因此输入隐式转换为int(*)[3]
,然后(int*)
告诉编译器“这是int*
。相信我,我知道我在做什么。”。从这一点上讲,它之所以有效,是因为正如前面链接的问题所解释的,数组在内存中的布局方式。硬c风格强制转换允许您将任何指针强制转换为任何其他指针,而不管语言的规则如何,但确保您不会使用转换后的指针出错的责任落在您身上噢,我的鬼:我只知道intx[]={1,2,3};库特
int case4()
{
int input[][3] = { {1,2,3},{4,5,6} };
int* aux[2];
aux[0] = (int*)input;// array of int[] ---> pointer to int
aux[1] = aux[0] + 3;
int** output = aux;// array of int* ---> pointer to int*
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
cout << output[i][j] << endl;
}
aux[0] = (int*)input;// array of int[] ---> pointer to int
aux[0] = *input;