How to delete array elements by using it's subscripts in C language?

You can't really delete an element. All you can do is move the data in higher subscripts to lower ones. For example if you have an array of 10 elements and you want to delete the 2nd one you have to move elements 3 to 10 to elements 2 to 9. That leaves the 10th elemenet unused. It can not be deleted unless you allocated the array with malloc() then use realloc() to make the array smaller.

There are two logical parts to an array. The capacity is set by the declaration. For the declaration int a[10]; , 10 is the capacity. It is the maximum number of elements that can be stored in the array. The size is the number of used elements in the array. Using the previous declaration, the size is 0 and the capacity is 10. After filling one element with a[0] = 10; , the size is 1 and the capacity is 10. The size is not known by C, you must maintain it with a separate variable.

The capacity will always remains the same, but elements can be removed by overwriting and decreasing the size. Overwriting is done by taking a block of elements from N to the current size and moving it left by 1. Then the size is decremented. C does not support that kind of block movement, but it can be done element by element with a loop.

#include <assert.h>
#include <stdio.h>

void remove_at(int* a, int* sz, int at) {
    assert(at >= 0 && at < sz);
    // move the [at+1,sz) block left by 1
    while (at++ < *sz)
        a[at-1] = a[at];
    --*sz; // the array has shrunk by 1
}

void list(char const* prefix, int* a, int sz, FILE* ostrm) {
    int x;
    fputs(prefix, ostrm);
    for (x = 0; x < sz; ++x)
        printf("%d%c", a[x], (x < sz-1 ? ',' : '\n'));
}

void main() {
    int a[10] = {0};
    int sz = 0;
    while (sz < 10)
        a[sz++] = sz * 10;
    list("original:      ", a, sz, stdout);
    remove_at(a, &sz, 0);
    list("remove first:  ", a, sz, stdout);
    remove_at(a, &sz, sz-1);
    list("remove last:   ", a, sz, stdout);
    remove_at(a, &sz, sz/2);
    list("remove middle: ", a, sz, stdout);
}

The memmove() function is another option that does the same thing.

In most cases, you don't want to shuffle data records around in a database.

If you have 3,000 students in a school, and a 3,200 student array of structs to handle their records, whenever a student leaves the school, you don't shuffle a bunch of records down to compact the database.

What you want to do is simply to mark out the student's fields (maybe a student ID number), and their name, to 0 and '\0', respectively. Now your program knows that new records can be put into those empty records.

Details include:
1) Your display and printouts of the records will not include records with zero'd out ID's or Names.

2) Your database will not always be kept in sorted order, but you don't care - you will have a small integer field in an auxiliary array, that your program will sort by, and use it to display or print any records, in sorted order.

That gives you the flexibility to display your records sorted by ID's, or Name fields, or any other fields (like age maybe), WITHOUT having to actually move your records around - at all. :)

The key idea is to minimize moving data around - that makes:
1) Your program more responsive - it doesn't waste time sorting and re-sorting the records.

2) Less wear and tear on the hard drives

3) Less power is used by the computer

4) Better data integrity, because you are not running the risk of shuffling records around, nearly as much.

If you want to know how to use an index auxiliary array to do this (it's simple). Let me know.

@Adak: That's exactly how I do it too, even in physical disk files. There is really no point in rewriting an entire file to delete one record. Just mark it as deleted and write the program smart enough to recognize that. Its also the same thing that DBase did it.

This article has been dead for over six months. Start a new discussion instead.