C语言函数调用后变量值被清零/覆盖的问题排查求助
解决C程序中变量值被意外覆盖/清空的问题
看起来你遇到了C程序里变量被意外覆盖的典型问题,咱们一步步拆解原因并修复:
问题根源分析
你的代码里有几个关键错误,直接导致了变量值被破坏:
字符数组定义与字符串打印不匹配
你定义了长度为1的字符数组(比如char sexo[1];、char diabetes[1];),但C语言中printf("%s", ...)要求传入的是以'\0'结尾的字符串。长度为1的数组只能存一个字符,没有空间放结束符,这会导致printf越界读取内存,甚至覆盖相邻变量的内容(比如peso的值被改成0,就是因为相邻的字符数组越界写入了'\0')。resp函数的未定义行为
你的resp函数声明返回char,但函数内部没有return语句,这属于未定义行为——程序会返回栈上的随机值,甚至破坏栈结构,间接导致其他变量异常。scanf的格式符使用错误
在resp函数里用scanf("%s", &tempo[0]);读取单个字符,但%s是用来读字符串的,它会自动在末尾添加'\0'。而你的tempo数组只有1个字节的空间,写入'\0'就会越界,直接覆盖栈上的其他变量(比如peso、diabetes的内存)。
修复后的代码
下面是修正后的完整代码,我会标注关键修改点:
#include <stdio.h> #include <stdlib.h> // 修改参数为char*,用于接收单个字符的地址 char resp(char *tempo, char op_1, char op_2); int main(void){ // 把长度为1的字符数组改成单个char变量 char sexo; int edad; int peso; char diabetes; char hipert; printf("Calculadora de factor de riesgo - COVID19.\n"); printf("Ingresa los datos que se te pidan.\n"); printf("Ingresa tu sexo (m/f): "); sexo = resp(&sexo, 'm', 'f'); printf("\nIngresa tu edad (mayor o igual a 18): "); scanf("%d", &edad); while(edad<18){ printf("\nRespuesta no aceptada. Intenta de nuevo. "); scanf("%d", &edad); } printf("\nIngresa tu estado de peso (bajo (1), normal (2), sobrepeso (3), obesidad (4)): "); scanf("%d", &peso); while(peso != 1 && peso != 2 && peso != 3 && peso != 4){ printf("\nRespuesta no aceptada. Intenta de nuevo. "); scanf("%d", &peso); } // 读取整数后,缓冲区会留下换行符,用getchar()清理,避免影响后续的字符读取 getchar(); printf("\nPadeces diabetes? (s/n): "); diabetes = resp(&diabetes, 's', 'n'); printf("\nPadeces hipertension? (s/n): "); hipert = resp(&hipert, 's', 'n'); // 用%c打印单个字符,而不是%s printf("\nDatos ingresados:\n"); printf("Sexo: %c\n", sexo); printf("Edad: %d\n", edad); printf("Peso: %d\n", peso); printf("Diabetes: %c\n", diabetes); printf("Hipertension: %c\n", hipert); return 0; } char resp(char *tempo, char op_1, char op_2){ // 用%c读取单个字符,避免字符串越界问题 scanf("%c", tempo); while (*tempo != op_1 && *tempo != op_2){ printf("\nRespuesta no aceptada. Intenta de nuevo. "); scanf("%c", tempo); } // 返回正确的字符值 return *tempo; }
关键修改说明
- 字符变量替换字符数组:把
char sexo[1]这类定义改成char sexo,用%c格式符打印,避免字符串结束符的问题。 - 修复resp函数:添加
return语句返回正确的字符,同时用%c读取单个字符,防止越界写入。 - 清理输入缓冲区:在读取完整数后,用
getchar()清除缓冲区里的换行符,避免后续的scanf("%c")直接读取到换行符导致逻辑错误。
内容的提问来源于stack exchange,提问作者Rodolfo Barrientos Acosta
相关产品推荐
相关产品推荐

