通用栈

栈是一种用得比较多的数据结构,用处很广。但很多时候,栈中的元素是不一样的。那如何写一个通用的栈呢。在C++中有模板,那如何用C实现通用的栈呢。

在C语言中,不同的数据类型,占用的字节数不一样。参考qsort对不同数据类型的排序方法,可以得知,使用一个指针,以及此类型的大小即可。

具体的请参考以下代码实现。

/*实现通用的栈结构
 */

#include <stdio.h>


typedef struct
{
	char *base, *top;
	int item_size; //栈中每个元素所占的字节数。
	int item_num;
}stack;

/* 创建含有item_num个元素,每个元素占有item_size个字节数的栈
 * 返回栈的指针
 * */
stack * create_stack(stack *s, int item_size, int item_num);

/* 释放栈空间 */
void free_stack(stack *s);

/* 判断栈是否已满 */
int is_full(stack *s);

/* 判断栈是否为空 */
int is_empty(stack *s);

/* push item 所指向的元素进栈*/
void push(stack *s, const void *item);

void pop(stack *s, void *item);

//方便操作的宏定义
#define PUSH(s,e) do {\
	push(&s, (char*)&e);\
	}while(0);

#define POP(s,e) do{\
	pop(&s, (char*)&e);\
}while(0);

int main()
{
	stack s;
	create_stack(&s, sizeof(char), 10);

	char c;
	
	c = 'a';
	PUSH(s, c);

	c = 'b';
	PUSH(s, c);

	c = 'c';
	PUSH(s, c);

	c = 0;
	POP(s, c);
	printf("%c\n", c);

	POP(s, c);
	printf("%c\n", c);

	//pop(&s, c);
	POP(s, c);
	printf("%c\n", c);

	free(&s);

	return 0;
}


/* 创建含有ele_num个元素,每个元素占有item_size个字节数的栈
 * 返回栈的指针
 * */
stack * create_stack(stack *s, int item_size, int item_num)
{
	if (s == NULL) 
		return NULL;

	item_num = item_num>0 ? item_num : 1;
	s->base = s->top = (char*)malloc(item_size * item_num);
	s->item_num = item_num;
	s->item_size = item_size;

	if (s->base==NULL)
		return NULL;
	else
		return s;
}

/* 释放栈空间 */
void free_stack(stack *s)
{
	free(s->base);
	s->base = s->top = NULL;
}

/* 判断栈是否已满 */
int is_full(stack *s)
{
	if ((s->top - s->base)/s->item_size >= s->item_num)
		return 1;
	else
		return 0;
}

/* 判断栈是否为空 */
int is_empty(stack *s)
{
	if (s->top - s->base == 0)
		return 1;
	else
		return 0;
}

void push(stack *s, const void *item)
{
	if (is_full(s))
		return;
	void *p = &item;

	memcpy(s->top, item, s->item_size);
	s->top += s->item_size;
} 


void pop(stack *s, void *item)
{
	if (is_empty(s))
		return;

	s->top -= s->item_size;
	memcpy(item, s->top, s->item_size);
} 
为了更符合使用习惯,将pop和push函数经过宏封闭。


缺点:push时,不能是常量,如 push(s, 'a')这种,因为取地址编译不通过。

好的,下面是 C++ 中通用类的定义及实现: ```c++ #include <iostream> using namespace std; template <class T> class Stack { private: T* data; // 数据 int top; // 顶指针 int size; // 大小 public: Stack(int s) { data = new T[s]; top = -1; size = s; } ~Stack() { delete[] data; } bool push(T element) { if (top >= size - 1) { return false; // 满 } top++; data[top] = element; return true; } bool pop(T& element) { if (top < 0) { return false; // 空 } element = data[top]; top--; return true; } bool isEmpty() { return top == -1; } }; int main() { Stack<int> intStack(5); // 创建一个大小为 5 的 int 类型 Stack<char> charStack(5); // 创建一个大小为 5 的 char 类型 // 向 int 中添加元素 cout << "向 int 中添加元素:" << endl; for (int i = 0; i < 6; i++) { if (intStack.push(i)) { cout << "Push " << i << " 成功" << endl; } else { cout << "Push " << i << " 失败" << endl; } } // 从 int 中弹出元素 cout << "从 int 中弹出元素:" << endl; int element; while (intStack.pop(element)) { cout << "Pop " << element << " 成功" << endl; } // 向 char 中添加元素 cout << "向 char 中添加元素:" << endl; for (char c = 'a'; c <= 'f'; c++) { if (charStack.push(c)) { cout << "Push " << c << " 成功" << endl; } else { cout << "Push " << c << " 失败" << endl; } } // 从 char 中弹出元素 cout << "从 char 中弹出元素:" << endl; char ch; while (charStack.pop(ch)) { cout << "Pop " << ch << " 成功" << endl; } return 0; } ``` 程序中定义了一个模板类 `Stack`,可以用来创建不同类型的通用。在 `main` 函数中,我们使用 `int` 类型和 `char` 类型分别创建了两个大小为 5 的,并对进行了 push 和 pop 操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值