最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于C語言實現(xiàn)泛型編程詳解

 更新時間:2022年07月06日 08:35:10   作者:奔馳的戰(zhàn)豬  
對于C而言,想實現(xiàn)泛型編程并非易事,甚至可以說非常繁瑣,一大堆坑。最主要也沒有現(xiàn)成的輪子可用。本文就來詳細為大家講講C語言如何實現(xiàn)泛型編程詳解,需要的可以參考一下

心理歷程

寫了一段時間C++后,真心感覺STL里的容器是個好東西。一個容器可以容納任意類型,容器對外的接口可以操作任意類型的數(shù)據(jù),甚至包括自定義類型的數(shù)據(jù)。這種泛型編程的思想,對于大型項目而言是非常有好處的。

對于C而言,想實現(xiàn)泛型編程并非易事,甚至可以說非常繁瑣,一大堆坑。最主要也沒有現(xiàn)成的輪子可用。當然也有一些通過宏實現(xiàn)了泛型的基礎(chǔ)功能,但是可讀性,可調(diào)試性太差了。

于是就想自己造一個輪子,實現(xiàn)基于C對窗口(順序表)的泛化,目標就是實現(xiàn)不同類型下,規(guī)范接口的一致性。拋磚引玉。

輪子用法

int main( void )
{
	// 1、創(chuàng)建一個窗口,并初始化它,大小為10,類型為double
    ValueWindowSquential tmp;
    InitValueWindow( &tmp, kValueTypeList[ DOUBLE ], 10 );

    double insert_data = 0;
    for ( int i = 0; i < tmp.max_size; i++ )
    {
    	// 2、填充這個窗口,直到窗口填滿
        insert_data = i * 10;
        if ( kWindowAlreadyFull == ValueWindowFixedInsert( &tmp, &insert_data ) )
        {
        	// 3、打印整個窗口
            printf( "start sort \r\n" );
            ShowTheWindow( &tmp );
	
			// 4、整個窗口排序
            ValueWindowSelectSort( &tmp );
	
			// 5、打印排序后的窗口
            printf( "end sort \r\n" );
            ShowTheWindow( &tmp );

            break;
        }
    }

    printf( "test generics \r\n" );
    return 0;
}

打印log如下:

這時想換成創(chuàng)建一個uint8_t類型的串口,只需要改兩個地方,這兩個地方在C++里也避免不了。

int main( void )
{
    ValueWindowSquential tmp;
    InitValueWindow( &tmp, kValueTypeList[ UINT8 ], 10 );

    uint8_t insert_data = 0;
    for ( int i = 0; i < tmp.max_size; i++ )
    {
        insert_data = ( tmp.max_size - i ) * 1;
        if ( kWindowAlreadyFull == ValueWindowFixedInsert( &tmp, &insert_data ) )
        {
            printf( "start sort \r\n" );
            ShowTheWindow( &tmp );

            ValueWindowSelectSort( &tmp );

            printf( "end sort \r\n" );
            ShowTheWindow( &tmp );

            break;
        }
    }

    printf( "test generics \r\n" );
    return 0;
}

大體流程

1.首先初始化一個空窗口對象,然后調(diào)用 InitValueWindow 傳入窗口類型,大小,然后初始化它。

2.調(diào)用 ValueWindowFixedInsert 往窗口中插入值,直到窗口滿后反饋狀態(tài)。

3.打印整個窗口

4.對窗口排序

5.打印整個窗口

這里的泛型主要通過查表實現(xiàn)了,將希望包含的類型加入表中,然后初始化時傳入其類型和大小。

插入數(shù)據(jù)的時候,需要保證數(shù)據(jù)類型和窗口類型統(tǒng)一,這算是個局限性了。

窗口被填充完畢后,會有反饋窗口狀態(tài),這時可以調(diào)用 ShowTheWindow 將原始窗口打印。

在調(diào)用 ValueWindowSelectSort 將窗口排序。排序完后再次打印。

可以看到除了初始化的時候,需要設(shè)定窗口的類型,這和 std::vector< double > 沒什么兩樣,插入數(shù)據(jù)時需要調(diào)用者確保數(shù)據(jù)類型與窗口統(tǒng)一。

部分源碼

#ifndef __TEST_GENERICS_h
#define __TEST_GENERICS_h

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>

#include <assert.h>

typedef signed char   int8_t;
typedef unsigned char uint8_t;

