2010-04-21 139 views
1

我有一个3x3数组,我试图创建一个指针,并且我一直收到这个数组,给出了什么?无法从int [] []转换为int *

我该如何定义指针?我尝试了[]和*的各种组合。

可以做到这一点吗?

int tempSec[3][3]; 

int* pTemp = tempSec; 
+0

这问题每天问10次左右,每次都回答。为什么这不关闭? – 2010-04-21 13:20:40

+0

您需要使用typedef来提供帮助。见下文。 – 2010-04-21 13:20:49

+0

提供重复的链接,我会投票结束它。 – Suma 2010-04-21 13:24:34

回答

15

你可以做int *pTemp = &tempSec[0][0];

如果你要治疗一个3x3的阵列作为一个int *,你应该宣布它作为一个int[9],并使用tempSec[3*x+y]代替tempSec[x][y]

另外,也许你想要的是int (*pTemp)[3] = tempSec?那将是一个指向tempSec的第一个元素的指针,第一个元素本身就是一个数组。

你其实可以采取一个指针到一个二维数组:

int (*pTemp)[3][3] = &tempSex; 

你会再使用这样的:

(*pTemp)[1][2] = 12; 

这是几乎可以肯定不是你想要的,但在你的评论你确实要求它...

+0

那么这些是我的两个选择?没有办法创建一个指向2D数组的指针? – cam 2010-04-21 12:57:15

+3

是的,但它不会有'int *'类型。我不知道你问题的哪些部分是你想要的部分,哪些不是你想要的部分... – 2010-04-21 12:59:22

+1

这样做,你扔掉任何关于数据布局的信息。现在你不能说它是一个三乘三的数组。 – 2010-04-21 13:20:32

0
int a[20][30]; 
int* b=&a[0][0]; 
0

原帖如下 - 请忽略,它是误导。留下它为了后代的缘故;)

但是,here is a link I found regarding memory allocation of 2-dimensional arrays in c++。也许它可能更有价值。


不知道这是你想要的东西,它已经有一段时间,因为我写C++,但你的施法失败的原因,是因为你是从一个数组的数组去整型的指针。如果,另一方面,你从数组试图数组指针的指针,它可能会工作

int tempSec[3][3]; 
int** pTemp = tempSec; 

记住,你的数组的数组是真正的内存持有指针的其他连续块的邻接块内存 - 这就是为什么将一个数组数组转换为一个int数组会得到一个看起来像垃圾的数组[垃圾真的是内存地址!]。

再次,取决于你想要什么。如果你想要它的指针格式,指针的指针是要走的路。如果你想要所有9个元素作为一个连续的数组,你将不得不对你的double数组进行线性化处理。

+0

“你的数组阵列实际上是一块连续的内存块,指向其他连续的内存块”。不,它确实不是。 – 2010-04-21 13:07:08

+0

“你的数组数组实际上是一个持有指针的连续块内存”---在这种情况下,这是不真实的。一个声明为“int arr [3] [3]”的数组是一个连续的内存块,足够大的空间用于9个int,并通过计算出的偏移量进行访问。我想很多C程序员都假设所有的多维数组都是指向指针的指针(等等......),因为'char ** argv' ---但是请记住这是一个'char *'数组,即一个字符串数组。一般来说,只有“不齐”的多维数组被实现为多层间接寻址(这是由程序员自行决定的)。 – 2010-04-21 13:09:56

+0

@Derrick土耳其,谢谢你的有益的意见!比我记得的更加生疏;) – 2010-04-21 13:26:54

0

正如史蒂夫指出的,正确的形式是int *pTemp = &tempSec[0][0];int** pTemp2 = tempSec;不起作用。给出的错误是:

cannot convert 'int (*)[3]' to 'int**' in initialization 

它没有存储为指向数组的指针数组。它存储为一个大的矢量,编译器隐藏你的[a][b] = [a*rowLength+b]

#include <iostream> 
using namespace std; 
int main() 
{ 
    // Allocate on stack and initialize. 
    int tempSec[3][3]; 
    int n = 0; 
    for(int x = 0; x < 3; ++x) 
     for(int y = 0; y < 3; ++y) 
      tempSec[x][y] = n++; 

    // Print some addresses. 
    cout << "Array base: " << size_t(tempSec) << endl; 
    for(int x = 0; x < 3; ++x) 
     cout << "Row " << x << " base: " << size_t(tempSec[x]) << endl; 

    // Print contents. 
    cout << "As a 1-D vector:" << endl; 
    int *pTemp = &tempSec[0][0]; 
    for(int k = 0; k < 9; ++k) 
     cout << "pTemp[" << k << "] = " << pTemp[k] << endl; 
    return 0; 
} 

输出:

