Void * pointer to support all data types of containers

Source: Internet
Author: User

This is actually a C language class assignment. I expanded my questions.

The core lies in how containers support all data types. My solution is to obtain the length of the Data Type (sizeof) during initialization, and then copy the data one byte at a time when adding the data.

The data structure is as follows:

The linked list + array method is used. I set ELEMENT_NUM to 40.

The statement is as follows:

Struct cInfo; struct cBox; struct cInfo {cBox * head, * tail; int blong, size ;}; struct cBox {cBox * pre, * next; cInfo * info; int move; // use number = move void * pt;}; void _ finit (int bl, cBox & B); // _ finit (sizeof (int), head) void _ fpush (void * data, cBox & B); void fprint (cBox & B, void (* fct) (void *)); // input an output function pointer to output a block void _ fprintAll (cBox & B, void (* fct) (void *); void * ffind (int pos, cBox & B); // call the function internally to find the address at a certain position and return void * _ fget (int pos, cBox & B); // directly return the pointer of the corresponding address, this requires you to carefully use void _ fchange (void * data, int pos, cBox & B); void _ fclean (cBox & B); void fcopy (void * data, void * plc, int bl); // call the void _ finsert (int pos, void * data, cBox & B) function internally; // insert an element at a specific position, if pos> size, it will be pushed to the end

 

 

The implementation of _ finsert is special. Its function is to add an element after the pos position. During the runtime, the corresponding block where the pos position is located will be located. If the block is not full (move <ELEMENT_NUM), the elements of the current block at the position of the pos will be moved down to one unit, and new elements will be written. If the block is full, add a new block with 0 elements next to the block, move half of the current block to the new block, and then perform the operation when the block is full.

 

PS: although it is c code, I am lazy and use c ++ references.

Code:

Box. h # ifndef BOX_H_INCLUDED # define BOX_H_INCLUDED # include <stdio. h> # include <stdlib. h> # include <malloc. h> # define ELEMENT_NUM 40 struct cInfo; struct cBox; struct cInfo {cBox * head, * tail; int blong, size ;}; struct cBox {cBox * pre, * next; cInfo * info; int move; // usage = move void * pt;}; void _ finit (int bl, cBox & B ); // _ finit (sizeof (int), head) void _ fpush (void * data, cBox & B); void fprint (cBox & B, void (* f Ct) (void *); // input the pointer of an output function to output a block void _ fprintAll (cBox & B, void (* fct) (void *)); void * ffind (int pos, cBox & B); // call the function internally to find the address at a certain position and return void * _ fget (int pos, cBox & B ); // The pointer of the corresponding address is directly returned, which requires you to carefully use void _ fchange (void * data, int pos, cBox & B ); void _ fclean (cBox & B); void fcopy (void * data, void * plc, int bl); // call void _ finsert (int pos, void * data, cBox & B); // insert an element in a specific position. If pos> size, it will be pressed to the final void _ finit (I Nt bl, cBox & B) // provides initialization for the user {B .info = (cInfo *) malloc (sizeof (cInfo); cInfo * temp = B .info; temp-> head = temp-> tail = & B; temp-> blong = bl; temp-> size = 0; B. pre = B. next = NULL; B. move = 0; B .pt = malloc (ELEMENT_NUM * (temp-> blong); // still managed by void *} void fcopy (void * data, void * plc, int bl) // The caller ensures that the plc is the correct address {char * wm = (char *) plc; char * d = (char *) data; for (int I = 0; I <bl; ++ I) {* wm = * d; // One byte + + wm, ++ d ;}} void _ fpush (void * data, cBox & tc) // press a data at the tail ;;;; size {cInfo * temp = tc.info; cBox & B = * temp-> tail; if (B. move> = ELEMENT_NUM) // {B. next = (cBox *) malloc (sizeof (cBox); // init cBox * ptn = B. next; ptn-> pre = & B; ptn-> next = NULL; ptn-> info = temp; ptn-> move = 0; ptn-> pt = malloc (ELEMENT_NUM * (temp-> blong); temp-> tail = ptn; // press _ fpush (data, * ptn );} else {void * beg = (Void *) (char *) B .pt + B. move * (temp-> blong); // The first written address fcopy (data, beg, temp-> blong); ++ B. move; ++ temp-> size ;}} void fprint (cBox & B, void (* fct) (void *) // input a pointer to an output function, print a block and call {cInfo * temp = B .info; void * pm = B .pt; // start address for (int I = 0; I <B. move; ++ I) {fct (pm); // print an element pm = (void *) (char *) pm + temp-> blong ); // move to the next position. char is a byte} void _ fprintAll (cBox & B, void (* fct) (void *) {cInfo * t Emp = B .info; cBox * head = temp-> head; while (head! = NULL) {fprint (* head, fct); // print a block head = head-> next; // move to the next block} void * ffind (int pos, cBox & B) // The Internal call function returns {cInfo * temp = B .info; cBox * head = temp-> head if it finds the address at a certain position; // It is ready to traverse int count = 0; if (pos> = temp-> size) // size returns NULL starting from 0; while (count + head-> move <pos) {count + = head-> move; head = head-> next; // move down} // int plc = pos-count has been found; return (void *) (char *) head-> pt + plc * (temp-> B Long); // The first address of the corresponding element} void * _ fget (int pos, cBox & B) {void * beg = ffind (pos, B); return beg ;} void _ fchange (void * data, int pos, cBox & B) // change the element of a location {cInfo * temp = B .info; if (pos> = temp-> size) return; void * plc = ffind (pos, B); // find fcopy (data, plc, temp-> blong); // overwrite} void _ finsert (int pos, void * data, cBox & B) // insert an element after a specific position. If pos> size, it will be compressed to {cInfo * temp = B .info; if (pos> = temp-> size ){ _ Fpush (data, B); return;} int count = 0; cBox * head = temp-> head; while (count + head-> move <pos) // locate the block that should be inserted {count + = head-> move; head = head-> next ;} ///// // bug in here maybe if (head-> move <ELEMENT_NUM) // This block still has space remaining {int mbeg = pos-count; void * pa = (void *) (char *) head-> pt + (head-> move) * (temp-> blong); void * pb = (void *) (char *) head-> pt + (head-> move + 1) * (temp-> blong ); // Pb = pa for (int I = head-> move; I> mbeg; -- I) // move back {fcopy (pa, pb, temp-> blong); pa = (void *) (char *) pa-temp-> blong); pb = (void *) (char *) pb-temp-> blong);} pa = (void *) (char *) pa + temp-> blong); fcopy (data, pa, temp-> blong ); ++ head-> move; ++ temp-> size;} else // This block has no space, and a node is created later, and copy half of the data to {cBox * pct = head-> next; head-> next = (cBox *) malloc (sizeof (cBox )); cBox * pnew = head-> next; Pnew-> pre = head, pnew-> next = pct; pnew-> info = temp; pnew-> move = 0; pnew-> pt = malloc (ELEMENT_NUM * (temp-> blong); if (pct = NULL) temp-> tail = pnew; // move the data int bgnum = ELEMENT_NUM/2; // start to move the number void * pa = (void *) (char *) head-> pt + bgnum * (temp-> blong); void * pb = (void *) (char *) pnew-> pt); while (bgnum <ELEMENT_NUM) {fcopy (pa, pb, temp-> blong); -- head-> move; ++ pnew-> move; pa = (void *)( (Char *) pa + temp-> blong); pb = (void *) (char *) pb + temp-> blong); ++ bgnum ;} // lazy after moving _ finsert (pos, data, B) ;}} void clean (cBox & B) {cInfo * temp = B .info; cBox * head = temp-> head, * tkeep; while (head! = NULL) {tkeep = head; head = head-> next; free (tkeep);} free (temp) ;}# endif // BOX_H_INCLUDED

 

An example. Three types, int, double, and custom, are used only to push and output all functions.

 

Box. cpp # include <stdio. h> # include <stdlib. h> # include "box. h "struct mytype {int a; char B ;}; void int_out (void * data) {int * p = (int *) data; printf (" % d \ n ", * p);} void double_out (void * data) {double * p = (double *) data; printf ("%. 2lf \ n ", * p);} void mytype_out (void * data) {mytype * p = (mytype *) data; printf (" % c-% d \ n ", p-> B, p-> a);} int main () {cBox tInt, tDb, tMy; // test _ finit (sizeof (int ), tInt); // initialize _ finit (sizeof (double), tDb); _ finit (sizeof (mytype), tMy); int ti = 0; double tdb = 0.0; mytype tm = {100}; for (int I = 0; I <; ++ I) {_ fpush (void *) & ti, tInt ); _ fpush (void *) & tdb, tDb); _ fpush (void *) & tm, tMy); ++ ti, ++ tdb; ++ tm. a, ++ tm. b;} _ 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 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.