typedef signed short   int16_t;
typedef unsigned short uint16_t;

typedef signed int   int32_t;
typedef unsigned int uint32_t;

typedef enum
{
    UINT8 = 0,
    INT,
    FLOAT,
    DOUBLE,

    ERROR

} TypeName;

const char* kValueTypeList[ ERROR + 1 ] = {

    "uint8_t",

    "int",
    "float",
    "double",

    "error",
};

TypeName ChangeStringToEnum( const char* tmp );

/**
 * @brief 該結(jié)構(gòu)體用于構(gòu)建基礎(chǔ)窗口順序表
 *        this structure is used to build the basic window sequence table
 */
typedef struct ValueWindowSquential
{
    char* type;
    void* data;

    uint32_t max_size;

    uint32_t sequence;

} ValueWindowSquential;

/**
 * @brief 初始化窗口,根據(jù)窗口類型,大小,動態(tài)分配內(nèi)存給到內(nèi)部緩沖區(qū)
 *        initialize the window, and dynamically allocate memory to the internal buffer according to the window type and size
 *
 * @param tmp base structure for Window
 * @param type Window type
 * @param max_size Window size
 *
 * @throw assert
 */
void InitValueWindow( ValueWindowSquential* tmp, const char* type, uint32_t max_size );

/**
 * @brief 重置或銷毀窗口
 *        reset or destroy window
 *
 * @param tmp base structure for Window
 */
void ResetValueWindow( ValueWindowSquential* tmp );

typedef enum
{
    kWindowIsNotFull = ( 0 ),
    kWindowIsSliding,

    kWindowCanNotInsert,
    kWindowInputFail,

} SlideWindowState;
/**
 * @brief 滑動插入數(shù)據(jù)進入窗口,先入先出(FIFO模型)
 *        slide insert data into the window, first in first out (FIFO model)
 *
 * @param tmp base structure for Window
 * @param data insert data
 *
 * @return SlideWindowState
 *              kWindowIsNotFull    窗口未填充滿
 *              kWindowIsSliding    窗口已填充滿并開始滑動
 *
 *              kWindowCanNotInsert 窗口不允許插入
 *              kWindowInputFail    窗口插入數(shù)據(jù)失敗
 */
SlideWindowState ValueWindowSlideInsert( ValueWindowSquential* tmp, void* data );

typedef enum
{
    kWindowNotFull = ( 0 ),
    kWindowAlreadyFull,

    kFixWindowCanNotInsert,
    kFixWindowInputFail,

} FixedWindowState;
/**
 * @brief 固定窗,往窗口里插入數(shù)據(jù),直到窗口滿了反饋 kWindowAlreadyFull ,否在反饋 kWindowNotFull
 *        與滑動窗區(qū)別是,固定窗會采集多組數(shù)據(jù),采集完成才能使用窗口,使用完后從頭重新采集
 *        也就是降頻處理數(shù)據(jù),窗口大小20,10ms插入一次,那么降頻到200ms處理一次窗口(數(shù)據(jù))
 *
 * @param tmp base structure for Window
 * @param data insert data
 *
 * @return FixedWindowState
 *              kWindowNotFull 窗口未滿
 *              kWindowAlreadyFull 窗口已滿,可以開始操作
 *
 *              kFixWindowCanNotInsert 窗口不允許插入
 *              kFixWindowInputFail 窗口插入數(shù)據(jù)失敗
 */
FixedWindowState ValueWindowFixedInsert( ValueWindowSquential* tmp, void* data );

/**
 * @brief 遍歷并打印窗口
 *
 * @param tmp base structure for Window
 */
void ShowTheWindow( ValueWindowSquential* tmp );

#endif // __TEST_GENERICS_h
/**
 * @file test_generics.cpp
 * @author benzs_war_pig (benzwarpig@outlook.com)
 * @brief   構(gòu)建一種基于C的泛型順序表,針對不同類型的順序表,實現(xiàn)接口一致化。
 *        同時針對順序表實現(xiàn)一些常用操作(排序,濾波,統(tǒng)計等)
 *
 *          build a generic sequence table based on C, and realize interface consistency
 *          for different types of sequence tables. At the same time, some common operations (sorting, filtering, statistics, etc.)
 *          are implemented for the sequence table
 *
 * @version 1.0
 * @date 2022-06-30
 *
 * @copyright Copyright (c) 2022
 *
 */
#include "test_generics.h"

