C语言入门问题:double数组首尾元素无法正常printf输出
问题:命令行愿望清单程序数组输出异常
开发一款命令行愿望清单程序,用户输入物品成本、优先级(1-3)及是否支持融资(y/n),数据存入数组后以表格展示。程序其余功能正常,但打印double类型数组itemCosts[numOfItems]时,首尾元素无法正常输出:即使所有物品输入相同价格(如6225.88),首元素显示异常,尾元素显示为0.000000。单独提取成本相关逻辑编译运行输出正常,推测bug存在于其他代码段但无法定位。
原代码
#define MAX_ITEMS 10 #include <stdio.h> int main() { const double MIN_INCOME = 500, MAX_INCOME = 400000; int numOfItems; double netIncome, itemTotal; double itemCosts[numOfItems]; int itemPriors[numOfItems]; char itemFinOps[numOfItems]; printf("+--------------------------+\n"); printf("+ Wish List Forecaster |\n"); printf("+--------------------------+\n\n"); // Prompt for net monthly income do { printf("Enter your monthly NET income: $"); scanf("%lf", &netIncome); if (netIncome < MIN_INCOME) { printf("ERROR: You must have a consistent monthly income of at least $500.00\n\n"); } else if (netIncome > MAX_INCOME) { printf("ERROR: Liar! I'll believe you if you enter a value no more than $400000.00\n\n"); } } while (!(netIncome >= MIN_INCOME && netIncome <= MAX_INCOME)); printf("\n"); // Prompt for # of wish list items do { printf("How many wish list items do you want to forecast?: "); scanf("%d", &numOfItems); if (!(numOfItems > 0 && numOfItems <= MAX_ITEMS)) { printf("ERROR: List is restricted to between 1 and 10 items.\n\n"); } printf("\n"); } while (!(numOfItems > 0 && numOfItems <= MAX_ITEMS)); // Store wish list item details for (int i = 0; i < numOfItems; i++) { printf("Item-%d Details:\n", i + 1); do //////////////// ******** PROMPT COST ********** ////////// { printf("Item cost: $"); scanf("%lf", &itemCosts[i]); if (!(itemCosts[i] >= (double)100)) { printf(" ERROR: Cost must be at least $100.00\n"); } } while (!(itemCosts[i] >= (double)100)); do // prompt priority { printf("How important is it to you? [1=must have, 2=important, 3=want]: "); scanf("%d", &itemPriors[i]); if (!(itemPriors[i] >= 1 && itemPriors[i] <= 3)) { printf(" ERROR: Value must be between 1 and 3\n"); } } while (!(itemPriors[i] >= 1 && itemPriors[i] <= 3)); do // prompt finance options { printf("Does this item have financing options? [y/n]: "); scanf(" %c", &itemFinOps[i]); if (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n')) { printf(" ERROR: Must be a lowercase 'y' or 'n'\n"); } } while (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n')); printf("\n"); } ///////// display summary of item details in TABLE ////////// printf("Item Priority Financed Cost\n"); printf("---- -------- -------- -----------\n"); for (int j = 0; j < numOfItems; j++) { printf(" %d %d %c %lf\n", j + 1, itemPriors[j], itemFinOps[j], itemCosts[j]); itemTotal += itemCosts[j]; } return 0; }
问题根源
- 变长数组初始化时机错误:声明
itemCosts、itemPriors、itemFinOps这三个变长数组时,numOfItems还未被赋值,此时它的值是栈上的随机垃圾值。后续输入numOfItems后,数组实际大小和预期不一致,写入和读取时出现内存越界,导致首尾元素数据异常。 - 未初始化变量:
itemTotal没有初始化为0.0,累加时会包含垃圾值,虽不是当前打印异常的直接原因,但属于潜在bug。
修复方案
- 将三个数组的声明移到
numOfItems被正确输入并验证之后。 - 初始化
itemTotal为0.0。
修复后的代码
#define MAX_ITEMS 10 #include <stdio.h> int main() { const double MIN_INCOME = 500, MAX_INCOME = 400000; int numOfItems; double netIncome, itemTotal = 0.0; // 初始化itemTotal printf("+--------------------------+\n"); printf("+ Wish List Forecaster |\n"); printf("+--------------------------+\n\n"); // Prompt for net monthly income do { printf("Enter your monthly NET income: $"); scanf("%lf", &netIncome); if (netIncome < MIN_INCOME) { printf("ERROR: You must have a consistent monthly income of at least $500.00\n\n"); } else if (netIncome > MAX_INCOME) { printf("ERROR: Liar! I'll believe you if you enter a value no more than $400000.00\n\n"); } } while (!(netIncome >= MIN_INCOME && netIncome <= MAX_INCOME)); printf("\n"); // Prompt for # of wish list items do { printf("How many wish list items do you want to forecast?: "); scanf("%d", &numOfItems); if (!(numOfItems > 0 && numOfItems <= MAX_ITEMS)) { printf("ERROR: List is restricted to between 1 and 10 items.\n\n"); } printf("\n"); } while (!(numOfItems > 0 && numOfItems <= MAX_ITEMS)); // 移到此处声明数组,此时numOfItems已确定 double itemCosts[numOfItems]; int itemPriors[numOfItems]; char itemFinOps[numOfItems]; // Store wish list item details for (int i = 0; i < numOfItems; i++) { printf("Item-%d Details:\n", i + 1); do //////////////// ******** PROMPT COST ********** ////////// { printf("Item cost: $"); scanf("%lf", &itemCosts[i]); if (!(itemCosts[i] >= (double)100)) { printf(" ERROR: Cost must be at least $100.00\n"); } } while (!(itemCosts[i] >= (double)100)); do // prompt priority { printf("How important is it to you? [1=must have, 2=important, 3=want]: "); scanf("%d", &itemPriors[i]); if (!(itemPriors[i] >= 1 && itemPriors[i] <= 3)) { printf(" ERROR: Value must be between 1 and 3\n"); } } while (!(itemPriors[i] >= 1 && itemPriors[i] <= 3)); do // prompt finance options { printf("Does this item have financing options? [y/n]: "); scanf(" %c", &itemFinOps[i]); if (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n')) { printf(" ERROR: Must be a lowercase 'y' or 'n'\n"); } } while (!(itemFinOps[i] == 'y' || itemFinOps[i] == 'n')); printf("\n"); } ///////// display summary of item details in TABLE ////////// printf("Item Priority Financed Cost\n"); printf("---- -------- -------- -----------\n"); for (int j = 0; j < numOfItems; j++) { printf(" %d %d %c %.2lf\n", j + 1, itemPriors[j], itemFinOps[j], itemCosts[j]); // 用%.2lf更符合货币格式 itemTotal += itemCosts[j]; } // 可选:打印总金额 printf("\nTotal cost: $%.2lf\n", itemTotal); return 0; }
内容的提问来源于stack exchange,提问作者chickpea
相关产品推荐
相关产品推荐

