C 多维列移位中的数组索引错误(正在使用指针)
我对如何处理多维数组列有了一些见解 下面是一些可编译的代码,在大多数情况下运行并执行正常 我想使用我现在正在使用的逻辑,这对我来说似乎很合理(至少作为一个新手),但是我得到了非常糟糕的输出C 多维列移位中的数组索引错误(正在使用指针),c,arrays,algorithm,pointers,multidimensional-array,C,Arrays,Algorithm,Pointers,Multidimensional Array,我对如何处理多维数组列有了一些见解 下面是一些可编译的代码,在大多数情况下运行并执行正常 我想使用我现在正在使用的逻辑,这对我来说似乎很合理(至少作为一个新手),但是我得到了非常糟糕的输出 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> 我在这里执行代码: 这都是一个文件。这也是我得到的令人不安的输出和预期的输出 1 2 3
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
我在这里执行代码:
这都是一个文件。这也是我得到的令人不安的输出和预期的输出
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):
在C语言中,数组的索引范围是0…数组-1中的条目数。所以这个代码块:
for (i = 1; i <= row; i++)
{
grid[i - 1][c] = grid[i][c];
}
for(i=1;irow-1
)来自位于数组末尾的某个未知值。这是未定义的行为,可能导致seg故障事件 在这一部分
for (i = 1; i <= row; i++)
{
grid[i - 1][c] = grid[i][c];
}
可用的最大索引是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;
}
对于那些仍然认为C++是C超集的人,请把目光投向这个代码,在你的天真中哭泣。你在说什么?我很天真?我知道我是,这就是我问问题的原因。for(I=1;I关于:for(I=1;I调用任何scanf()
family of functions:1)时,始终检查返回值(而不是参数值)以确保操作成功。2)使用“%s”输入格式说明符时,始终包含一个比输入缓冲区长度小一的MAX CHARACTERS修饰符,因为函数将向输入追加一个NUL字节
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;
}
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
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];
}
for (i = 1; i <= row; i++)
{
grid[i - 1][c] = grid[i][c];
}
Type array[n];
#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