C语言正负数字拆分到数组时负数变为0的问题排查
问题分析与解决
你的代码核心问题在于填充正负数组时使用了错误的索引方式,导致负数数组的元素没有被正确赋值,出现了看似全部为0的异常(实际是内存越界访问产生的未定义行为,刚好显示为0)。
具体问题点
在第二个循环里,你遍历tabData时直接用循环变量i作为tabPositives和tabNegatives的索引:
for (int i = 0; i < numberData; i++) { if (tabData[i] >= 0) { tabPositives[i] = tabData[i]; } else { tabNegatives[i] = tabData[i]; } }
举个你的测试用例例子:输入423(正数,i=0)和-5(负数,i=1),此时:
- 正数数组
tabPositives的大小是1,给tabPositives[0]赋值423是正确的; - 负数数组
tabNegatives的大小是1,但你试图给tabNegatives[1]赋值——这已经超出了数组的合法索引范围(只能到0),属于数组越界访问,会破坏内存或读取到随机值,你看到的0就是内存里的随机垃圾值。
解决方法
给正负数组分别设置独立的计数器,用来跟踪当前应该赋值的位置:
- 声明两个索引变量
posIdx和negIdx,初始化为0; - 遍历
tabData时,遇到正数就赋值给tabPositives[posIdx++],遇到负数就赋值给tabNegatives[negIdx++]; - 这样就能保证每个数组的元素都被正确填充到对应的位置。
修正后的完整代码
#include <stdlib.h> #include <stdio.h> int main (int argc, char **argv) { int numberData = 0; int numberPositives = 0; int numberNegatives = 0; int number = 0; int *tabData = NULL; int *tabPositives = NULL; int *tabNegatives = NULL; printf("Enter size : "); scanf("%d", &numberData); tabData = malloc(numberData * sizeof(int)); if (tabData == NULL) { // 新增内存分配检查,避免空指针崩溃 perror("malloc failed for tabData"); return 1; } for (int i = 0; i < numberData; i++) { printf("Enter number: "); scanf("%d", &number); tabData[i] = number; if (number >= 0) { numberPositives++; } else { numberNegatives++; } } // 内存分配并检查失败情况 tabPositives = malloc(numberPositives * sizeof(int)); if (tabPositives == NULL) { perror("malloc failed for tabPositives"); free(tabData); return 1; } tabNegatives = malloc(numberNegatives * sizeof(int)); if (tabNegatives == NULL) { perror("malloc failed for tabNegatives"); free(tabData); free(tabPositives); return 1; } // 使用独立索引填充正负数组 int posIdx = 0, negIdx = 0; for (int i = 0; i < numberData; i++) { if (tabData[i] >= 0) { tabPositives[posIdx++] = tabData[i]; } else { tabNegatives[negIdx++] = tabData[i]; } } printf("INPUT\n"); for (int i = 0; i < numberData; i++) { printf("%d ", tabData[i]); // 加空格让输出更清晰 } printf("\n"); printf("POSITIVES\n"); for (int i = 0; i < numberPositives; i++) { printf("%d ", tabPositives[i]); } printf("\n"); printf("NEGATIVES\n"); for (int i = 0; i < numberNegatives; i++) { printf("%d ", tabNegatives[i]); } printf("\n"); // 按分配逆序释放内存,更规范 free(tabPositives); free(tabNegatives); free(tabData); return 0; }
额外优化点
- 新增了内存分配失败检查:
malloc可能返回NULL,不处理会导致程序崩溃; - 输出时添加空格,让结果更易读;
- 调整内存释放顺序,更符合编程规范。
现在运行你的测试用例:输入2,然后423和-5,输出会是:
INPUT 423 -5 POSITIVES 423 NEGATIVES -5
完全符合预期。
内容的提问来源于stack exchange,提问作者user11913526
相关产品推荐
相关产品推荐

