C语言结构体传参函数中float值重复打印问题排查
C语言中点计算程序重复打印、结果错误问题修复
问题复现
程序目标为接收用户输入的两个二维坐标,计算并返回两点中点,存在两个异常表现:
solveMidpoint函数内的调试打印语句重复输出2次point1.x的值,预期仅打印1次- 最终输出的中点坐标计算结果错误
原实现代码:
#include <stdio.h> #include <math.h> struct line{ struct point{ float x; float y; }point1, point2, midpoint; }; struct line solveMidpoint(struct line line1){ printf("%f\n", line1.point1.x); line1.midpoint.x = (line1.point1.x+line1.point2.x)/2; line1.midpoint.y = (line1.point1.y+line1.point2.y)/2; return line1; } int main(void){ struct line liner; printf("Enter x and y for point1: "); scanf("%f %f", &(liner.point1.x), &(liner.point1.y)); printf("Enter x and y for point2: "); scanf("%f %f", &(liner.point2.x), &(liner.point2.x)); printf("Midpoint: %f, %f", solveMidpoint(liner).midpoint.x, solveMidpoint(liner).midpoint.y); }
测试输入1 1、0 1时的输出:
Enter x and y for point1: 1 1 Enter x and y for point2: 0 1 1.000000 1.000000 Midpoint: 1.000000, 0.500000 [Program finished]
根因分析
两个独立bug共同导致了异常:
- 重复打印的直接原因:函数被调用了两次
最后一行printf的两个参数分别写了solveMidpoint(liner)调用,C语言中参数列表里的函数调用会按编译器实现定义的顺序逐一执行,因此solveMidpoint会完整运行2次,函数内部的打印语句自然会执行2次,该问题和float类型、结构体传参逻辑没有关系。 - 计算结果错误的直接原因:scanf参数写错
读取point2坐标的scanf语句中,两个入参都传了&(liner.point2.x),输入的第二个值会覆盖point2.x的内容,point2.y始终是未初始化的脏值,计算结果必然错误。测试输入0 1时,point2.x先被写入0,又被第二个输入值1覆盖,最终point2.x=1,point2.y为随机值,和实际输出结果完全吻合。
修复方案
- 修正
scanf读取point2坐标的参数,将第二个入参改为&(liner.point2.y) - 不要在
printf参数列表中重复调用计算函数,提前将函数返回值存入局部变量,仅执行一次计算逻辑
修复后的完整代码:
#include <stdio.h> #include <math.h> struct line{ struct point{ float x; float y; }point1, point2, midpoint; }; struct line solveMidpoint(struct line line1){ printf("%f\n", line1.point1.x); line1.midpoint.x = (line1.point1.x + line1.point2.x)/2; line1.midpoint.y = (line1.point1.y + line1.point2.y)/2; return line1; } int main(void){ struct line liner; printf("Enter x and y for point1: "); scanf("%f %f", &(liner.point1.x), &(liner.point1.y)); printf("Enter x and y for point2: "); scanf("%f %f", &(liner.point2.x), &(liner.point2.y)); struct line res = solveMidpoint(liner); printf("Midpoint: %f, %f", res.midpoint.x, res.midpoint.y); return 0; }
验证结果
相同测试输入下的输出:
Enter x and y for point1: 1 1 Enter x and y for point2: 0 1 1.000000 Midpoint: 0.500000, 1.000000
调试打印仅触发1次,中点计算结果符合数学预期。
内容的提问来源于stack exchange,提问作者Chizuru
相关产品推荐
相关产品推荐

