Как вы делаете арифметику Pointer c с многомерными массивами в C? - PullRequest
1 голос
/ 16 апреля 2020

Как бы я использовал указатели в многомерном массиве? В каком направлении я бы заменил то, что я сделал, на арифметику указателя c? Я определил мой ptr как * местоположение. Я думаю, что мне нужно внести это изменение, потому что я получаю ошибки сегментации, когда totalHops> 400. Таким образом, явное изменение x, y, z каждый раз должно вызывать эту ошибку. Контекст: я двигаю частицу в трехмерном пространстве L на L на L. У меня есть генератор случайных чисел, чтобы определить, движется ли частица влево, вправо, вверх, вниз, назад или вперед при каждом случайном перемещении частицы в определенном месте. (Обратите внимание, что я разработал систему для периодических c граничных условий).

const int L = 10;
int N = L*L*L;
const int totalHops = 200; 
int sites[L][L][L] = {};
int x = 0, y = 0, z = 0;
int tracker[N] = {};
int *location;
location = &sites[0][0][0];
for (int i = 1; i <= totalHops; i++) // the random walk //
    {
        int direction = randomInt(6); // six possible directions to move //
        // along x //
        if (direction == 0) { // move in negative direction //
            x -= 1;
            if (x == -1)
            {
                x = L-1;
            }
        }
        if (direction == 1) { // move in positive direction //
            x +=1;
            if (x == L) 
            {
                x = 0;
            }
        }
        // along y //
        if (direction == 2) { // move in negative direction //
            y -= 1;
            if (y == -1)
            {
                y = L-1;
            }
        }
        if (direction == 3) { // move in positive direction //
            y +=1;
            if (y == L) 
            {
                y = 0;
            }
        }
        // along z //
        if (direction == 4) { // move in negative direction //
            z -= 1;
            if (z == -1)
            {
                z = L-1;
            }
        }
        if (direction == 5) { // move in positive direction //
            z +=1;
            if (z == L) 
            {
                z = 0;
            }
        }
    tracker[i] = sites[x][y][z]; }

Большое спасибо за вашу помощь заранее.

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Имейте в виду, что, хотя C поддерживает нотации массивов, такие как 2D, 3D, ..., nD массивы, чтобы сделать работу с ними более естественной с точки зрения читаемости человеком. Но в памяти массивы фактически создаются как единый блок непрерывной памяти. Например, ваш массив:

const int L = 10;
...
int sites[L][L][L] = {0}; //(using {0} is an idiomatic way to init. arrays to all 0

организован в памяти как 10 * 10 * 10 последовательных (int) секций памяти, начиная с ячейки памяти, на которую указывает sites.

* 1007. *

Из-за этого факта математика указателя становится довольно простой:

*(sites + 0)   is equivalent to sites[0][0][0]
*(sites + 1)   is equivalent to sites[0][0][1]
*(sites + 2)   is equivalent to sites[0][0][2]
...
*(sites + 10)  is equivalent to sites[0][1][0]
...
*(sites + 100) is equivalent to sites[1][0][0]
...
*(sites + 998) is equivalent to sites[9][9][8]
*(sites + 999) is equivalent to sites[9][9][9]

Схема между обозначением указателя и обозначением массива становится очень очевидной, так как число, добавляемое в начало массива, коррелирует с расположение индексов в нотации массива.

На основе этой базовой формы c вы можете получить способ использования математических указателей для представления многомерных массивов, в вашем случае затем, используя int *location;, инициализированный для начало sites может использоваться для отслеживания (или определения) того, какой элемент массива 3D просматривается или изменяется.

Это может хорошо применяться к вашей конкретной проблеме c в этом отслеживании totalHops, и принятие решений на основе значений вне диапазона 0 - 9 в любом направлении для x,y,z может оказаться более сложным, чем принятие решения на основе обозначений, таких как *(sites + 400) (согласно вашему описанию в OP).

0 голосов
/ 16 апреля 2020

Итак, в заключение моей ошибки сегментации, я просто использовал неверную переменную в моем массиве трекеров. Но, тем не менее, будучи довольно новым программистом, было приятно побеседовать с ними и поблагодарить вас за всю вашу помощь! Я рад, что исследовал как использование индексации, так и указателей.

Массив должен быть

int tracker[totalHops] = {};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...