void 指標實現支援所有資料型別的容器

2022-05-10 04:46:46 字數 3799 閱讀 9191

這其實是一次c語言課的作業。自己拓展了一下題目。

核心就在於如何實現容器對所有資料型別的支援。我的解決方案是在初始化的時候獲得資料型別的長度(sizeof),以後在新增資料的時候乙個位元組乙個位元組地拷貝。

資料結構如下圖:

採用的是鍊錶+陣列的做法。我把element_num設為了40。

宣告如下:

struct cinfo;

struct cbox;

struct cinfo

;struct cbox

;void _finit( int bl,cbox &b ); // _finit( sizeof(int),head )

void _fpush( void *data,cbox &b );

void fprint( cbox &b,void (*fct)( void *) ); //傳入乙個輸出函式的指標 輸出乙個塊

void _fprintall( cbox &b,void (*fct)(void *));

void* ffind( int pos,cbox &b ); //內部呼叫函式 找到某個位置的位址返回

void* _fget( int pos,cbox &b ); //直接返回的是相應位址的指標,這就要求使用者小心使用

void _fchange( void *data,int pos,cbox &b );

void _fclean( cbox &b );

void fcopy( void *data,void *plc,int bl ); //內部呼叫函式

void _finsert( int pos,void *data,cbox &b ); //在特定位置插入乙個元素,如果pos>size,會被壓到最後

其中_finsert的實現方式比較特殊,它的功能是在pos位置以後加入乙個元素。執行時會找到pos位置所在的相應塊,如果塊沒滿( move < element_num ),就將pos對應位置一下的當前塊的元素下移乙個單位,然後寫入新元素。如果滿了,就在那個塊後面加入乙個0個元素的新塊,把當前塊的一半元素移動到新塊,然後執行假設一沒滿時候的操作。

ps:雖說是c的**,但是我偷懶用了c++的引用。

**:

box.h

#ifndef box_h_included

#define box_h_included

#include #include #include

#define element_num 40

struct cinfo;

struct cbox;

struct cinfo

;struct cbox

;void _finit( int bl,cbox &b ); // _finit( sizeof(int),head )

void _fpush( void *data,cbox &b );

void fprint( cbox &b,void (*fct)( void *) ); //傳入乙個輸出函式的指標 輸出乙個塊

void _fprintall( cbox &b,void (*fct)(void *));

void* ffind( int pos,cbox &b ); //內部呼叫函式 找到某個位置的位址返回

void* _fget( int pos,cbox &b ); //直接返回的是相應位址的指標,這就要求使用者小心使用

void _fchange( void *data,int pos,cbox &b );

void _fclean( cbox &b );

void fcopy( void *data,void *plc,int bl ); //內部呼叫函式

void _finsert( int pos,void *data,cbox &b ); //在特定位置插入乙個元素,如果pos>size,會被壓到最後

void _finit( int bl,cbox &b ) //提供給使用者初始化

void fcopy( void *data,void *plc,int bl ) //呼叫者確保plc是正確的位址

}void _fpush( void *data,cbox &tc ) //壓入乙個資料在最尾部 ;;;;size

else

}void fprint( cbox &b,void (*fct)( void *) ) //傳入乙個輸出函式的指標,列印乙個塊,內部呼叫

}void _fprintall( cbox &b,void (*fct)(void *) )

}void* ffind( int pos,cbox &b ) //內部呼叫函式 找到某個位置的位址返回

//已經找到了

int plc = pos - count;

return (void*)( (char*)head->pt + plc*(temp->blong) ); //相應元素的首位址

}void* _fget( int pos,cbox &b )

void _fchange( void *data,int pos,cbox &b ) //改變某個位置的元素

void _finsert( int pos,void *data,cbox &b ) //在特定位置之後插入乙個元素,如果pos>size,會被壓到最後

int count = 0;

cbox *head = temp->head;

while( count + head->move < pos ) //找到應該插入的那個塊

////////////////////////bug in here maybe

if( head->move < element_num ) //本塊還有剩餘空間

pa = (void*)( (char*)pa + temp->blong);

fcopy( data,pa,temp->blong );

++head->move;

++temp->size;

}else

//本塊沒有空間了,在後面開闢乙個節點,並將一半的資料拷貝過去

//移動完畢 偷懶的做法

_finsert( pos,data,b );

}}void clean( cbox &b )

free(temp);

}#endif // box_h_included

乙個使用例子。使用了三種型別,int,double和自定義型別,只用到了壓入和輸出全部的功能

box.cpp

#include #include #include "box.h"

struct mytype

;void int_out( void *data )

void double_out( void *data )

void mytype_out( void *data )

int main()

; for( int i = 0;i < 100;++i )

_fprintall(tint,int_out);

system("pause");

system("cls");

_fprintall(tdb,double_out);

system("pause");

system("cls");

_fprintall(tmy,mytype_out);

system("pause");

system("cls");

return 0;

}

MySQL支援所有標準SQL數值資料型別

mysql支援所有標準sql數值資料型別。這些型別包括嚴格數值資料型別 integer smallint decimal和numeric 以及近似數值資料型別 float real和double precision 關鍵字int是integer的同義詞,關鍵字dec是decimal的同義詞。bit資...

Bro支援的資料型別

bro ids的策略層分析和檢測元件是由一種指令碼語言實現的,這種指令碼語言主要面向網路連線和流量的處理,支援特定的型別。bro資料型別系統支援18種資料型別 bro指令碼中的每個變數都必須是上述型別之一。對於大多數型別,有很多方式將變數指定為常量。例如,2.71828是乙個雙精度型別的常量,80 ...

SQLite支援的資料型別

一般資料採用的固定的靜態資料型別,而sqlite採用的是動態資料型別,會根據存入值自動判斷。sqlite具有以下五種資料型別 1.null 空值。2.integer 帶符號的整型,具體取決有存入數字的範圍大小。3.real 浮點數字,儲存為8 byte ieee浮點數。4.text 字串文字。5.b...