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

C语言FCFS进程调度程序中For循环仅执行一次的问题

问题排查与修复方案

首先不用致歉,刚接触C语言遇到这类问题太正常了,咱们一步步来解决~

循环仅执行一次的核心原因:全局变量i被意外篡改

你代码里的i是全局变量,这就导致在smallestentry()函数里的循环会直接修改这个全局的i值,进而破坏calculate()里for循环的计数器逻辑:

  1. 当calculate()里的for循环第一次执行时(i=1),会调用smallestentry()
  2. 在smallestentry()的for(i=0; i<processes; i++)循环结束后,全局i的值会变成processes(循环终止条件)
  3. 回到calculate()的for循环,执行i++,此时i变成processes+1,直接不满足i < processes的条件,循环就此终止

除此之外,还有几个小逻辑问题需要调整,比如等待时间的计算边界、输出表头的重复问题等。

具体修复步骤

1. 把全局变量i改为局部变量

所有函数里的循环计数器i都单独声明为局部变量,避免全局变量的副作用:

  • 删除全局声明里的i
  • 在input()、changeline()、smallestentry()、calculate()里各自声明int i;

2. 修正smallestentry()的初始值逻辑

当第一个进程被处理后,at[0]会被设为999,为了避免极端情况,先找到第一个未被处理的进程作为初始最小值,再遍历找真正的最小到达时间:

void smallestentry() {
    int i;
    // 先找到第一个未被处理的进程作为初始最小值
    for(i = 0; i < processes; i++){
        if(at[i] != 999){
            smallest = at[i];
            position = i;
            break;
        }
    }
    // 再遍历找真正的最小值
    for(i = 0; i < processes; i++) {
        if(at[i] != 999 && smallest > at[i]) {
            smallest = at[i];
            position = i;
        }
    }
}

3. 修正输出表头的重复问题

changeline()里的表头AT\tBT\tWT\tTAT\tAT重复了AT,改成Original AT对应atperm存储的原始到达时间:

printf("Current AT\tBT\tWT\tTAT\tOriginal AT\n");

4. 调整calculate()里的初始化与等待时间逻辑

确保awt初始化为0,同时处理进程到达时间晚于当前总Burst时间的边界情况(避免等待时间为负数):

void calculate() {
    awt = 0; // 初始化平均等待时间为0
    smallestentry();
    wt[position] = 0;
    tat[position] = bt[position];
    atat = tat[position];
    int btt = bt[position];
    atperm[position] = at[position];
    changeline(position);
    
    int i;
    for (i = 1; i < processes; i++) {
        smallestentry();
        // 处理进程到达时间晚于当前总Burst时间的情况
        wt[position] = (btt >= at[position]) ? (btt - at[position]) : 0;
        btt += bt[position];
        awt += wt[position];
        tat[position] = wt[position] + bt[position];
        atat += tat[position];
        atperm[position] = at[position];
        changeline(position);
    }
    atat /= processes;
    awt /= processes;
    
    // 新增最终平均时间输出
    printf("平均等待时间: %.2f\n", awt);
    printf("平均周转时间: %.2f\n", atat);
}

修改后的完整代码

#include <stdio.h>
#include <stdlib.h>
/*
 * WT - 等待时间 (TAT - BT)
 * BT - 执行时间(Burst Time)
 * AT - 到达时间(Arrival Time)
 * TAT - 周转时间 (CT - AT)
 * AWT - 平均等待时间
 * ATAT - 平均周转时间
 */
int wt[10], bt[10], at[10], atperm[10], tat[10], processes, smallest, position;
float awt, atat;

void input() {
    printf("输入进程数量:\n");
    scanf("%d", &processes);
    int i;
    for (i = 0; i < processes; i++) {
        printf("输入进程%d的Burst时间:", i + 1);
        scanf("%d", &bt[i]);
        printf("输入进程%d的到达时间:", i + 1);
        scanf("%d", &at[i]);
    }
}

void changeline(int position) {
    at[position] = 999;
    printf("Current AT\tBT\tWT\tTAT\tOriginal AT\n");
    int i;
    for (i = 0; i < processes; i++) {
        printf("%d\t\t%d\t%d\t%d\t%d\n", at[i], bt[i], wt[i], tat[i], atperm[i]);
    }
    printf("----------------------------------------\n");
}

void smallestentry() {
    int i;
    // 找到第一个未被处理的进程作为初始值
    for(i = 0; i < processes; i++){
        if(at[i] != 999){
            smallest = at[i];
            position = i;
            break;
        }
    }
    // 遍历寻找最小到达时间的进程
    for (i = 0; i < processes; i++) {
        if(at[i] != 999 && smallest > at[i]) {
            smallest = at[i];
            position = i;
        }
    }
}

void calculate() {
    awt = 0;
    smallestentry();
    wt[position] = 0; // 第一个进程等待时间为0
    tat[position] = bt[position];
    atat = tat[position];
    int btt = bt[position];
    atperm[position] = at[position];
    changeline(position);
    
    int i;
    for (i = 1; i < processes; i++) {
        smallestentry();
        // 处理进程到达时间晚于当前总Burst时间的情况
        wt[position] = (btt >= at[position]) ? (btt - at[position]) : 0;
        btt += bt[position];
        awt += wt[position];
        tat[position] = wt[position] + bt[position];
        atat += tat[position];
        atperm[position] = at[position];
        changeline(position);
    }
    atat /= processes;
    awt /= processes;
    
    // 最后输出平均时间
    printf("平均等待时间: %.2f\n", awt);
    printf("平均周转时间: %.2f\n", atat);
}

int main() {
    printf("FCFS CPU调度算法\n");
    input();
    calculate();
    return 0;
}

额外说明

  • 新增了平均等待时间和周转时间的最终输出,方便查看结果
  • 优化了等待时间的计算逻辑,避免出现负数
  • 所有循环计数器都改为局部变量,彻底解决了全局变量导致的逻辑冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:44:58