让我们假设有int**类型的变量,它是指向5x52D数组的指针:
int** ptr_array_5by5;以及具有以下原型的函数:
void print2DArray_with5Columns(int (*ptr_row)[5]);是否有一种方法将ptr_array_5by5转换为某种类型的,它将与函数的第一个参数的类型相匹配?
print2DArray_with5Columns( (<some casting type>) ptr_array_5by5)发布于 2014-06-11 14:54:04
int**和int(*)[5]是不同的类型(如n.m. )。(已指出)int a[5]; *(a+1) = 6;int *a = new int[5]; a[1] = 6;。但将对象A视为对象B并不意味着它实际上是对象B。
不过,您可以做的是声明一个int (*)[5],将ptr_array_5by5的值写入其中(当然是在分配内存之后),并将其传递给print2DArray_with5Columns。
另一方面,是的,有些强制转换可以使您的代码进行编译。但我怀疑使用其中之一是否会使您更接近您的目标(参见http://ideone.com/lVzNrN)。
发布于 2014-06-11 15:11:36
当然了。
int** ptr_array_5by5;
void print2DArray_with5Columns(int (*ptr_row)[5]);
print2DArray_with5Columns( (int (*)[5]) ptr_array_5by5);
print2DArray_with5Columns( reinterpret_cast<int (*)[5]>(ptr_array_5by5));尽管C语言声明语法存在所有错误,但可以通过简单地重写声明,忽略任何标识符来创建强制转换。它可以编译,甚至可以工作。
这里有很多混乱,因为描述性的措辞与C声明不匹配。这里有一些代码实现了这种(特殊的)强制转换,并显示了它可以工作,正如我所说的。
void print2DArray_with5Columns(int (*ptr_row)[5]) {
for (int i = 0; i < 5; i++)
cout << (*ptr_row)[i] << " ";
cout << std::endl;
}
int main() {
int* a;
int** ptr_array_5by5;
a = new int[25];
for (int i = 0; i < 25; i++)
a[i] = i;
ptr_array_5by5 = (int**)a;
print2DArray_with5Columns((int (*)[5])(ptr_array_5by5));
return 0;
}请注意,这个声明是而不是 5x5矩阵。该转换只是一个指向5个ints数组的指针,该数组将衰减为一个简单的数组。此代码生成一个5x5平坦矩阵并打印第一行。
我怀疑真正的问题是演员是错的,所以整个问题都是错误的。
问题是,这是否是令人恐惧的不明确的行为。在适当的注意下,情况并非如此。该标准实际上允许将任何类型的指针到对象转换为其他指针到对象、空指针或足够大的整数,然后再返回。指针到函数和指针到成员的处理方式有点不同。保证往返指针保留相同的值。因此,只要遵守规则,此转换就不是UB,这并不难做到。
发布于 2014-06-11 16:07:05
这里需要注意的是,int**不是指向任何东西的2D数组的指针。它是指向一维指针数组的指针。int (*)[5]是指向int的2D数组的指针(或者更准确地说,它是指向此类数组的第一个元素的指针)。您几乎可以使用reinterpret_cast将任何指针类型转换为任何其他指针类型,但它也几乎可以保证在运行时不工作。(有一些特殊的例外,但它们都是非常特定于平台的,并且非常接近硬件。)
如果您确实有一个指向5int*的int*,每个int都指向5 int,并且您需要一个int (*)[5],那么成功转换的唯一方法就是对实际的底层数据进行转换(这将涉及一个副本),而不是对指针进行转换。类似于:
int tmp[5][5];
for ( int i = 0; i != 5; ++ i ) {
int* row = ptr_array_5by5[i];
for ( int j = 0; j != 5; ++ j ) {
tmp[i][j] = row[j];
}
}然后,您可以将tmp传递给您的函数,而无需任何强制转换:数组到指针的隐式转换将将int [5][5]转换为int (*)[5]。
https://stackoverflow.com/questions/24165572
复制相似问题