/* 温度监测：输入整数摄氏温度，判断等级，并累计统计。
 * 输入 -1：显示报告并退出；输入 -2：显示报告后继续检测。
 */
#include <stdio.h>
#include <stdlib.h>

/* 函数声明：指针参数用于传入温度变量的地址。 */
const char *check(int *a);
void inputoutput(int *temperature);
void continue_or_break(void);
void error_feedback(int *a);

/* 全局统计变量：多次调用函数时保留累计结果。 */
int total_tests = 0; // 所有有效温度的检测次数，不包含控制指令
int normal_count = 0;
int warning_count = 0;
int critical_count = 0;
int low_count = 0;
int high_count = 0;
int max_temperature = -999;     // 初值低于有效温度下限，便于首次更新最大值
int min_temperature = 999;      // 初值高于有效温度上限，便于首次更新最小值
int total_temperature = 0;      // 累加所有有效温度
double average_temperature = 0; // 平均温度，使用浮点数保存小数部分

int main(void)
{
    continue_or_break(); // 进入输入循环，由特殊输入控制查看报告或退出
    return 0;
}

/* *a 表示读取指针指向的温度值；返回值是等级字符串的地址。
 * const char * 表示不能通过返回的指针修改字符串内容。
 */
const char *check(int *a)
{
    if (*a >= 0 && *a < 70) // 0～69：正常
    {
        normal_count++; // 对应等级次数加一
        total_tests++;
        total_temperature += *a;  // 累加温度，用于计算平均值
        if (*a > max_temperature) // 当前温度更高时，更新最高温度
        {
            max_temperature = *a;
        }
        if (*a < min_temperature) // 当前温度更低时，更新最低温度
        {
            min_temperature = *a;
        }
        return "NORMAL";
    }
    else if (*a >= 999 || *a <= -999) // 拒绝 -999 及以下、999 及以上的温度，不更新统计
    {
        return "温度错误";
    }
    else if (*a >= 70 && *a < 90) // 70～89：警告，同时更新累计统计
    {
        warning_count++;
        total_tests++;
        total_temperature += *a;
        if (*a > max_temperature)
        {
            max_temperature = *a;
        }
        if (*a < min_temperature)
        {
            min_temperature = *a;
        }
        return "WARNING";
    }
    else if (*a >= 90 && *a <= 150) // 90～150：严重警告，同时更新累计统计
    {
        critical_count++;
        total_tests++;
        total_temperature += *a;
        if (*a > max_temperature)
        {
            max_temperature = *a;
        }
        if (*a < min_temperature)
        {
            min_temperature = *a;
        }
        return "CRITICAL";
    }
    else if (*a < 0) // -998～-3：低温；-1、-2 已在输入循环中作为控制指令处理
    {
        low_count++; // 低温次数加一
        total_tests++;
        total_temperature += *a;
        if (*a > max_temperature)
        {
            max_temperature = *a;
        }
        if (*a < min_temperature)
        {
            min_temperature = *a;
        }
        return "LOW";
    }
    else // 151～998：超高温，同时更新累计统计
    {
        high_count++;
        total_tests++;
        total_temperature += *a;
        if (*a > max_temperature)
        {
            max_temperature = *a;
        }
        if (*a < min_temperature)
        {
            min_temperature = *a;
        }
        return "TOO HIGH";
    }
}

/* 判断温度并更新有效记录的统计；输出等级标识或中文错误提示。 */
void inputoutput(int *temperature)
{
    const char *result = check(temperature);
    printf("%s\n", result);
}

/* 持续读取温度，处理退出、查看报告和普通检测三种情况。 */
void continue_or_break(void)
{
    int temperature;

    while (1) // 不限定循环次数，通过 return 或 break 结束
    {
        printf("请输入温度（摄氏度）：");
        if (scanf("%d", &temperature) != 1) // & 取地址；成功读入一个整数时返回 1
        {
            return; // 输入无法转换为整数或到达输入末尾时，结束函数
        }

        if (temperature == -1) // 查看统计并结束检测
        {
            error_feedback(&temperature);
            break;
        }
        if (temperature == -2) // 查看统计，但不清空已累计的数据
        {
            printf("\n");
            error_feedback(&temperature);
            continue; // 跳过本轮剩余代码，开始下一轮输入
        }
        inputoutput(&temperature); // 普通输入交给等级判断函数处理
    }
}

/* 输出累计统计报告；a 指向触发报告的输入值。 */
void error_feedback(int *a)
{
    if (total_tests > 0)
    {
        // 强制转换为 double，避免整数除法丢失小数。
        // 所有有效等级（包括 LOW）均已累计温度，并更新最高、最低温度。
        // 控制指令和超出范围的温度不参与平均值计算。
        average_temperature = (double)total_temperature / total_tests;
        printf("===== 监测统计报告 =====\n总检测次数：%d\n正常次数：%d\n警告次数：%d\n严重警告次数：%d\n低温次数：%d\n超高温次数：%d\n最高温度：%d℃\n最低温度：%d℃\n平均温度：%1.1lf℃\n========================\n", total_tests, normal_count, warning_count, critical_count, low_count, high_count, max_temperature, min_temperature, average_temperature);
    }
    else if (*a == -2) // 尚无检测记录，并且要求查看报告后继续
    {
        *a = 0; // 修改原温度变量，使下面的递归调用进入最后的 else 分支
        printf("检测继续");
        error_feedback(a); // 再调用本函数，输出检测次数为零的报告
    }
    else
    {
        average_temperature = 0; // 无记录时只输出次数，避免除以零
        printf("===== 监测统计报告 =====\n总检测次数：%d\n========================\n", total_tests);
    }
}
