让我们假设有一个int **类型的变量,它是指向5x5 2D数组的指针:
int** ptr_array_5by5;
以及具有以下原型的函数:
void print2DArray_with5Columns(int (*ptr_row)[5]);
有没有办法将 ptr_array_5by5 强制转换为某种类型,这会匹配函数第一个参数的类型?
print2DArray_with5Columns( (<some casting type>) ptr_array_5by5)
答案 0 :(得分:3)
这里要认识到的重要一点是int**
不是
指向任何东西的2D数组的指针。它是指向1D的指针
指针数组。 int (*)[5]
是指向2D数组的指针
int
(或者更确切地说,它是指向第一个元素的指针
这样一个阵列)。你几乎可以转换任何指针类型
使用reinterpret_cast
到任何其他指针类型,但它是
也非常保证不会在运行时工作。 (有
特殊例外,但它们都是特定于平台的,并且
非常接近硬件。)
如果你确实有int**
指向5 int*
,则每个int
它指向5 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]
至{{1}}。
答案 1 :(得分:2)
当然。
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个整数数组的指针,它会衰减为一个简单的数组。此代码生成一个5x5平面矩阵并打印第一行。
我怀疑真正的问题是演员是错的,因此整个问题都是错误的。
有人质疑这是否是可怕的未定义行为。经过适当的照顾,它不是。该标准实际上允许将任何类型的指针对象强制转换为其他指针对象或void指针或足够大的整数,然后再返回。 [指向函数的指针和指向成员的指针的处理方式稍有不同。]往返指针保证保持相同的值。因此,如果遵循规则,这个演员阵容不是UB,这并不难做到。
答案 2 :(得分:1)
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)。
答案 3 :(得分:0)
我认为你会因为假设指针是数组而感到困惑。指针不是数组,反之亦然。如果ptr_array_5by5
是一个2D数组,那么原型中的参数可以用于传递ptr_array_5by5
作为参数。但您将其声明为int **ptr_array_5by5
,最好将参数更改为int **
类型。
答案 4 :(得分:0)
你为什么要施展int **?
使用指针指向地址。
因此,不必使用类型转换指针,而是必须将此指针指向某个变量。
类型转换指针没有意义,因为它们本身并不存储值。