首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将int**转换为“指向每列元素数固定的二维整数数组的指针”。

将int**转换为“指向每列元素数固定的二维整数数组的指针”。
EN

Stack Overflow用户
提问于 2014-06-11 14:29:30
回答 5查看 2K关注 0票数 1

让我们假设有int**类型的变量,它是指向5x52D数组的指针:

代码语言:javascript
复制
int** ptr_array_5by5;

以及具有以下原型的函数:

代码语言:javascript
复制
void print2DArray_with5Columns(int (*ptr_row)[5]);

是否有一种方法将ptr_array_5by5转换为某种类型的,它将与函数的第一个参数的类型相匹配?

代码语言:javascript
复制
print2DArray_with5Columns( (<some casting type>) ptr_array_5by5)
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-06-11 14:54:04

  1. int**int(*)[5]是不同的类型(如n.m. )。(已指出)
  2. 您可以将作为指针对待,例如int a[5]; *(a+1) = 6;
  3. 您可以将作为数组对待,例如int *a = new int[5]; a[1] = 6;

但将对象A视为对象B并不意味着它实际上是对象B。

不过,您可以做的是声明一个int (*)[5],将ptr_array_5by5的值写入其中(当然是在分配内存之后),并将其传递给print2DArray_with5Columns

另一方面,是的,有些强制转换可以使您的代码进行编译。但我怀疑使用其中之一是否会使您更接近您的目标(参见http://ideone.com/lVzNrN)。

票数 1
EN

Stack Overflow用户

发布于 2014-06-11 15:11:36

当然了。

代码语言:javascript
复制
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声明不匹配。这里有一些代码实现了这种(特殊的)强制转换,并显示了它可以工作,正如我所说的。

代码语言:javascript
复制
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,这并不难做到。

票数 3
EN

Stack Overflow用户

发布于 2014-06-11 16:07:05

这里需要注意的是,int**不是指向任何东西的2D数组的指针。它是指向一维指针数组的指针。int (*)[5]是指向int的2D数组的指针(或者更准确地说,它是指向此类数组的第一个元素的指针)。您几乎可以使用reinterpret_cast将任何指针类型转换为任何其他指针类型,但它也几乎可以保证在运行时不工作。(有一些特殊的例外,但它们都是非常特定于平台的,并且非常接近硬件。)

如果您确实有一个指向5int*int*,每个int都指向5 int,并且您需要一个int (*)[5],那么成功转换的唯一方法就是对实际的底层数据进行转换(这将涉及一个副本),而不是对指针进行转换。类似于:

代码语言:javascript
复制
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]

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24165572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档