I am working on a project in which I need to check neighboring cells of a specific cell in a dynamically allocated 2D char
array. Basically, If certain neighboring cells are 'X'
for example, then the current cell you are on becomes '-'
. To allocate the 2D array, I used a single malloc
call:
char *array = (char *)malloc(numRows * numCols * sizeof(char));
To access an element while using a double for loop, I use this:
for (int i = 0; i <= getNumRows(); i++)
{
for (int j = 0; j < getNumCols(); j++)
{
printf("%c ", **(array + i * getNumCols() + j));
}
printf("\n");
}
How would I access and view the neighboring cells of the current element?
The code posted to display the matrix has problems:
i == getNumRows()
andprintf
argument should use a single *
dereferencing operatorHere is a modified version:
for (int i = 0; i < getNumRows(); i++) {
for (int j = 0; j < getNumCols(); j++) {
printf("%c ", *(array + i * getNumCols() + j));
}
printf("\n");
}
Which can also be rewritten to avoid recomputing the matrix sizes repeatedly:
for (int i = 0, row = getNumRows(), cols = getNumCols(); i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%c ", array[i * cols + j]);
}
printf("\n");
}
Accessing the neighbouring cells of cell r,c
depends on how you deal with boundaries:
r
and/or c
are on a boundary to produce between 3 and 8 neighbours.r+/-1 % rows
and c+/-1 % cols
to always produce 8 neighbours.To simplify the first case, you can allocate the matrix with 2 extra columns and rows, with char *array = malloc(sizeof(char) * (numRows + 1) * (numCols + 2));
and use the inner space (active area) this way:
for (int i = 1; i <= getNumRows(); i++) {
for (int j = 1; j <= getNumCols(); j++) {
printf("%c ", *(array + i * getNumCols() + j));
}
printf("\n");
}
If you initalize the boundary rows and columns in the matrix as ' '
, you can always access the 8 cells at r+/-1, c+/-1
and check for 'X'
without special casing the boundary rows of the active part.
Accessing these neighbouring cells can be done according to the implementation choices:
int rows = getNumRows(), cols = getNumCols();
char *cellp = array + r * cols + c;
// using extra rows and columns
char top_1 = cellp[-cols - 1];
char top_2 = cellp[-cols];
char top_3 = cellp[-cols + 1];
char mid_1 = cellp[-1];
char mid_2 = cellp[+1];
char bot_1 = cellp[+cols - 1];
char bot_2 = cellp[+cols];
char bot_3 = cellp[+cols + 1];
// using torus-like wrapping
char top_1 = array[(r + rows - 1) % rows * cols + (c + cols - 1) % cols];
char top_2 = array[(r + rows - 1) % rows * cols + c];
char top_3 = array[(r + rows - 1) % rows * cols + (c + 1) % cols];
char mid_1 = array[r * cols + (c + cols - 1) % cols];
char mid_2 = array[r * cols + (c + 1)];
char bot_1 = array[(r + 1) % rows * cols + (c + cols - 1) % cols];
char bot_2 = array[(r + 1) % rows * cols + c];
char bot_3 = array[(r + 1) % rows * cols + (c + 1) % cols];
// using tests
char top_1 = (r == 0 || c == 0 ) ? 0 : cellp[-cols - 1];
char top_2 = (r == 0 ) ? 0 : cellp[-cols];
char top_3 = (r == 0 || c == cols - 1) ? 0 : cellp[-cols + 1];
char mid_1 = ( c == 0 ) ? 0 : cellp[-1];
char mid_2 = ( c == cols - 1) ? 0 : cellp[+1];
char bot_1 = (r == rows - 1 || c == 0 ) ? 0 : cellp[+cols - 1];
char bot_2 = (r == rows - 1 ) ? 0 : cellp[+cols];
char bot_3 = (r == rows - 1 || c == cols - 1) ? 0 : cellp[+cols + 1];