#include "generics_impl.h"

/**
 * @brief 將字符串轉(zhuǎn)換成TypeName
 *          private interface
 *
 * @param tmp
 * @return TypeName
 */
TypeName ChangeStringToEnum( const char* tmp )
{
    assert( tmp != NULL );

    TypeName return_tmp = ERROR;

    if ( strcmp( tmp, kValueTypeList[ UINT8 ] ) == 0 )
    {
        return_tmp = UINT8;
    }
    else if ( strcmp( tmp, kValueTypeList[ FLOAT ] ) == 0 )
    {
        return_tmp = FLOAT;
    }
    else if ( strcmp( tmp, kValueTypeList[ DOUBLE ] ) == 0 )
    {
        return_tmp = DOUBLE;
    }
    else if ( strcmp( tmp, kValueTypeList[ INT ] ) == 0 )
    {
        return_tmp = INT;
    }
    else
    {
        printf( "error char* input !!!" );
        assert( 0 );
    }
    return return_tmp;
}

// 初始化窗口
// Initialize window
void InitValueWindow( ValueWindowSquential* tmp, const char* type, uint32_t max_size )
{
    assert( tmp != NULL );

    tmp->type = ( char* ) malloc( strlen( type ) * sizeof( char ) );
    strncpy( tmp->type, type, strlen( type ) );

    tmp->max_size = max_size;
    tmp->sequence = 0;

    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            tmp->data = ( uint8_t* ) malloc( max_size * sizeof( uint8_t ) );
            memset( tmp->data, 0, tmp->max_size );
        }
        break;

        case INT: {
            tmp->data = ( int* ) malloc( max_size * sizeof( int ) );
            memset( tmp->data, 0, tmp->max_size );
        }
        break;

        case FLOAT: {
            tmp->data = ( float* ) malloc( max_size * sizeof( float ) );
            memset( tmp->data, 0, tmp->max_size );
        }
        break;

        case DOUBLE: {
            tmp->data = ( double* ) malloc( max_size * sizeof( double ) );
            memset( tmp->data, 0, tmp->max_size );
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }

    printf( "type is : %s , number is : %d  \r\n", tmp->type, max_size );
}

// 重置/銷毀窗口
void ResetValueWindow( ValueWindowSquential* tmp )
{
    tmp->sequence = 0;
    tmp->max_size = 0;

    if ( tmp->data != NULL )
    {
        free( tmp->data );
        tmp->data = NULL;
    }

    if ( tmp->type != NULL )
    {
        free( tmp->type );
        tmp->type = NULL;
    }
}

// 滑動往窗口插入數(shù)據(jù)
SlideWindowState ValueWindowSlideInsert( ValueWindowSquential* tmp, void* data )
{
    SlideWindowState return_tmp = kWindowIsNotFull;

    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* tmp_buffer = ( uint8_t* ) tmp->data;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                tmp_buffer[ i - 1 ] = tmp_buffer[ i ];
            }
            uint8_t* res                    = ( uint8_t* ) data;
            tmp_buffer[ tmp->max_size - 1 ] = *res;
        }
        break;

        case INT: {
            int* tmp_buffer = ( int* ) tmp->data;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                tmp_buffer[ i - 1 ] = tmp_buffer[ i ];
            }
            int* res                        = ( int* ) data;
            tmp_buffer[ tmp->max_size - 1 ] = *res;
        }
        break;

        case FLOAT: {
            float* tmp_buffer = ( float* ) tmp->data;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                tmp_buffer[ i - 1 ] = tmp_buffer[ i ];
            }
            float* res                      = ( float* ) data;
            tmp_buffer[ tmp->max_size - 1 ] = *res;
        }
        break;

        case DOUBLE: {
            double* tmp_buffer = ( double* ) tmp->data;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                tmp_buffer[ i - 1 ] = tmp_buffer[ i ];
            }
            double* res                     = ( double* ) data;
            tmp_buffer[ tmp->max_size - 1 ] = *res;
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }
    if ( ++tmp->sequence > tmp->max_size )
    {
        return_tmp    = kWindowIsSliding;
        tmp->sequence = tmp->max_size;
    }

    return return_tmp;
}

