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

C语言数组删除函数异常:仅前置printf时正常工作求助

数组删除函数异常问题解决

问题描述

写了个borrar函数用来从数组里删元素,删倒数第二个元素时会出问题,有时会误删最后两个。更奇怪的是,只要函数里那个被注释的printf(" ");打开,函数就正常工作。

问题代码

#include <stdio.h>
#include <stdbool.h>
#include <windows.h>

enum
{
    MAX = 10
};

struct lista
{
    int array[MAX];
    int NELMS;
};

struct numero
{
    int numero;
    struct lista posiciones;
    int repe;
};

void scanlist(struct lista* list)
{
    printf("Introduzca 10 números: ");
    list->NELMS = 10;
    for(int i = 0; i < list->NELMS; i++){
        scanf(" %d", &list->array[i]);
    }
}

void printlist(const struct lista* L)
{
    for(int i = 0; i < L->NELMS; i++){
        printf("%d ",L->array[i]);
    }
}

void borrar(struct lista* list, int posicion)    // 有问题的函数
{
    for(int i = posicion; i < list->NELMS; i++){
        list->array[i] = list->array[i+1];

    }
    list->NELMS --;
   // printf(" ");                               // 注释掉就出错,打开就正常
}


void singulares (const struct lista* L1, struct lista* L2)
{
    *L2 = *L1;

    for(int i = 0; i < L2->NELMS; i++){
        for(int k = i+1; k < L2->NELMS; k++){
            if(L2->array[i] == L2->array[k])
            {
                borrar(L2, k);
                L2->NELMS--;  // 这里重复减计数了
            }
        printlist(L2);
        printf("\n");
        }
    }
}

int main()
{
    SetConsoleOutputCP(1252);
    SetConsoleCP(1252);

    struct lista list1;
  //  struct lista list2;

    scanlist(&list1);

   // singulares(&list1,&list2);

    borrar(&list1, 8);

    printlist(&list1);
    printf("\n%d",list1.NELMS);
                                     // 测试输入:7 10 143 10 52 143 72 10 143 7
}

问题根源

  1. 数组越界访问:borrar函数里的循环条件i < list->NELMS会导致当i等于list->NELMS-1时,访问list->array[i+1]也就是下标为list->NELMS的位置,超出数组的合法范围(数组下标最大是MAX-1=9)。这种未定义行为会导致程序表现随机,加printf刚好改变了内存布局,侥幸让程序看起来正常。
  2. 计数重复减少:singulares函数里调用borrar后又执行L2->NELMS--,但borrar内部已经减过一次元素计数,这会导致数组元素计数错误,后续操作逻辑混乱。

修复方案

  1. 修正borrar函数的循环条件,避免越界:
void borrar(struct lista* list, int posicion)
{
    // 循环到倒数第二个元素为止,i+1不会超出数组范围
    for(int i = posicion; i < list->NELMS - 1; i++){
        list->array[i] = list->array[i+1];
    }
    list->NELMS --;
}
  1. 删除singulares函数里重复的L2->NELMS--;语句:
if(L2->array[i] == L2->array[k])
{
    borrar(L2, k);
    // 删掉这行:L2->NELMS--;
}

测试验证

用测试输入7 10 143 10 52 143 72 10 143 7执行,调用borrar(&list1, 8)后,数组应该正确删除下标8的元素,输出为7 10 143 10 52 143 72 10 7 ,元素计数显示为9。

内容的提问来源于stack exchange,提问作者Serye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:15:28