Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
混淆显式衰减;int[]的数组;至;指向int";的指针;? 我是一个新手,正在学习随机顺序的C++。_C++ - Fatal编程技术网

混淆显式衰减;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;