// 插入數(shù)據(jù)直到填滿整個窗口
FixedWindowState ValueWindowFixedInsert( ValueWindowSquential* tmp, void* data )
{
    FixedWindowState return_tmp = kWindowNotFull;

    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* tmp_buffer = ( uint8_t* ) tmp->data;
            uint8_t* res        = ( uint8_t* ) data;

            tmp_buffer[ tmp->sequence ] = *res;
        }
        break;

        case INT: {
            int* tmp_buffer = ( int* ) tmp->data;
            int* res        = ( int* ) data;

            tmp_buffer[ tmp->sequence ] = *res;
        }
        break;

        case FLOAT: {
            float* tmp_buffer = ( float* ) tmp->data;
            float* res        = ( float* ) data;

            tmp_buffer[ tmp->sequence ] = *res;
        }
        break;

        case DOUBLE: {
            double* tmp_buffer = ( double* ) tmp->data;
            double* res        = ( double* ) data;

            tmp_buffer[ tmp->sequence ] = *res;
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }

    if ( ++tmp->sequence >= tmp->max_size )
    {
        tmp->sequence = 0;
        return_tmp    = kWindowAlreadyFull;
    }
    return return_tmp;
}

// 打印窗口內(nèi)全部值
void ShowTheWindow( ValueWindowSquential* tmp )
{
    // printf("current_type:{%d}", ChangeStringToEnum(tmp->type));
    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* msg = ( uint8_t* ) tmp->data;
            for ( int i = 0; i < tmp->max_size; ++i )
            {
                printf( "i : {%d} , %d \r\n", i, msg[ i ] );
            }
        }
        break;

        case INT: {
            int* msg = ( int* ) tmp->data;
            for ( int i = 0; i < tmp->max_size; ++i )
            {
                printf( "i : {%d} , %d \r\n", i, msg[ i ] );
            }
        }
        break;

        case FLOAT: {
            float* msg = ( float* ) tmp->data;
            for ( int i = 0; i < tmp->max_size; ++i )
            {
                printf( "i : {%d} , %f \r\n", i, msg[ i ] );
            }
        }
        break;

        case DOUBLE: {
            double* msg = ( double* ) tmp->data;
            for ( int i = 0; i < tmp->max_size; ++i )
            {
                printf( "i : {%d} , %f \r\n", i, msg[ i ] );
            }
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }
}

int main( void )
{
    ValueWindowSquential tmp;
    InitValueWindow( &tmp, kValueTypeList[ DOUBLE ], 10 );

    double insert_data = 0;
    for ( int i = 0; i < tmp.max_size; i++ )
    {
        insert_data = ( tmp.max_size - i ) * 10;
        if ( kWindowAlreadyFull == ValueWindowFixedInsert( &tmp, &insert_data ) )
        {
            printf( "start sort \r\n" );
            ShowTheWindow( &tmp );

            ValueWindowSelectSort( &tmp );

            printf( "end sort \r\n" );
            ShowTheWindow( &tmp );

            break;
        }
    }
    ResetValueWindow(&tmp);

    printf( "test generics \r\n" );
    return 0;
}

這是最開始的一版源碼,基本的思路是基于 void* 實現(xiàn)對窗口的泛化,把窗口的地址,大小,類型 在初始化時設(shè)定好,以后所有的結(jié)構(gòu)便基于這些信息,實現(xiàn)接口一致性。

目前實現(xiàn)了兩種窗口類型, ValueWindowSlideInsert (滑動窗) 和 ValueWindowFixedInsert(固定窗) 。 兩者不同之處只是插入數(shù)據(jù)時的處理不同?;瑒哟白裱璅IFO模型,即先入先出,窗口狀態(tài)有未滿和開始滑動,一般開始滑動后再對窗口進行操作。

固定窗有未滿和已滿兩種狀態(tài),已滿后會清空窗口,重新開始填充,這也是兩種常見的窗口模型。

在STL里,當有一些底層數(shù)據(jù)結(jié)構(gòu)去存儲數(shù)據(jù)時,要有一些容器的方法(算法),比如排序等,這里先實現(xiàn)了一些基礎(chǔ)的泛型算法接口:

#ifndef GENERICS_IMPL_H
#define GENERICS_IMPL_H

#include <stdbool.h>

#include "test_generics.h"

/**
 * @file generics_impl.h
 * @author benzs_war_pig (benzwarpig@outlook.com)
 * @brief 該文件實現(xiàn)了一些操作泛型順序表的算法,如排序,查找,遍歷,判斷變化率等等
 *
 *        this file implements some algorithms for operating generic sequential tables, such as sorting, searching, traversing,
 *          judging the rate of change, and so on
 *
 * @version 1.0
 * @date 2022-06-30
 *
 * @copyright Copyright (c) 2022
 *
 */

