C - 从数组中删除数字,不会删除相同数字的更多实例

时间:2016-05-26 23:20:11

标签: c arrays

我的代码只删除一个数字,例如同一个数字的3个实例,

int n,i,va,x;
int arr[100];
int *ptr;
srand(time(NULL));
printf("array size");
scanf("%d",&n);

for(i = 0 ; i<n; i++)
{
    va = (rand()%10);
    arr[i] = va;
}
for(i = 0 ; i<n; i++)
{
    printf("%d\n",arr[i]);
}

printf("number you wanna delete :");
scanf("%d",&x);

ptr = arr;  //pointer

bellow是我想要解决的代码

for(i = 0; i<n; i++,*ptr++)   
{
    if(*ptr == x)
    {
        for(i = i; i<n; i++)
        {
            arr[i] = arr[i+1];
        }
    }
}
n--;

打印新阵列

for(i=0; i<n; i++)
{
    printf("new array - %d\n",arr[i]);
}

继承我的结果 - 它只删除该号码的第一个实例,但不删除其余的

enter image description here

1 个答案:

答案 0 :(得分:2)

使用clang进行编译(将其放入main并仅将stdio.h包含为the OP said)后,我收到了一大堆警告。

$ make
cc -Wall -g    test.c   -o test
test.c:7:5: warning: implicit declaration of function 'srand' is invalid in C99
      [-Wimplicit-function-declaration]
    srand(time(NULL));
    ^
test.c:7:11: warning: implicit declaration of function 'time' is invalid in C99
      [-Wimplicit-function-declaration]
    srand(time(NULL));
          ^
test.c:12:15: warning: implicit declaration of function 'rand' is invalid in C99
      [-Wimplicit-function-declaration]
        va = (rand()%10);
              ^
test.c:26:19: warning: explicitly assigning value of variable of type 'int' to itself
      [-Wself-assign]
            for(i = i; i<n; i++) {
                ~ ^ ~
test.c:24:25: warning: expression result unused [-Wunused-value]
    for(i = 0; i<n; i++,*ptr++) {
                        ^~~~~~
5 warnings generated.

前三个是通过包含stdlib.h和time.h来修复的。要了解C的一些事情:仅仅因为它恰好工作并不意味着它可以为其他人工作,甚至在下次运行时也能工作。一个不同的编译器,一个不同的操作系统,或一个僵硬的微风可以使很多“工作”但不正确的C代码失败。找到IDE提供的所有警告和限制,然后全部打开。

问题的最后两点。让我们再看一遍。

$ make
cc -Wall -g    test.c   -o test
test.c:28:19: warning: explicitly assigning value of variable of type 'int' to itself
      [-Wself-assign]
            for(i = i; i<n; i++) {
                ~ ^ ~
test.c:26:25: warning: expression result unused [-Wunused-value]
    for(i = 0; i<n; i++,*ptr++) {
                        ^~~~~~
2 warnings generated.

i在内循环中递增,同样使用i。一旦找到问题,外部循环就会停止。这可以通过使用内部循环的新计数器j来修复。

for(i = 0; i<n; i++,*ptr++) {
    if(*ptr == x) {
        for(int j = i; j<n; j++) {
            arr[j] = arr[j+1];
        }
    }
}
n--;

现在它有效......有点儿。下一个问题是循环之后的n--,它假定只删除了一个元素。但是删除了任意数量的元素,因此每次都必须减少。 n--进入循环。

for(i = 0; i<n; i++,*ptr++) {
    if(*ptr == x) {
        for(int j = i; j<n; j++) {
            arr[j] = arr[j+1];
        }
        n--;
    }
}

最后,有关于*ptr--的警告。我看到发生了什么,而且很聪明......但太聪明了。很难跟踪发生的事情。不需要*ptr,只需使用arr[i]访问数组元素。

for(i = 0; i<n; i++) {
    if(arr[i] == x) {
        for(int j = i; j<n; j++) {
            arr[j] = arr[j+1];
        }
        n--;
    }
}

删除一堆不必要的变量,提供更多描述性变量名称,并根据需要初始化计数器,我们得到......

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int numbers[100];
    int size = 0;
    int to_delete;

    srand(time(NULL));
    printf("array size: ");
    scanf("%d",&size);

    for(int i = 0 ; i < size; i++) {
        numbers[i] = (rand()%10);
        printf("%d\n",numbers[i]);
    }

    printf("number you wanna delete: ");
    scanf("%d",&to_delete);

    for(int i = 0; i < size; i++) {
        if(numbers[i] == to_delete) {
            for(int j = i; j < size; j++) {
                numbers[j] = numbers[j+1];
            }
            size--;
        }
    }

    for(int i = 0; i < size; i++) {
        printf("new array - %d\n",numbers[i]);
    }

    return 0;
}

现在看看你是否可以在没有内循环的情况下做到这一点。