混淆从"array of int[]"到"pointer to int"的显式衰减?
Confusing explicit decay from "array of int[]" to "pointer to int"?
我是一个新手,正在按随机顺序学习C++。
在下面的前三种情况下,我可以理解正在发生的事情,因为隐式衰减的模式是清楚的。
"
X
的数组"隐式衰减为"指向X
的指针"。
void case1()
{
int a[] = { 1,2,3,4,5,6 };
int *b = a;// array of int ---> pointer to int
}
void case2()
{
int input[][3] = { {1,2,3},{4,5,6} };
int(*output)[3] = input;// array of int[] ---> a pointer to int[]
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
cout << output[i][j] << endl;
}
int case3()
{
int input[][3] = { {1,2,3},{4,5,6} };
int* aux[2];
aux[0] = input[0];// array of int ---> pointer to int
aux[1] = input[1];// array of int ---> pointer to int
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;
}
问题
然而,我真的对以下第四种情况感到困惑。
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;
}
如何将"int[]
的数组"显式衰减为"指向int
的指针"?
aux[0] = (int*)input;// array of int[] ---> pointer to int
欢迎任何简单的解释!
如何将"一个int[]数组"显式衰减为"一个指向int的指针"?
对术语过于迂腐:"显式衰退"是一种矛盾修辞法。衰减根据定义是一种隐式转换。
要回答"如何将[数组]显式[转换]为[不是第一个元素类型的指针]?">:
这是因为数组可以衰减为指针,并且所有数据指针都可以显式转换(重新解释)为任何其他数据指针类型。在这种情况下,input
衰减为int(*)[3]
,然后显式地转换为int*
。
尽管它的形式确实很好,但另一个问题是通过显式重新解释的指针进行间接是否定义了行为。指针重新解释的规则是复杂而微妙的——假设它保证按照你观察到的方式行事是不安全的。我会更有信心写作:
aux[0] = *input;
这里,input
数组衰减为指向第一个子数组的指针,该指针被间接地获取左值,然后它衰减为指向子数组元素的指针。
通常,在使用显式转换(T)expr
或函数转换T(expr)
或重新解释强制转换reinterpret_cast<T>(expr)
时要非常小心。除非你能引用标准规则,让它们的使用得到很好的定义,否则不要使用它们。
嗯,这听起来很有效,但合法吗。
已知的是,数组的第一个元素和数组本身在内存中共享相同的地址。
在常见的实现中,所有指针共享相同的表示,并且该表示只是其第一个字节的内存地址。简单地说,标准并不能保证这一点。
但是,成功地将数组的地址转换为其第一个元素的地址就足够了。显式强制转换将数组地址的表示形式重新解释为第一个元素的地址,由于实现的原因,它恰好起作用。
这就是未定义行为的伟大之处:它并不禁止自然行为,但也不能保证它。
因此,根据标准的字符串读取,特别是严格混叠规则,将指向数组的指针转换为指向其第一个元素的指针,并使用该指针解引用元素是UB,因为数组及其元素类型是不同的类型。只需AFAIK,它就可以在所有常见的实现中工作。
TL/DR:它适用于所有常见的实现,但如果您想编写符合标准的程序,请不要使用它。
- 为什么选择 g++ 给予者:"error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]"
- static_cast int to reference to int?
- 访问基类型数组成员(Int-to-type习惯用法)
- Int to Base 2 & 8 优化
- ASCII to int to ASCII (ATMEGA 2560)
- 简单的 int 到字符串转换..int to const char* 无效
- visual Int to char c++
- 隐式转换更改符号性 'int " to 'unsigned int"
- 如何修复此错误错误"error C2440: '=' : cannot convert from 'int (*)[]' to 'int *' "?
- int to char C++ help me
- Int to PCSTR for Winsock DEFAULT_PORT
- 将 double 分配给 const int&vs int to const int&
- "cannot Convert vector<int>* to int"是什么意思?
- 如何解决此棉绒警告"Implicit binary conversion from int to unsigned int"
- c++ int to char
- 为什么我会收到"cannot convert from Dequeu<int> to int"错误?
- "error: invalid conversion from 'int*' to 'int' function"
- "Truncation from int to char"不产生任何结果
- Cast int to void* and void* to int for TMemoryStream->WriteBuffer (C++Builder XE7)
- C++ Int to Array without Libs