/**
 * @brief 交換順序表中兩個成員的值
 *
 * @param tmp base structure for Window
 * @param i
 * @param j
 */
static void swap( ValueWindowSquential* tmp, uint32_t i, uint32_t j )
{
    assert( tmp != NULL );
    // assert( i > tmp->max_size || j > tmp->max_size );
    // assert( i >= tmp->max_size || j >= tmp->max_size );

    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* tmp_buffer = ( uint8_t* ) tmp->data;
            uint8_t  res        = tmp_buffer[ i ];

            tmp_buffer[ i ] = tmp_buffer[ j ];
            tmp_buffer[ j ] = res;
        }
        break;

        case INT: {
            int* tmp_buffer = ( int* ) tmp->data;
            int  res        = tmp_buffer[ i ];

            tmp_buffer[ i ] = tmp_buffer[ j ];
            tmp_buffer[ j ] = res;
        }
        break;

        case FLOAT: {
            float* tmp_buffer = ( float* ) tmp->data;
            float  res        = tmp_buffer[ i ];

            tmp_buffer[ i ] = tmp_buffer[ j ];
            tmp_buffer[ j ] = res;
        }
        break;

        case DOUBLE: {
            double* tmp_buffer = ( double* ) tmp->data;
            double  res        = tmp_buffer[ i ];

            tmp_buffer[ i ] = tmp_buffer[ j ];
            tmp_buffer[ j ] = res;
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }
}

static inline void ValueWindowBubbleSort( ValueWindowSquential* tmp )
{
    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* tmp_buffer = ( uint8_t* ) tmp->data;

            bool is_end_loop = true;
            for ( int i = 0; i < tmp->max_size && is_end_loop; i++ )
            {
                is_end_loop = false;

                for ( int j = tmp->max_size - 1; j >= i; j-- )
                {
                    if ( tmp_buffer[ j - 1 ] > tmp_buffer[ j ] )
                    {
                        swap( tmp, j - 1, j );
                        is_end_loop = true;
                    }
                }
            }
        }
        break;

        case INT: {
            int* tmp_buffer = ( int* ) tmp->data;

            bool is_end_loop = true;
            for ( int i = 0; i < tmp->max_size && is_end_loop; i++ )
            {
                is_end_loop = false;

                for ( int j = tmp->max_size - 1; j >= i; j-- )
                {
                    if ( tmp_buffer[ j - 1 ] > tmp_buffer[ j ] )
                    {
                        swap( tmp, j - 1, j );
                        is_end_loop = true;
                    }
                }
            }
        }
        break;

        case FLOAT: {
            float* tmp_buffer = ( float* ) tmp->data;

            bool is_end_loop = true;
            for ( int i = 0; i < tmp->max_size && is_end_loop; i++ )
            {
                is_end_loop = false;

                for ( int j = tmp->max_size - 1; j >= i; j-- )
                {
                    if ( tmp_buffer[ j - 1 ] > tmp_buffer[ j ] )
                    {
                        swap( tmp, j - 1, j );
                        is_end_loop = true;
                    }
                }
            }
        }
        break;

        case DOUBLE: {
            double* tmp_buffer = ( double* ) tmp->data;

            bool is_end_loop = true;
            for ( int i = 0; i < tmp->max_size && is_end_loop; i++ )
            {
                is_end_loop = false;

                for ( int j = tmp->max_size - 1; j >= i; j-- )
                {
                    if ( tmp_buffer[ j - 1 ] > tmp_buffer[ j ] )
                    {
                        swap( tmp, j - 1, j );
                        is_end_loop = true;
                    }
                }
            }
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }
}

