Не удается преобразовать из int [] [] в int * - PullRequest
1 голос
/ 21 апреля 2010

У меня есть массив 3x3, на который я пытаюсь создать указатель, и я продолжаю получать этот массив, что дает?

Как мне определить указатель? Я пробовал каждую комбинацию [] и *.

Возможно ли это сделать?

int tempSec[3][3];

int* pTemp = tempSec;

Ответы [ 9 ]

15 голосов
/ 21 апреля 2010

Вы можете сделать 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;

Это почти наверняка не то, что вы хотите, но в своем комментарии вы просили об этом ...

6 голосов
/ 21 апреля 2010

Его проще использовать 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;
}
3 голосов
/ 21 апреля 2010

О. Это просто!

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 голосов
/ 21 апреля 2010
int tempSec[3][3];

int* pTemp = tempSec[0];
0 голосов
/ 21 апреля 2010

Давайте попросим cdecl.org перевести вашу декларацию для нас:

int tempSec[3][3]

возвращает

declare tempSec as array 3 of array 3 of int 

1011 *
*

Хорошо, как мы можем создать указатель на это? Давайте снова спросим cdecl:

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

возвращает

int (*pTemp)[3][3]


Поскольку у нас уже есть массив 3 массива 3 типа int, мы можем просто сделать:

int (*pTemp)[3][3] = &tempSec;
0 голосов
/ 21 апреля 2010

Еще один способ сделать это - сначала создать массив указателей:

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 голосов
/ 21 апреля 2010

Как указал Стив, правильная форма - 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.

0 голосов
/ 21 апреля 2010

Оригинальный пост следует - пожалуйста, не обращайте внимания, он дезинформирован. Оставив это ради потомков;)

Однако, вот ссылка, которую я нашел относительно выделения памяти для 2-мерных массивов в c ++ . Возможно, это может иметь большую ценность.


Не уверен, что это то, что вам нужно, и я давно писал C ++, но причина вашего сбоя в том, что вы переходите от массива массивов к указателю целых чисел. С другой стороны, если вы пытаетесь перейти от массива к массиву до указателя указателей, это, вероятно, сработает

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

помните, что ваш массив массивов - это действительно непрерывный блок памяти, содержащий указатели на другие смежные блоки памяти, - поэтому преобразование массива массивов в массив целых дает вам массив того, что выглядит как мусор мусор - это действительно адреса памяти!].

Опять же, зависит от того, что вы хотите. Если вы хотите получить указатель в формате указателя, указатель указателя - путь. Если вы хотите, чтобы все 9 элементов представляли собой один непрерывный массив, вам придется выполнить линеаризацию вашего двойного массива.

0 голосов
/ 21 апреля 2010
int a[20][30];
int* b=&a[0][0];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...