C language learning: number of sets of algorithm implementation level

Preface: A normal insertion sort.

Insertion sort defaults from largest to smallest //externvoidsort_insert_int(inta[],int len) {

    int i, j;

    for(i =1; i < len; ++i) {

        intkey = a[j = i];

        // From small to large while(j >0&& a[j -1] <key) {

            a[j] = a[j -1];

            --j;

        }

        a[j] = key;

    }

}

At this time, someone thought, the array is a double, then how to make it. There is also a solution

#definesort_insert(a, len) \    _Generic(a

            , int*    : sort_insert_int

            , double*  : sort_insert_double

            , default: sort_insert_default) (a, len)

 

Is it enlightening? Of course. For the above, the package is from large to small. Then if you need to grow from small to large, you can do this

staticinlineint_compare_2(constintleft,constint key) {

    returnleft - key;

} externvoidsort_insert_2(inta[],int len,

    intcompare(constintleft,constint key)) {

    int i, j;

    for(i =1; i < len; ++i) {

        intkey = a[j = i];

        while(j >0&& compare(a[j -1], key) <0) {

            a[j] = a[j -1];

            --j;

        }

        a[j] = key;

    }

}

Separately abstract the comparison behavior and register it in. Isn't it very happy?

 

 A little bit more packaging

  Maybe it will be happier here. Since it can be simulated by high-tech generics, then we can also use old technology to make it.

typedefint(* compare_f)(constvoid* left,constvoid* key);staticinlineint_compare_3(constvoid* left,constvoid* key) {

    return*(int*)left - *(int*)key;

}externvoidsort_insert_3_(void* data, size_t ez,int len, compare_f compare) {

    char* a = data;

    void* key;

    int i, j;

    if((key =malloc(ez)) == NULL)

        return;

    for(i =1; i < len; ++i) {

        memcpy(key, &a[i * ez], ez);

        for(j = i; j >0&& compare(&a[(j -1) * ez], key) <0; --j)

            memcpy(&a[j * ez], &a[(j -1) * ez], ez);

        if(j != i)

            memcpy(&a[j * ez], key, ez);

    }

    free(key);

}#definesort_insert_3(a, len, compare) \    sort_insert_3_(a, sizeof(*(a)), len, (compare_f)compare)

Is it very clever, everything is programmed to void *. Of course, if you use C99 version or higher, or use a higher version of GCC.

It can be written better.

externvoidsort_insert_4_(void* data, size_t ez,int len, compare_f compare) {

    char* a = data;

    char key [ez];

    int i, j;

    for(i =1; i < len; ++i) {

        memcpy(key, &a[i * ez], ez);

        for(j = i; j >0&& compare(&a[(j -1) * ez], key) <0; --j)

            memcpy(&a[j * ez], &a[(j -1) * ez], ez);

        if(j != i)

            memcpy(&a[j * ez], key, ez);

    }

}

 

The VLA feature of C99 is used here. I don't know if the careful students are thinking about it. How does GCC implement VLA variable-length arrays?

If you see the blue sky aside from the clouds, we might as well have an experiment to verify it. Look at the test code below

#include #include /* * file : vla.c

* make: gcc -g -Wall -O2 -o vla.exe vla.c

*

*/intmain(intargc,char* argv[]) {

    chara[10];

    intb = 7;

    char c[b];

    int* d =malloc(sizeof(int));

    if(d == NULL)

        exit(EXIT_FAILURE);

    *d =1000;

    chare [* d];

    printf("%p : char a[10]\n", a);

    printf("%p : int b\n", &b);

    printf("%p : char c[b]\n", c);

    printf("%p : int * d\n", d);

    printf("%p : char e[*d]\n", e);

    free(d);

    return EXIT_SUCCESS;

}

The final output is

For vla variable arrays through address matching, GCC is placed on the stack. All can be predicted, when the variable array size is too large. The function stack will directly crash.

If you have an idea, then implement it, we can still catch the most simple drops independently~~

 

Common Taolu

  There is also a routine, using macro templates to implement, briefly mention this idea. Look at the following code

#ifdefined(__T)#define__f(type) sort_insert_##type#define__F(type) __f(type)staticvoid__F(__T) (__T a[],intlen,intcompare(const__T left,const __T key)) {

    int i, j;

    for(i =1; i < (int)len; ++i) {

        __T key = a[j = i];

        while(j >0&& compare(a[j -1], key) <0) {

            a[j] = a[j -1];

            --j;

        }

        a[j] = key;

    }

}#endif

Generally speaking, the above template functions are encapsulated in a partial file and it is also very convenient to use, for example, the following

// The definition part, the separation of declaration and definition can be done by yourself #undef__T#define__T int#include "sort_insert.c"// The part used is the same as the ordinary function sort_insert_int(a, LEN(a), _compare_2);

 

Of course, in addition to the above file-based function template. It is also implemented with a function template purely based on function macros.

#definesort_insert_definition(T) \staticvoidsort_insert_##T (T a[],intlen,intcompare(constT left,const T key)) { \

        int i, j; \

        for(i =1; i < len; ++i) { \

            T key = a[j = i]; \

            while(j >0&& compare(a[j -1], key) <0) { \

                a[j] = a[j -1]; \

                --j; \

            } \

            a[j] = key; \

        } \

    }

sort_insert_definition(int)

The use is still the same sort_insert_int(a, LEN(a), _compare_2); to run. The first type of function template is used more in embedded

The second type is used more in actual combat, and it is very common to deal with various algorithm-related codes. By now, you should be able to understand the above

The routine of a small function in the C package


In addition, if you want to better improve your programming ability, learn C language and C++ programming! Overtaking in a curve, one step faster! I may be able to help you here~

UP has uploaded some video tutorials on learning C/C++ programming on the homepage. Those who are interested or are learning must go and take a look! It will be helpful to you~

Sharing (source code, actual project video, project notes, basic introductory tutorial)

Welcome partners who change careers and learn programming, use more information to learn and grow faster than thinking about it yourself!

 

Programming learning:

Programming learning:

 

Guess you like

Origin blog.csdn.net/weixin_45713725/article/details/115300648