В C / C ++: Как я могу реализовать массив 2D int, используя два отдельных указателя (без использования ** int)? - PullRequest
0 голосов
/ 20 марта 2019

Я изучаю указатель "механика" в C / C ++. Я пытаюсь понять, можно ли и как реализовать 2D-матрицу, используя два указателя (один для «строк» ​​и один для «столбцов») вместо одного двойного указателя. Мне известно, что матрица с числом строк и столбцов * значений может храниться в памяти последовательно, но я стремлюсь глубже понять механизм указателей и в конечном итоге реализовать функцию, аналогичную

int value=getValue(vectorNr,vectorValue) 

, способный "симулировать" конструкцию

value=Matrix[vectorNr][vectorValue]

vectorPointer                 vectorValue
| AddressV1 |------|valAddr11 valAddr12 valAddr13 |
| AddressV2 |------|valAddr21 valAddr22 valAddr23 |
| AddressV3 |------|valAddr31 valAddr32 valAddr33 |   

Я пытался начать писать подобный код, но быстро застрял в арифметике указателей и смещении адресов. Я также мог бы выбрать очень грязный подход, поэтому любые комментарии приветствуются.

КОД ДЛЯ РЕАЛИЗАЦИИ Массива 2D с помощью указателей (НО НЕ ИСПОЛЬЗУЯ ДВОЙНЫХ УКАЗАТЕЛЕЙ). Чтобы избежать путаницы между строками и столбцами, я имею в виду «Векторы как строки» и «Столбцы как значения векторов»

    int vectorsNumber = 3; //Number of Vectors
    int valuesNumber = 3; //Number of values stored in one     Vector


    //Addresses of Vectors. Since Vectors holds a reference to set of values, vectorPointer will hold an address for every set.
    void* vectorPointer = malloc(vectorsNumber     *sizeof(void*)); 


    //Populating the vectorPointer with the address generated by allocating memory for every set of values
    for (int i = 0; i < vectorsNumber; i++)
    {
        vectorPointer = (int*)malloc(valuesNumber * sizeof(int)); //Values shall be of int types
        vectorPointer++; //ILLEGAL since cannot perform arithmetic on pointers of type void. What do do??
    }

    //Restore the initial address. In any case...ILLEGAL arithmetic.    What do do??
    for (int i = 0; i < vectorsNumber; i++)
    {
        vectorPointer--; //Restore the initial address. In any case...ILLEGAL arithmetic.
    }

    //Declaring the pointer to hold the address of one value. Memory was already allocated before
    int* valueAddress; 
    for (int j = 0; j < vectorsNumber; j++)
    {
        //Getting the address of the first value of the first Vector
        valueAddress = (int*)vectorPointer; //Is this casting valid in C language?


        //Populating the value with whatever operation
        for (int k = 0; k < valuesNumber; k++)
        {

            *valueAddress = (k + 1)*(j + 1); //populate the Vector with int values
        }

        vectorPointer++; //Switch to next Vector.ILLEGAL arithmetic

    }

Ответы [ 3 ]

2 голосов
/ 20 марта 2019

Эта идея "двух указателей" не имеет никакого смысла, и код, который вы разместили, не может быть спасен. Вместо этого вам следует использовать указатель на двумерный массив:

int (*ptr)[x][y] = malloc(sizeof *ptr);
...
free(ptr);

Вот и все. Однако указатель на 2D-массив громоздок, так как мы должны отменить ссылку на него перед доступом к реальному массиву. То есть в итоге мы написали бы (*ptr)[i][j] = ...;, что ужасно.

Чтобы избежать этого, мы можем вместо этого выделить 2D-массив, но вместо того, чтобы указывать на «весь массив», мы указываем на первый элемент, который является 1D-массивом:

int (*ptr)[y] = malloc( sizeof(int[x][y]) );
...
ptr[i][j] = ... ; // more convenient syntax for access
...
free(ptr);

Дополнительная информация: Правильное размещение многомерных массивов

2 голосов
/ 20 марта 2019

На самом деле вам нужен только один указатель. Один из способов сделать это - выделить достаточно памяти для хранения всех значений, а затем иметь функции, которые отображают значения x / y в массиве в соответствующее место в памяти. Предположим, что мы хотим, чтобы они были размерами и нашей переменной массива:

int dimX = 10, dimY = 5;
int *array;

Вы можете установить значение следующим образом:

void arraySet(int value, int x, int y) {
    array[x + dimX * y] = value;
}

И получить значение таким образом:

int arrayGet(int x, int y) {
    return array[x + dimX * y];
}

Заранее выделите память, например, в функции main:

array = malloc(sizeof(int)*dimX*dimY);

Используйте это так:

arraySet(123, 9, 3); // sets the value of [9, 3] to 123
printf("Memory at 9, 3 is %d\n", arrayGet(9, 3));
1 голос
/ 20 марта 2019

Вы можете смоделировать int a[2][3]; с помощью

  • одномерный массив и индексные вычисления:

    int* matrix = (int*) malloc(6 * sizeof(int));
    
    int get_matrix_2_3(int* matrix, int i, int j) { return matrix[3 * i + j]; }
    
  • 2-мерный массив:

    int** matrix = (int**) malloc(2 * sizeof(int*));
    for (int i = 0; i != 2; ++i) {
         matrix[i] = (int*) malloc(3 * sizeof(int));
    }
    
    matrix[1][2] = 42;
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...