我对如何处理多维数组列有了一些了解。
下面是一些可编译的代码,大部分情况下都可以正常运行和执行。
我想使用我现在正在使用的逻辑,这对我来说似乎很合理(至少作为新手),但是我得到了非常令人讨厌的输出。
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
Here I initialize an empty array which you will see later in main:
void initializeGrid(int row, int col, int grid[][col])
{
int count = 1;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
grid[i][j] = count;
count++;
}
}
}
Here I print the initial case of the grid that will later be manipulated. This should be reused:
void printGrid(int row, int col, int grid[][col])
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
printf("%3d", grid[i][j]);
}
printf("\n");
}
}
Here I get the location of a specific value by its row and its column and I store it to the pointers r, and c:
bool findUnit(int unit, int row, int col, int grid[][col], int *r, int *c)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (grid[i][j] == unit)
{
*r = i;
*c = j;
return true;
}
}
}
return false;
}
Here I shift up using very elementary array mechanics and I felt so confident about it until seeing my output:
bool shiftUp(int unit, int row, int col, int grid[][col])
{
int r = 0;
int c = 0;
if (findUnit(unit, row, col, grid, &r, &c))
{
int i;
int temp = grid[0][c];
for (i = 1; i <= row; i++)
{
grid[i - 1][c] = grid[i][c];
}
grid[r][c] = temp;
return true;
}
return false;
}
Here I run the shift up command or I quit. Assume that run can make array move in other directions as well. It does not work for any direction yet, but I assume if I can fix one, I can fix all:
bool run(char cmd[10], int row, int col, int grid[][col])
{
int unit = 0;
printf("$: ");
scanf(" %s %d", cmd, &unit);
if (strcmp(cmd, "up") == 0)
{
shiftUp(unit, row, col, grid);
return true;
}
if (strcmp(cmd, "quit") == 0)
{
return false;
}
return false;
}
Here I execute the code:
int main()
{
int row = 4;
int col = 4;
int grid[row][col];
char cmd[32];
initializeGrid(row, col, grid);
printGrid(row, col, grid);
while (run(cmd, row, col, grid))
{
printGrid(row, col, grid);
}
return 0;
}
这都是一个文件。这也是我得到的令人不安的输出和预期的输出。
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
$: up 9
5 2 3 4
9 6 7 8
1 10 11 12
1347447432 14 15 16
$: quit
^C
请注意,即使我输入 quit,它也不会退出。
预期输出应该类似于(在较小的网格中,即 3x3):
1 2 3 1 5 3
4 5 6 --(up 5)--> 4 8 6
7 8 9 7 2 9
最佳答案
在这部分
for (i = 1; i <= row; i++)
{
grid[i - 1][c] = grid[i][c];
}
当i == row
时,grid[i][c]
出现越界错误。
在 C 语言中,数组索引从 0
开始,
当有这样的数组时
Type array[n];
可用的最大索引为n-1
。
举个例子,
您可以使用一维数组而不是二维数组来简化该过程。
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
//When there is no strlwr
#ifndef STRLWR
#include <ctype.h>
char *strlwr(char *s){
for(char *p = s; *p; ++p)
*p = tolower((unsigned char)*p);
return s;
}
#endif
static inline void clear_input_buff(void){
while(getchar() != '\n');
}
typedef enum {
QUIT, UP, DOWN, LEFT, RIGHT
} Command;
Command getCommand(const char *prompt){
while(true){
char cmd[8] = "";
fputs(prompt, stdout);fflush(stdout);
scanf("%7s", cmd);
strlwr(cmd);
if(!strcmp(cmd, "quit"))
return QUIT;
else if(!strcmp(cmd, "up"))
return UP;
else if(!strcmp(cmd, "down"))
return DOWN;
else if(!strcmp(cmd, "left"))
return LEFT;
else if(!strcmp(cmd, "right"))
return RIGHT;
printf(
"invalid input for command\n"
"input again\n"
);
clear_input_buff();
}
}
bool findUnit(int unit, int row, int col, int grid[], int *r, int *c){
for(*r = 0; *r < row; ++*r)
for(*c = 0; *c < col; ++*c)
if(*grid++ == unit)
return true;
return false;
}
void moveHelper(int n, int array[], Command dir, int distance){
int temp;
int last = (n-1) * distance;
if(dir == LEFT){
temp = array[0];
for(int i = distance; i <= last; i += distance){
array[i - distance] = array[i];
}
array[last] = temp;
} else if(dir == RIGHT){
temp = array[last];
for(int i = last; i > 0; i -= distance)
array[i] = array[i - distance];
array[0] = temp;
}
}
bool move(int unit, int row, int col, int grid[], Command cmd){
int r, c;
if(findUnit(unit, row, col, grid, &r, &c)){
switch(cmd){
case UP:
case DOWN:
cmd = (cmd == UP) ? LEFT : RIGHT;
moveHelper(row, &grid[c ], cmd, col);
break;
case LEFT:
case RIGHT:
moveHelper(col, &grid[r * col], cmd, 1);//1: 1 element
break;
}
return true;
}
printf("Can't found [%d]. So you can't move.\n", unit);
return false;
}
bool run(int row, int col, int grid[]){
Command cmd;
while((cmd = getCommand("$: ")) != QUIT){
int unit = 0;
if(scanf("%d", &unit) != 1){//get operand as unit
printf("invalid input for unit.\n");
clear_input_buff();
continue;
}
return move(unit, row, col, grid, cmd);
}
return false;
}
void initializeGrid(int n, int grid[n]){
int value = 1;
while(n--)
*grid++ = value++;
}
void printGrid(int row, int col, int *grid, int width){
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++)
printf("[%*d]", width, *grid++);
putchar('\n');
}
}
static inline int width(int value){
return snprintf(NULL, 0, "%d", value);
}
int main(void){
int row = 4, col = 4;
int n = row * col;//number of elements
int grid[n];
initializeGrid(n, grid);
int w = width(grid[n-1]);//width of max value
printGrid(row, col, grid, w);
while(run(row, col, grid)){
printGrid(row, col, grid, w);
}
return 0;
}
<小时/>
执行示例:
[ 1][ 2][ 3][ 4]
[ 5][ 6][ 7][ 8]
[ 9][10][11][12]
[13][14][15][16]
$: up 9
[ 5][ 2][ 3][ 4]
[ 9][ 6][ 7][ 8]
[13][10][11][12]
[ 1][14][15][16]
$: right 11
[ 5][ 2][ 3][ 4]
[ 9][ 6][ 7][ 8]
[12][13][10][11]
[ 1][14][15][16]
$: down 15
[ 5][ 2][15][ 4]
[ 9][ 6][ 3][ 8]
[12][13][ 7][11]
[ 1][14][10][16]
$: left 15
[ 2][15][ 4][ 5]
[ 9][ 6][ 3][ 8]
[12][13][ 7][11]
[ 1][14][10][16]
$: quit
关于c - 多维列移位中的数组索引错误(使用指针),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46555479/