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

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就是内存里的随机垃圾值。

解决方法

给正负数组分别设置独立的计数器,用来跟踪当前应该赋值的位置:

  1. 声明两个索引变量posIdx和negIdx,初始化为0;
  2. 遍历tabData时,遇到正数就赋值给tabPositives[posIdx++],遇到负数就赋值给tabNegatives[negIdx++];
  3. 这样就能保证每个数组的元素都被正确填充到对应的位置。

修正后的完整代码

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:28