物理实验数据处理代码
耗子本人作为苦逼的物理类专业学生,一想到开学做实验记录处理相关实验数据,花将近一天的时间来给只有1学分的普物实验写实验报告就欲哭无泪(>_<),所以心血来潮创作了这么一段代码,让AI帮忙修改了一下,虽然还并不是很完善,但想着到时候处理数据或许能派上用场。之后应该会逐渐改进的,或许会推出更多功能吧 ~

#include
#include
#include
const float G_TABLE[21] = { 0, 0, 0, 1.15, 1.46, 1.67, 1.82, 1.94, 2.03, 2.11, 2.18,
2.23, 2.29, 2.33, 2.37, 2.41, 2.44, 2.47, 2.50, 2.53, 2.56 };
typedef struct {
char name[20];
char units[5][10];
int unit_count;
char formula[100];
} PhysicalQuantity;
PhysicalQuantity basic_quantities[] = {
{"长度", {"m", "cm", "mm", "km", "μm"}, 5, "直接测量(刻度尺/游标卡尺);L = 末位置 - 初位置"},
{"质量", {"kg", "g", "mg", "t", "μg"}, 5, "直接测量(天平/电子秤);m = 总质量 - 容器质量"},
{"时间", {"s", "ms", "min", "h", "μs"}, 5, "直接测量(秒表/打点计时器);Δt = t末 - t初"},
{"电流", {"A", "mA", "μA", "kA"}, 4, "I = U/R(欧姆定律);直接测量(电流表串联)"},
{"热力学温度", {"K", "℃"}, 2, "T = t + 273.15(t为摄氏温度,单位℃);直接测量(温度计)"},
{"物质的量", {"mol", "mmol", "μmol"}, 3, "n = m/M(m为质量,M为摩尔质量);n = V/Vm(气体,Vm为摩尔体积)"}
};
PhysicalQuantity derived_quantities[] = {
{"速度", {"m/s", "km/h", "cm/s", "mm/s"}, 4, "v = Δs/Δt(Δs为位移,Δt为时间);v = s/t(匀速运动)"},
{"加速度", {"m/s²", "cm/s²", "mm/s²"}, 3, "a = (v末 - v初)/Δt;a = F/m(牛顿第二定律,F为合力)"},
{"电阻", {"Ω", "kΩ", "MΩ", "mΩ"}, 4, "R = U/I(欧姆定律);R = ρL/S(ρ为电阻率,L为长度,S为横截面积)"},
{"电压", {"V", "kV", "mV", "μV"}, 4, "U = IR(欧姆定律);U = W/Q(W为电能,Q为电荷量)"},
{"功率", {"W", "kW", "mW", "MW"}, 4, "P = W/t(W为功,t为时间);P = UI(电路功率,U为电压,I为电流)"},
{"密度", {"kg/m³", "g/cm³", "kg/L"}, 3, "ρ = m/V(m为质量,V为体积);ρ = ρ₀(1+αΔt)(温度修正,α为体胀系数)"},
{ "力", {"N", "kN", "mN"}, 3, "F = ma(牛顿第二定律);F = kx(胡克定律,k为劲度系数,x为形变量)" }
};
int show_category_menu();
int show_quantity_menu(PhysicalQuantity quantities[], int count, char* category_name);
char* show_unit_menu(PhysicalQuantity* pq);
int main() {
int category_choice;
int quantity_index;
char* selected_unit;
PhysicalQuantity* selected_pq;
int n;
float data[50], filtered_data[50];
float average = 0.0, filtered_avg = 0.0;
float sum_diff_sq = 0.0, filtered_sum_sq = 0.0;
float var_sample, filtered_var;
float std_sample, filtered_std;
float u_A, filtered_uA;
int filtered_n = 0;
int has_outlier = 0;
FILE* fp;
category_choice = show_category_menu();
if (category_choice == 1) {
quantity_index = show_quantity_menu(basic_quantities,
sizeof(basic_quantities) / sizeof(PhysicalQuantity),
"基本物理量");
selected_pq = &basic_quantities[quantity_index];
}
else {
quantity_index = show_quantity_menu(derived_quantities,
sizeof(derived_quantities) / sizeof(PhysicalQuantity),
"常用导出量");
selected_pq = &derived_quantities[quantity_index];
}
selected_unit = show_unit_menu(selected_pq);
printf("
=== 选中信息 ===
");
printf("物理量:%s
", selected_pq->name);
printf("单位:%s
", selected_unit);
printf("核心公式(实验参考):%s
", selected_pq->formula);
printf("
=== %s测量数据输入 ===
", selected_pq->name);
printf("请输入测量次数(n≥2,≤20):");
scanf("%d", &n);
if (n < 2 || n > 20) {
printf("错误:测量次数需在2~20之间(符合物理实验多次测量规范)!
");
return 1;
}
printf("请输入%d组%s数据(单位:%s):
", n, selected_pq->name, selected_unit);
for (int i = 0; i < n; i++) {
printf("第%d组数据:", i + 1);
scanf("%f", &data[i]);
average += data[i];
}
average /= n;
for (int i = 0; i < n; i++) {
sum_diff_sq += pow(data[i] - average, 2);
}
var_sample = sum_diff_sq / (n - 1);
std_sample = sqrt(var_sample);
u_A = std_sample / sqrt(n);
printf("
=== 异常值判断(格拉布斯准则,95%置信水平)===
");
float G_critical = G_TABLE[n];
if (n >= 3) {
for (int i = 0; i < n; i++) {
float G_i = fabs(data[i] - average) / std_sample;
if (G_i > G_critical) {
printf("警告:第%d组数据(%.4f %s)为异常值(G=%.3f > G临界值=%.3f)
",
i + 1, data[i], selected_unit, G_i, G_critical);
has_outlier = 1;
}
else {
filtered_data[filtered_n++] = data[i];
}
}
}
else {
memcpy(filtered_data, data, sizeof(data));
filtered_n = n;
printf("提示:测量次数n=2,无需判断异常值
");
}
if (has_outlier) {
char choice;
printf("是否剔除异常值并重新计算结果?(y=是/n=否):");
scanf(" %c", &choice);
if (choice == 'y' || choice == 'Y') {
filtered_avg = 0.0;
for (int i = 0; i < filtered_n; i++) {
filtered_avg += filtered_data[i];
}
filtered_avg /= filtered_n;
filtered_sum_sq = 0.0;
for (int i = 0; i < filtered_n; i++) {
filtered_sum_sq += pow(filtered_data[i] - filtered_avg, 2);
}
filtered_var = filtered_sum_sq / (filtered_n - 1);
filtered_std = sqrt(filtered_var);
filtered_uA = filtered_std / sqrt(filtered_n);
}
else {
filtered_avg = average;
filtered_var = var_sample;
filtered_std = std_sample;
filtered_uA = u_A;
}
}
else {
filtered_avg = average;
filtered_var = var_sample;
filtered_std = std_sample;
filtered_uA = u_A;
}
printf("
=== 最终数据处理结果 ===
");
printf("物理量:%s
", selected_pq->name);
printf("单位:%s
", selected_unit);
printf("测量次数(原始/过滤后):%d / %d
", n, filtered_n);
printf("平均值:%.4f %s
", filtered_avg, selected_unit);
printf("样本方差:%.4f %s²
", filtered_var, selected_unit);
printf("样本标准差:%.4f %s
", filtered_std, selected_unit);
printf("A类不确定度:%.4f %s
", filtered_uA, selected_unit);
printf("测量结果表达式:%s = (%.4f ± %.4f) %s(P=95%)
",
selected_pq->name, filtered_avg, filtered_uA, selected_unit);
fp = fopen("实验数据处理结果.txt", "w");
if (fp != NULL) {
fprintf(fp, "=== %s测量数据处理报告 ===
", selected_pq->name);
fprintf(fp, "物理量分类:%s
", category_choice == 1 ? "基本物理量" : "常用导出量");
fprintf(fp, "单位:%s
", selected_unit);
fprintf(fp, "核心公式:%s
", selected_pq->formula);
fprintf(fp, "测量次数(原始/过滤后):%d / %d
", n, filtered_n);
fprintf(fp, "原始数据:");
for (int i = 0; i < n; i++) {
fprintf(fp, "%.4f ", data[i]);
}
fprintf(fp, "%s
", selected_unit);
fprintf(fp, "过滤后数据:");
for (int i = 0; i < filtered_n; i++) {
fprintf(fp, "%.4f ", filtered_data[i]);
}
fprintf(fp, "%s
", selected_unit);
fprintf(fp, "平均值:%.4f %s
", filtered_avg, selected_unit);
fprintf(fp, "样本方差:%.4f %s²
", filtered_var, selected_unit);
fprintf(fp, "样本标准差:%.4f %s
", filtered_std, selected_unit);
fprintf(fp, "A类不确定度:%.4f %s
", filtered_uA, selected_unit);
fprintf(fp, "测量结果:%s = (%.4f ± %.4f) %s(P=95%)
",
selected_pq->name, filtered_avg, filtered_uA, selected_unit);
fclose(fp);
printf("
提示:结果已保存到「实验数据处理结果.txt」(当前文件夹)
");
}
else {
printf("
警告:文件保存失败,请检查文件夹权限!
");
}
return 0;
}
int show_category_menu() {
int choice;
printf("=== 物理实验数据处理程序 ===
");
printf("请选择物理量分类:
");
printf("1. 基本物理量(国际单位制)
");
printf("2. 常用导出量(实验高频)
");
printf("请输入选择(1/2):");
scanf("%d", &choice);
while (choice != 1 && choice != 2) {
printf("输入错误!请重新输入(1/2):");
scanf("%d", &choice);
}
return choice;
}
int show_quantity_menu(PhysicalQuantity quantities[], int count, char* category_name) {
int choice;
printf("
=== 选择%s ===
", category_name);
for (int i = 0; i < count; i++) {
printf("%d. %s
", i + 1, quantities[i].name);
}
printf("请输入选择(1-%d):", count);
scanf("%d", &choice);
while (choice < 1 || choice > count) {
printf("输入错误!请重新输入(1-%d):", count);
scanf("%d", &choice);
}
return choice - 1;
}
char* show_unit_menu(PhysicalQuantity* pq) {
int choice;
printf("
=== 选择%s的单位 ===
", pq->name);
for (int i = 0; i < pq->unit_count; i++) {
printf("%d. %s
", i + 1, pq->units[i]);
}
printf("请输入选择(1-%d):", pq->unit_count);
scanf("%d", &choice);
while (choice < 1 || choice > pq->unit_count) {
printf("输入错误!请重新输入(1-%d):", pq->unit_count);
scanf("%d", &choice);
}
return pq->units[choice - 1];
}








