我的大学教授告诉我们,通用堆栈看起来像这样(我基本上从课程支持文件中复制粘贴):
typedef struct
{ size_t maxe, dime;
char *b, *sv, *vf;
} TStiva, *ASt;
#define DIME(a) (((ASt)(a))->dime)
#define BS(a) (((ASt)(a))->b)
#define SV(a) (((ASt)(a))->sv)
#define VF(a) (((ASt)(a))->vf)
#define DIMDIF(s,d) (DIME(s) != DIME(d))
#define VIDA(a) (VF(a) == BS(a))
#define PLINA(a) (VF(a) == SV(a))
// Function Declarations
void* InitS(size_t d,...);
int Push(void* a, void* ae);
int Pop (void* a, void* ae);
int Top (void* a, void* ae);
void *InitS(size_t d,...)
{ ASt a = (ASt)malloc(sizeof (TStiva));
va_list ap;
if (!a) return NULL;
va_start(ap,d);
a->maxe = va_arg(ap,size_t);
va_end(ap);
a->dime = d;
a->b = (char*)calloc(a->maxe, d);
if (!a->b) { free(a); return NULL; }
a->vf = a->b;
a->sv = a->b + d * a->maxe;
return (void *)a;
}
int Push(void *a, void *ae)
{ if( PLINA(a)) return 0;
memcpy (VF(a), ae, DIME(a));
VF(a) += DIME(a);
return 1;
}
int Pop(void *a, void *ae)
{ if(VIDA(a)) return 0;
VF(a) -= DIME(a);
memcpy (ae, VF(a), DIME(a));
return 1;
}
int Top(void *a, void *ae)
{ if(VIDA(a)) return 0;
memcpy (ae, VF(a)-DIME(a), DIME(a));
return 1;
}
无论如何,这是一个通用的堆栈实现 with vectors ,从中我不明白为什么在 Top
, Push
和 Pop
函数中需要将堆栈数据结构称为 void *
.
通用,是不是意味着 value the data structure wants to hold is generic ?这意味着,如果您将通用数据结构称为typedef而不是 void *
,那么它不是通用的't certainly mean that it' .
我问这个是因为我要创建一个使用链接列表实现的通用堆栈,我有点困惑 .
这是我的通用链表数据结构:
typedef struct Element {
struct Element *next;
void *value;
} TElement, *TList, **AList;
对于堆栈:
typedef struct Stack {
size_t size;
TList top;
} TStack, *AStack;
/* Function Definitions */
TStack InitStack(size_t);
void DeleteStack(AStack);
int Push(TStack, void*);
int Pop(TStack, void*);
int Top(TStack, void*);
在我的实现中,有什么似乎不通用吗?
3 回答
通用意味着它可以保存任何数据类型(
char*
,int*
等等),或包含任何数据类型 .C
中的空指针void *
允许您按原样投射物品并将这些物品取出(必须在检索时重新投射它们) .因此,它允许程序忽略您在自定义数据结构中的数据类型 .
参考结构本身(只要您没有指定所述结构中保存的数据),不会破坏一般性 . 因此,只要在该堆栈内操作的数据是通用的(id est
void *
),就可以在函数中特别提及TStack
.void*
用于通用目的 . 想象一下它作为指向内存的指针,当然内存可以容纳任何东西 .void*
你的意思是你不知道你指的是什么,但你知道你指的是什么 .是的
void*
可以正确实现通用堆栈,但这会产生一个问题,您不知道存储在堆栈中的数据类型 .void*
的概念是它指向一些有效的内存块,但是对于内存的类型绝对没有任何线索 . 因此,使用此通用堆栈的代码必须显式进行类型转换 .void*
仅用于存储数据,不允许使用它们进行操作 .