static inline void ValueWindowSelectSort( ValueWindowSquential* tmp )
{
    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* tmp_buffer = ( uint8_t* ) tmp->data;

            int tmp_data = 0;
            for ( int i = 0; i < tmp->max_size; i++ )
            {
                tmp_data = i;
                for ( int j = i; j < tmp->max_size; j++ )
                {
                    if ( tmp_buffer[ tmp_data ] > tmp_buffer[ j ] )
                    {
                        tmp_data = j;
                    }
                }
                if ( tmp_data != i )
                {
                    swap( tmp, i, tmp_data );
                }
            }
        }
        break;

        case INT: {
            int* tmp_buffer = ( int* ) tmp->data;

            int tmp_data = 0;
            for ( int i = 0; i < tmp->max_size; i++ )
            {
                tmp_data = i;
                for ( int j = i; j < tmp->max_size; j++ )
                {
                    if ( tmp_buffer[ tmp_data ] > tmp_buffer[ j ] )
                    {
                        tmp_data = j;
                    }
                }
                if ( tmp_data != i )
                {
                    swap( tmp, i, tmp_data );
                }
            }
        }
        break;

        case FLOAT: {
            float* tmp_buffer = ( float* ) tmp->data;

            int tmp_data = 0;
            for ( int i = 0; i < tmp->max_size; i++ )
            {
                tmp_data = i;
                for ( int j = i; j < tmp->max_size; j++ )
                {
                    if ( tmp_buffer[ tmp_data ] > tmp_buffer[ j ] )
                    {
                        tmp_data = j;
                    }
                }
                if ( tmp_data != i )
                {
                    swap( tmp, i, tmp_data );
                }
            }
        }
        break;

        case DOUBLE: {
            double* tmp_buffer = ( double* ) tmp->data;

            int tmp_data = 0;
            for ( int i = 0; i < tmp->max_size; i++ )
            {
                tmp_data = i;
                for ( int j = i; j < tmp->max_size; j++ )
                {
                    if ( tmp_buffer[ tmp_data ] > tmp_buffer[ j ] )
                    {
                        tmp_data = j;
                    }
                }
                if ( tmp_data != i )
                {
                    swap( tmp, i, tmp_data );
                }
            }
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }
}

static inline void ValueWindowInsertSort( ValueWindowSquential* tmp )
{
    switch ( ChangeStringToEnum( tmp->type ) )
    {
        case UINT8: {
            uint8_t* tmp_buffer = ( uint8_t* ) tmp->data;

            uint8_t tmp_data = 0;
            int     j        = 0;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                if ( tmp_buffer[ i ] < tmp_buffer[ i - 1 ] )
                {
                    tmp_data = tmp_buffer[ i ];
                    // TAG : 數(shù)據(jù)整體向后遷移,尋找數(shù)值更大的成員
                    for ( j = i - 1; tmp_buffer[ j ] > tmp_data && j >= 0; j-- )
                    {
                        tmp_buffer[ j + 1 ] = tmp_buffer[ j ];
                    }
                    tmp_buffer[ j + 1 ] = tmp_data;
                }
            }
        }
        break;

        case INT: {
            int* tmp_buffer = ( int* ) tmp->data;

            int tmp_data = 0;
            int j        = 0;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                if ( tmp_buffer[ i ] < tmp_buffer[ i - 1 ] )
                {
                    tmp_data = tmp_buffer[ i ];
                    // TAG : 數(shù)據(jù)整體向后遷移,尋找數(shù)值更大的成員
                    for ( j = i - 1; tmp_buffer[ j ] > tmp_data && j >= 0; j-- )
                    {
                        tmp_buffer[ j + 1 ] = tmp_buffer[ j ];
                    }
                    tmp_buffer[ j + 1 ] = tmp_data;
                }
            }
        }
        break;

        case FLOAT: {
            float* tmp_buffer = ( float* ) tmp->data;

            float tmp_data = 0;
            int   j        = 0;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                if ( tmp_buffer[ i ] < tmp_buffer[ i - 1 ] )
                {
                    tmp_data = tmp_buffer[ i ];
                    // TAG : 數(shù)據(jù)整體向后遷移,尋找數(shù)值更大的成員
                    for ( j = i - 1; tmp_buffer[ j ] > tmp_data && j >= 0; j-- )
                    {
                        tmp_buffer[ j + 1 ] = tmp_buffer[ j ];
                    }
                    tmp_buffer[ j + 1 ] = tmp_data;
                }
            }
        }
        break;

        case DOUBLE: {
            double* tmp_buffer = ( double* ) tmp->data;

            double tmp_data = 0;
            int    j        = 0;
            for ( int i = 1; i < tmp->max_size; i++ )
            {
                if ( tmp_buffer[ i ] < tmp_buffer[ i - 1 ] )
                {
                    tmp_data = tmp_buffer[ i ];
                    // TAG : 數(shù)據(jù)整體向后遷移,尋找數(shù)值更大的成員
                    for ( j = i - 1; tmp_buffer[ j ] > tmp_data && j >= 0; j-- )
                    {
                        tmp_buffer[ j + 1 ] = tmp_buffer[ j ];
                    }
                    tmp_buffer[ j + 1 ] = tmp_data;
                }
            }
        }
        break;

        default: {
            printf( "error tmp->type input !!!" );
            assert( 0 );
        }
        break;
    }
}
#endif // GENERICS_IMPL_H