Array base: 140734799802384 
Row 0 base: 140734799802384 
Row 1 base: 140734799802396 
Row 2 base: 140734799802408 
As a 1-D vector: 
pTemp[0] = 0 
pTemp[1] = 1 
pTemp[2] = 2 
pTemp[3] = 3 
pTemp[4] = 4 
pTemp[5] = 5 
pTemp[6] = 6 
pTemp[7] = 7 
pTemp[8] = 8 

注意,行0的地址是相同的完整的阵列地址,以及连续的行由sizeof(int) * 3 = 12抵消。 easyier

6

它使用一个typedef

typedef int ThreeArray[3]; 
typedef int ThreeByThree[3][3]; 

int main(int argc, char* argv[]) 
{ 
    int   data[3][3]; 

    ThreeArray* dPoint = data; 
    dPoint[0][2]   = 5; 
    dPoint[2][1]   = 6; 

    // Doing it without the typedef makes the syntax very hard to read. 
    // 
    int(*xxPointer)[3] = data; 
    xxPointer[0][1]  = 7; 

    // Building a pointer to a three by Three array directly. 
    // 
    ThreeByThree* p1  = &data; 
    (*p1)[1][2]   = 10; 

    // Building a pointer to a three by Three array directly (without typedef) 
    // 
    int(*p2)[3][3]  = &data; 
    (*p2)[1][2]   = 11; 

    // Building a reference to a 3 by 3 array. 
    // 
    ThreeByThree& ref1 = data; 
    ref1[0][0]   = 8; 

    // Building a reference to a 3 by 3 array (Without the typedef) 
    // 
    int(&ref2)[3][3]  = data; 
    ref2[1][1]   = 9; 


    return 0; 
} 
+0

这会丢弃数组的其中一个维度,这正是您在我的答案中指出的。所以现在我很困惑你在做什么。 – 2010-04-21 13:27:35

+0

@Steve Jessop:你放弃了这两个维度。我只丢弃一个。转换为一个指针,你将松散一个维度,你不能帮助。如果我们转换为引用,那么您不需要松散维度。 – 2010-04-21 13:32:41

+0

除了我的答案的第一行之外,我给出了和你一样的答案,但没有使用typedef。无论如何,你可以*避免丢失任何维度,将所有维度都包含在指针的类型中。这不太可能是提问者想要的,但是对于我来说,提问者是特别想要一个'int *',还是只想要某种指向数组的指针,这是完全不清楚的。这就是我提到两者的原因。 – 2010-04-21 13:36:07

0

另一种方式去这样做,是先创建一个指针数组:

int* pa[3] = { temp[0], temp[1], temp[2] }; 

然后创建一个指向指针指向:

int** pp = pa; 

然后,您可以使用该指针指针的普通数组语法来获取您的元素Ë寻找:

int x = pp[1][0]; // gets the first element of the second array 

另外,如果你想将其转换为指针的唯一原因是这样你就可以把它传递给一个函数,你可以这样做:

void f(int v[3][3]); 

由于只要数组的大小是固定的,您可以将二维数组传递给像这样的函数。它比比传递指针更具体。

+0

这个'f'的签名是不是真的放弃了其中一个维度?它与void f(int(* v)[3]);'的同义,',实际上是指向数组的指针而不是数组。所以虽然它比传递一个int **更具体,但并不像你想象的那样具体。将数字放在最后一个维度是有点误导的,因为编译器会忽略它,但这是调用者想要传递的数组数量的一个线索。 – 2010-04-21 13:50:30

+0

在哪里按最后尺寸,当然我的意思是第一维... – 2010-04-21 13:57:08

+0

很明显,编译器会让你做各种疯狂的事情而不抱怨。是的,我的观点是,这对用户来说会更加清楚。 – 2010-04-21 13:58:49

3

哦。这很容易!

int aai[3][3]; 
int* pi = reinterpret_cast<int*>(aai); 

实际上,您可以使用这种令人敬畏的技巧将其转换为其他精彩的类型。例如:

int aai[3][3]; 
int (__stdcall *pfi_lds)(long, double, char*) = reinterpret_cast<int (__stdcall *)(long, double, char*)>(aai); 

是不是只是膨胀?问题是它是否有意义。

你在问怎么骗你的编译器。所以首先要知道的是:你为什么要撒谎?

+0

是的,这真的不是一个好主意...... – 2010-04-21 13:38:45

+0

你为什么要这样做?获得第一个成员的地址是完全合法的。 – 2010-04-21 14:23:32

0

让我们问cdecl.org翻译您的声明我们:

int tempSec[3][3] 

回报

declare tempSec as array 3 of array 3 of int 


好了,我们如何创建一个指向?让我们CDECL又问:

declare pTemp as pointer to array 3 of array 3 of int 

回报

int (*pTemp)[3][3] 


既然我们已经有一个整型数组3的排列3,我们可以这样做:

int (*pTemp)[3][3] = &tempSec; 
相关问题