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

程序崩溃问题排查:疑与sort函数中第二个for循环相关

程序崩溃问题排查与修复方案

兄弟,我一眼就揪出了导致你程序崩溃的核心问题,还有几个细节也得调整下,咱们一步步来解决:

核心崩溃原因:格式符类型不匹配

你在sort函数的第二个printf语句里犯了一个低级但致命的错误:

printf("Total Homework Score: %d\nTotal Exam Score: %d\nClass Percentage: %f Grade: %s", s[i].totalhw, s[i].totalex, s[i].classperc, s[i].grade);

这里的%s是用来打印**字符串(char数组)**的格式符,但s[i].grade是单个char类型变量!用%s会让程序从grade的内存地址开始,一直读取数据直到遇到\0,直接触发非法内存访问,导致程序崩溃。

把%s改成%c就能解决这个崩溃问题:

printf("Total Homework Score: %d\nTotal Exam Score: %d\nClass Percentage: %f Grade: %c", s[i].totalhw, s[i].totalex, s[i].classperc, s[i].grade);

次要问题:排序循环的硬编码值

你的sort函数里的排序循环用了固定的SIZE而不是传入的参数n:

for (int i = 0; i < SIZE - 1; i++) {
    for (int j = i + 1; j< SIZE; j++) {

虽然当前main函数里传入的n等于SIZE,但如果后续你修改了数组大小或者传入不同的n,这会导致数组越界问题。改成用参数n来控制循环范围更健壮:

for (int i = 0; i < n - 1; i++) {
    for (int j = i + 1; j < n; j++) {

额外优化:符合C标准的main函数

C标准规定main函数的返回类型应该是int,而不是void。虽然有些编译器允许void main(),但改成标准写法更规范:

int main() {
    // 现有代码...
    system("PAUSE");
    return 0;
}

修复后的完整代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 5

struct student {
    char name[20];
    int hw1, hw2, hw3, ex1, ex2, totalhw, totalex;
    float classperc;
    char grade;
};

void student_info(struct student s[], int n, int *classex1, int *classex2, int *a, int *b, int *c, int *d, int *f) {
    for (int i = 0; i < n; i++) {
        printf("\n\nPlease enter the student's name:\n");
        gets_s(s[i].name, 20);
        printf("\nPlease enter the student's homework grades:\n");
        scanf("%d %d %d", &(s[i].hw1), &(s[i].hw2), &(s[i].hw3));
        printf("\nPlease enter the student's exam scores:\n");
        scanf("%d %d", &(s[i].ex1), &(s[i].ex2));
        getchar();
        s[i].totalhw = s[i].hw1 + s[i].hw2 + s[i].hw3;
        s[i].totalex = s[i].ex1 + s[i].ex2;
        *classex1 += s[i].ex1;
        *classex2 += s[i].ex2;
        s[i].classperc = ((float)s[i].totalhw / 1.875) + ((float)s[i].totalex / 3.333);
        if (s[i].classperc >= 90) {
            *a = *a + 1;
            s[i].grade = 'A';
        } else if (s[i].classperc >= 80) {
            *b = *b + 1;
            s[i].grade = 'B';
        } else if (s[i].classperc >= 70) {
            *c = *c + 1;
            s[i].grade = 'C';
        } else if (s[i].classperc >= 60) {
            *d = *d + 1;
            s[i].grade = 'D';
        } else {
            *f = *f + 1;
            s[i].grade = 'F';
        }
    }
}

void sort(struct student s[], int n) {
    struct student temp;
    // 修改:用n代替SIZE控制循环范围
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            if (strcmp(s[i].name, s[j].name) > 0) {
                temp = s[i];
                s[i] = s[j];
                s[j] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("\nStudent: %s\nThe Three Homework Scores: %d %d %d\nThe Two Exam Scores: %d %d\n", s[i].name, s[i].hw1, s[i].hw2, s[i].hw3, s[i].ex1, s[i].ex2);
        // 修改:把%s改成%c打印char类型的grade
        printf("Total Homework Score: %d\nTotal Exam Score: %d\nClass Percentage: %f Grade: %c", s[i].totalhw, s[i].totalex, s[i].classperc, s[i].grade);
    }
}

void avg_exams(int classex1, int classex2, float *avgex1, float *avgex2) {
    *avgex1 = classex1 / (float)5;
    *avgex2 = classex2 / (float)5;
}

void print_classinfo(float avgex1, float avgex2, int a, int b, int c, int d, int f) {
    printf("\n\nThe Average Exam Score for Exam 1 is: %0.2f\nThe Average Exam Score for Exam 2 is: %0.2f\n", avgex1, avgex2);
    printf("There were %d A's, %d B's, %d C's, %d D's, %d F's in the class overall\n\n", a, b, c, d, f);
}

// 修改:改成标准的int main()
int main() {
    struct student s[SIZE];
    int a, b, c, d, f , classex1, classex2;
    a = b = c = d = f = 0;
    classex1 = classex2 = 0;
    float classperc, avgex1, avgex2;
    student_info( s, SIZE, &classex1, &classex2, &a, &b, &c, &d, &f);
    sort(s, SIZE);
    avg_exams(classex1, classex2, &avgex1, &avgex2);
    print_classinfo(avgex1, avgex2, a, b, c, d, f);
    system("PAUSE");
    return 0;
}

把这些修改做完后,你的程序应该就能正常运行,不会再崩溃了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:14:34