Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 多维列移位中的数组索引错误(正在使用指针)_C_Arrays_Algorithm_Pointers_Multidimensional Array - Fatal编程技术网

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;i
row-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