C语言结构体指针程序bug排查及scanf参数使用疑问求助
C语言学生管理程序Bug修复与疑问解答
一、Bug定位与修正后的代码
主要Bug点
- 未初始化指针导致内存访问错误:定义
void *answer后未分配内存,直接解引用*answer传入scanf,会触发内存非法访问,导致程序异常终止。 realloc使用完全错误:将标准库函数realloc当作变量名,语法逻辑混乱,既没有正确扩容内存,还误用sizeof(int)代替sizeof(student)计算结构体内存。- 新增学生逻辑错误:循环从
j=0开始会覆盖原有学生数据;用%c读取姓名会捕获输入残留的换行符;读取年龄时未加&,不符合scanf的参数要求。 - 冗余类型定义:
typedef int size无实际意义,易造成变量类型混淆。
修正后的代码
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct student { char name[30]; int age; } student; int main(){ int i; int siz = 0; student *number; printf("Welcome\n\nEnter the number of student you want to evaluate: "); scanf("%d", &siz); printf("\n"); // 初始化内存并检查分配结果 number = malloc(siz * sizeof(student)); if (number == NULL) { printf("Memory allocation failed!\n"); return 1; } for(i = 0; i < siz; i++){ printf("Student name: "); scanf("%s", number[i].name); printf("Student age: "); scanf("%d", &number[i].age); printf("\n"); } printf("Do you want to add Students(Yes or No)? "); char answer[10]; // 用字符数组存储输入,避免指针问题 scanf("%s", answer); if(strcmp(answer, "Yes") == 0){ printf("\nGive the number of the additional students: "); int adsize; scanf("%d", &adsize); // 扩容内存:保留原有学生,加上新增数量 student *temp = realloc(number, (siz + adsize) * sizeof(student)); if (temp == NULL) { printf("Memory reallocation failed!\n"); free(number); return 1; } number = temp; // 从已有学生的下一个位置开始新增 for(int j = siz; j < siz + adsize; j++){ printf("Student name: "); scanf("%s", number[j].name); printf("Student age: "); scanf("%d", &number[j].age); printf("\n"); } siz += adsize; // 更新总学生数 } else { printf("\nEnd of program"); } // 释放申请的内存,避免泄漏 free(number); return 0; }
二、关于scanf中&number[i].age的疑问解答
number是student*类型的指针,但number[i]等价于*(number + i),它代表的是一个具体的student结构体变量,而非指针。age是这个结构体里的int类型普通成员,不是指针。scanf的%d格式要求传入int*类型的地址,用来存储输入的整数,所以必须用&取age的地址。- 而
number[i].name是字符数组,C语言中数组名会自动隐式转换为指向数组第一个元素的指针(char*类型),刚好符合scanf("%s")的参数要求,所以不需要加&。
内容的提问来源于stack exchange,提问作者JOHN BOURAS
相关产品推荐
相关产品推荐

