You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言二维数组元素下落异常:1向左偏移后下落问题排查

二维数组元素垂直下落异常的问题修复

在C语言中定义了20×20的二维数组,期望将值为1的元素垂直下落至数组底部,但运行代码后元素会先向左偏移再向下移动。预期逻辑是将当前位置设为0,下方位置设为1,重复此操作实现直落效果,核心逻辑在fallDown()函数中。

原代码

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#ifdef __unix__
# include <unistd.h>
#elif defined _WIN32
# include <windows.h>
#define sleep(x) Sleep(1000 * (x))
#endif

int sizeX = 20;
int sizeY = 20;

int grid[20][20] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

int fallDown(int grid[sizeX][sizeY], int x, int y){
    grid[x][y]=0;
    grid[x][y+1]=1;
}

int main(void){
    int neighbour_count[sizeX][sizeY];
    int x,y,iterations;

    for(iterations=0;iterations<500;iterations++){
        system("cls"); //Clear screen
        for(x=0;x<sizeX;x++){
            printf("\n");
            for(y=0;y<sizeY;y++){
                if(grid[x][y]==1){
                    printf("@");
                }
                else{
                    printf(" ");
                }
            }
        }
        for(y=0;y<sizeY;y++){
            for(x=0;x<sizeX;x++){
                if(grid[x][y] == 1){
                    fallDown(grid, x, y);
                }
            }
        }
        printf("\n");
        sleep(1);
    }
}

问题原因

  1. 坐标逻辑错误:根据打印逻辑,x代表行(每轮x循环输出一行),y代表列。垂直下落应该是行号增加(向下移动一行),但原代码中fallDown()函数修改的是y+1(列号增加,即向右移动),这是偏移的根本原因。
  2. 遍历顺序错误:主函数中从x=0到x=sizeX-1遍历行,当处理完(x,y)的元素后,将(x,y+1)设为1,后续循环会处理到这个新设置的1,导致同一轮内元素被多次移动,出现向左偏移的异常。
  3. 无边界判断:当元素处于最后一行时,x+1会超出数组范围,引发越界访问。

修复方案

  1. 修正fallDown()函数的坐标逻辑,改为修改行号x+1,并添加边界判断,确保元素不会越界。
  2. 调整遍历顺序:从下往上遍历行(x从sizeX-2到0),同一列内先处理下方的元素,避免同一轮循环中重复处理刚下落的元素。
  3. 修正遍历循环的顺序,确保每一轮只处理一次当前位置的元素。

修复后的代码

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#ifdef __unix__
# include <unistd.h>
#elif defined _WIN32
# include <windows.h>
#define sleep(x) Sleep(1000 * (x))
#endif

int sizeX = 20;
int sizeY = 20;

int grid[20][20] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};

// 修正下落逻辑,添加边界判断
void fallDown(int grid[sizeX][sizeY], int x, int y){
    // 确保不是最后一行,才能下落
    if(x < sizeX - 1){
        grid[x][y] = 0;
        grid[x + 1][y] = 1;
    }
}

int main(void){
    int x,y,iterations;

    for(iterations=0;iterations<500;iterations++){
        system("cls"); // 清屏
        for(x=0;x<sizeX;x++){
            printf("\n");
            for(y=0;y<sizeY;y++){
                if(grid[x][y]==1){
                    printf("@");
                }
                else{
                    printf(" ");
                }
            }
        }
        // 从下往上遍历行,避免同一轮重复处理
        for(y=0;y<sizeY;y++){
            for(x=sizeX - 2;x >= 0;x--){
                if(grid[x][y] == 1){
                    fallDown(grid, x, y);
                }
            }
        }
        printf("\n");
        sleep(1);
    }
    return 0;
}

关键修改点

  • 将fallDown()的返回类型改为void(原代码无返回值,不符合语法),并修改坐标为x+1,添加x < sizeX -1的边界判断。
  • 遍历行时从sizeX-2(倒数第二行)开始向上遍历到0,这样处理当前元素时,下方的位置还未被本轮循环修改,不会出现重复移动的问题。

内容的提问来源于stack exchange,提问作者Saw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 04:24:25