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

C(VS)中static关键字失效 删除数组次大元素后n值未更新问题

需求说明
  • 接收用户输入的数值N,再输入N个整数存入数组
  • 编写C语言函数删除数组中所有第二大(次大)元素,删除后重排数组
  • 最终输出处理后的新数组,以及更新后的数组长度N
  • 样例:输入N=7,数组为7 11 13 11 8 7 4时,预期输出N=5,数组为7 13 8 7 4
问题复现

原实现代码

#include<stdio.h>

int secondLargest(int arr[], int n);
int indexOfSecondLargest(int arr[], int n, int max2);
void deleteElement(int arr[], int n, int index);
void deleteSecondLargest(int arr[], int n);
void printArray(int arr[], int n);

int main() 
{
    static int n;
    printf("Enter value of n \n");
    scanf("%d", &n);

    int arr[100];

    printf("Enter n numbers \n");
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }    

    deleteSecondLargest(arr, n);

    printf("New value of n = %d and the array is \n", n);
    
    printArray(arr, n);
    
    return 0;
}

int secondLargest(int arr[], int n)
{
    int max1 = arr[0], max2 = arr[0];
    for (int i = 0; i < n; i++)
    {
        if (arr[i] > max1)
        {
            max2 = max1;
            max1 = arr[i];            
        }
        if (arr[i] > max2 && arr[i] < max1)
        {
            max2 = arr[i];
        }       
    }
    
    return max2;
}

int indexOfSecondLargest(int arr[], int n, int max2)
{
    for (int i = 0; i < n; i++)
    {
        if (arr[i] == max2)
        {
            return i;
        }        
    }
    
    return -1;
}

void deleteElement(int arr[], int n, int index)
{
    for (int i = index; i < n - 1; i++)
    {
        arr[i] = arr[i+1];
    }

    n = n - 1;
}

void deleteSecondLargest(int arr[], int n)
{
    int max2 = secondLargest(arr, n);

    int index = indexOfSecondLargest(arr, n, max2);
    while (index != -1)
    {
        deleteElement(arr, n, index);
        index = indexOfSecondLargest(arr, n, max2);
    }
}

void printArray(int arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }    
}

错误运行结果

Enter value of n 
7
Enter n numbers 
7 11 13 11 8 7 4
New value of n = 7 and the array is 
7 13 8 7 4 4 4

问题现象

开发者在Visual Studio环境中调试时,尝试用static关键字修饰main函数中的长度变量n,甚至将n定义为全局变量,但调用删除次大元素的函数后,main函数中的n值始终没有更新为预期的5,数组输出末尾存在冗余元素,无法得到正确结果。

问题根因
  • C语言函数默认采用值传递机制,函数形参是实参的独立副本,函数内部对形参的修改不会同步到外层实参。原代码中deleteElement、deleteSecondLargest函数都以值的方式接收长度参数n,函数内部执行n = n -1时,修改的只是函数栈上的局部副本,main函数中的原始n完全不受影响。
  • 即使将main函数中的n用static修饰、或者定义为全局变量,只要两个删除函数的形参列表中仍定义了同名的int n,函数内部访问的n就会是形参局部变量,自动遮蔽外层的static变量或全局变量,修改操作依然不会生效。
  • 由于长度值始终没有更新,删除元素后遍历数组仍用原始长度7计数,就会输出数组尾部未被覆盖的冗余旧值,也就是样例中末尾多打印的两个4。
修复方案
  • 调整需要修改长度的函数形参,将长度参数改为指针类型,传入main函数中n的内存地址,让函数可以直接修改原始n的值,无需依赖static修饰或全局变量。
  • 所有涉及数组长度判断、遍历的逻辑,都使用指针解引用获取实时更新的长度值,保证删除元素后长度计数同步变化。
修复后完整代码
#include<stdio.h>

int secondLargest(int arr[], int n);
int indexOfSecondLargest(int arr[], int n, int max2);
void deleteElement(int arr[], int *n, int index);
void deleteSecondLargest(int arr[], int *n);
void printArray(int arr[], int n);

int main() 
{
    int n;
    printf("Enter value of n \n");
    scanf("%d", &n);

    int arr[100];

    printf("Enter n numbers \n");
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
    }    

    deleteSecondLargest(arr, &n);

    printf("New value of n = %d and the array is \n", n);
    
    printArray(arr, n);
    
    return 0;
}

int secondLargest(int arr[], int n)
{
    int max1 = arr[0], max2 = arr[0];
    for (int i = 0; i < n; i++)
    {
        if (arr[i] > max1)
        {
            max2 = max1;
            max1 = arr[i];            
        }
        if (arr[i] > max2 && arr[i] < max1)
        {
            max2 = arr[i];
        }       
    }
    
    return max2;
}

int indexOfSecondLargest(int arr[], int n, int max2)
{
    for (int i = 0; i < n; i++)
    {
        if (arr[i] == max2)
        {
            return i;
        }        
    }
    
    return -1;
}

void deleteElement(int arr[], int *n, int index)
{
    for (int i = index; i < *n - 1; i++)
    {
        arr[i] = arr[i+1];
    }
    *n = *n - 1;
}

void deleteSecondLargest(int arr[], int *n)
{
    int max2 = secondLargest(arr, *n);

    int index = indexOfSecondLargest(arr, *n, max2);
    while (index != -1)
    {
        deleteElement(arr, n, index);
        index = indexOfSecondLargest(arr, *n, max2);
    }
}

void printArray(int arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("%d ", arr[i]);
    }    
}
验证结果

修复后运行代码,输入样例数据可得到正确输出:

Enter value of n 
7
Enter n numbers 
7 11 13 11 8 7 4
New value of n = 5 and the array is 
7 13 8 7 4 

内容的提问来源于stack exchange,提问作者MOHAMMAD SHOAIB ANSARI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 18:57:25