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

void函数指针问题致C程序输出-nan:海伦公式求三角形面积故障排查

问题分析与修复方案

核心问题点

  • 输入格式不匹配:你的scanf用了"%lf, %lf, %lf",要求输入必须是逗号分隔的三个数(比如3,4,5),但你只输入了单个5,导致变量b、c未被初始化,内存里是随机垃圾值,后续计算直接出错。
  • 指针参数冲突:调用heron(&result, a, b, c, &result)时,把同一个变量的地址同时传给semiPerimeter和result指针。函数执行时,先读取*semiPerimeter(原半周长),但随后会把计算结果覆盖到同一个地址,直接毁掉了半周长的值——虽然这不是这次-nan的直接原因,但属于严重逻辑漏洞。
  • 无合法性校验:海伦公式要求三边必须能构成三角形(任意两边之和大于第三边),且s*(s-a)*(s-b)*(s-c)必须非负,否则sqrt会返回nan。

修复后的完整代码

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

void CalculateSemiPerimeter(double a, double b, double c, double *result)
{
    *result = (a + b + c) / 2.0;    
}

// 优化:直接传半周长的值,避免指针冲突
void heron(double semiPerimeter, double a, double b, double c, double *result)
{
    double sub1 = semiPerimeter - a;
    double sub2 = semiPerimeter - b;
    double sub3 = semiPerimeter - c;
    *result = semiPerimeter * sub1 * sub2 * sub3;
}

int main()
{
    double a, b, c, semi, area_sq; 
    // 修改输入格式为空格分隔,更符合常规输入习惯
    printf("输入三角形三边(空格分隔):");
    // 校验输入是否有效
    if (scanf("%lf %lf %lf", &a, &b, &c) != 3) {
        printf("输入错误,请输入三个数字!\n");
        return 1;
    }

    // 校验三边是否能构成有效三角形
    if (a <= 0 || b <= 0 || c <= 0 || 
        a + b <= c || a + c <= b || b + c <= a) {
        printf("输入的三边无法构成有效三角形!\n");
        return 1;
    }

    CalculateSemiPerimeter(a, b, c, &semi);
    heron(semi, a, b, c, &area_sq);

    // 极端情况校验:防止乘积为负
    if (area_sq < 0) {
        printf("计算异常,乘积为负!\n");
        return 1;
    }

    double area = sqrt(area_sq);
    printf("三角形面积:%.2lf\n", area);
    return 0;
}

关键修复说明

  1. 输入逻辑修正:把scanf格式改为"%lf %lf %lf",支持空格分隔的输入(比如3 4 5),同时增加输入计数校验,确保三个边都被正确读取。
  2. 解决指针冲突:将heron函数的第一个参数从指针改为普通double类型,直接传递半周长的值,避免同一个内存地址被同时读写的问题,代码逻辑更清晰。
  3. 合法性校验:新增三边正数检查和三角形三边关系校验,从源头杜绝无效计算。
  4. 容错处理:增加对海伦公式乘积的非负校验,防止极端情况下sqrt返回nan。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:15:49