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

为何井字棋程序调用最后draw_board函数后提前终止?

问题分析与修复

你的程序在最后一次调用draw_board后直接终止,核心原因是数组越界访问触发的未定义行为,具体问题出在moves数组的定义与使用逻辑上:

核心问题:数组越界破坏内存

  1. moves数组长度不足:你定义的int moves[7] = {0,8,6,3,2,4,1};仅包含7个元素,有效索引范围是0~6,但后续代码存在两处越界访问:
    • 循环for(int i = 0; i < 8; i++)会在i=7时访问moves[7],超出数组边界;
    • 最后一行board[moves[8]] = 'x';直接访问moves[8],越界程度更严重。

数组越界会直接破坏栈内存中的关键数据(比如函数返回地址、栈帧结构),导致程序执行到越界代码后直接崩溃,后续的printf("End\n")和main中的printf("\n Done!!!\n")完全没有执行机会。

修复步骤

  1. 扩展moves数组长度:井字棋共有9个格子,需要9步走满,将moves数组定义为包含9个元素的数组,比如:

    int moves[9] = {0,8,6,3,2,4,1,5,7};
    

    确保moves[0]到moves[8]均为有效数组元素。

  2. 保留原有循环逻辑:原循环执行8次(i<8)对应前8步,最后一步单独处理的逻辑是合理的,调整数组长度后即可避免越界。

额外优化建议

你的wait函数使用clock()计算等待时间,clock()统计的是程序占用的CPU时间而非实际墙上时间,若程序被系统调度暂停,实际等待时长会超出预期。可改用跨平台的精确延迟方案:

#include <windows.h> // Windows平台需要添加该头文件

void wait(float seconds) {
    #ifdef _WIN32
        Sleep((DWORD)(seconds * 1000));
    #else
        struct timespec ts;
        ts.tv_sec = (time_t)seconds;
        ts.tv_nsec = (long)((seconds - ts.tv_sec) * 1e9);
        nanosleep(&ts, NULL);
    #endif
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 19:42:45