以上就是基于C語言實現(xiàn)泛型編程詳解的詳細內(nèi)容,更多關(guān)于C語言 泛型編程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++實現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法

    C++實現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法

    這篇文章主要為大家詳細介紹了C++如何實現(xiàn)基于不相交集合的O(mlgn)復(fù)雜度的kruskal算法,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-02-02
  • C++ 將一個文件讀入數(shù)組再讀出數(shù)組的方法

    C++ 將一個文件讀入數(shù)組再讀出數(shù)組的方法

    今天小編就為大家分享一篇C++ 將一個文件讀入數(shù)組再讀出數(shù)組的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • C++二分法在數(shù)組中查找關(guān)鍵字的方法

    C++二分法在數(shù)組中查找關(guān)鍵字的方法

    這篇文章主要介紹了C++二分法在數(shù)組中查找關(guān)鍵字的方法,涉及C++數(shù)組查找算法的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • C++中memcpy和memmove的區(qū)別總結(jié)

    C++中memcpy和memmove的區(qū)別總結(jié)

    這篇文章主要介紹了C++中memcpy和memmove的區(qū)別總結(jié),這個問題經(jīng)常出現(xiàn)在C++的面試題目中,需要的朋友可以參考下
    2014-10-10
  • C語言中如何通過指針參數(shù)返回值

    C語言中如何通過指針參數(shù)返回值

    這篇文章主要介紹了C語言中如何通過指針參數(shù)返回值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++面向行輸入之get()與getline()實例詳解

    C++面向行輸入之get()與getline()實例詳解

    在c++里當我們輸入一個字符串時習慣用cin,但是cin只能讀取一段不含空格的字符串,如果我們需要讀取一段包含空格的字符串時,就需要用到getline()或get(),下面這篇文章主要給大家介紹了關(guān)于C++面向行輸入之get()與getline()的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • C語言 數(shù)組指針詳解及示例代碼

    C語言 數(shù)組指針詳解及示例代碼

    本文主要介紹C語言 數(shù)組指針,這里整理了相關(guān)資料并附示例待會及實現(xiàn)結(jié)果,幫助大家學習C語言中指針的知識,有需要學習此部分內(nèi)容的朋友可以參考下
    2016-08-08
  • VC++的if語句應(yīng)用范圍分析

    VC++的if語句應(yīng)用范圍分析

    這篇文章主要介紹了VC++的if語句應(yīng)用范圍分析,對VC++初學者有很好的參考學習價值,需要的朋友可以參考下
    2014-08-08
  • C++超詳細講解構(gòu)造函數(shù)

    C++超詳細講解構(gòu)造函數(shù)

    C++的構(gòu)造函數(shù)的作?:初始化類對象的數(shù)據(jù)成員。即類的對象被創(chuàng)建的時候,編譯系統(tǒng)對該對象分配內(nèi)存空間,并?動調(diào)?構(gòu)造函數(shù),完成類成員的初始化。構(gòu)造函數(shù)的特點:以類名作為函數(shù)名,?返回類型
    2022-06-06
  • C語言項目全正整數(shù)后再計算的三種參考解答方法

    C語言項目全正整數(shù)后再計算的三種參考解答方法

    今天小編就為大家分享一篇關(guān)于C語言項目全正整數(shù)后再計算的三種參考解答方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02

最新評論

中江县| 青川县| 滦南县| 延寿县| 六盘水市| 宁夏| 海淀区| 桓台县| 射阳县| 安徽省| 锡林郭勒盟| 拜城县| 江北区| 岑溪市| 五莲县| 乡宁县| 石泉县| 鱼台县| 广德县| 金坛市| 镇安县| 五莲县| 中宁县| 舞阳县| 迁西县| 周口市| 凤山市| 霍山县| 门头沟区| 云阳县| 廊坊市| 越西县| 定兴县| 桐柏县| 鹿泉市| 东方市| 和林格尔县| 江陵县| 福贡县| SHOW| 成武县|