//既然在这里开始,那就在这里结束。
实现stack 功能
____coding
_using subfunction to focus on the main aim of current function
_void* is not allowed to do arithmetic operation
_makde sure parameters are valid before using them,especially related to pointer.
_____assert测试
assert带有一个断言作为int 类型参数,断言是指正常情况下为真的表达式。assert是一个宏,但是用函数实现的。
当参数为0,编译停止,提供参数信息输出显示。调试结束后,取消assert测试,只需加上一句
#define NDEBUG 在#include "assert.h"之前。
____void * realloc(void * p, int size);
return the same pointer in the parameter.
if current space is not enough, than go to a new place ,a pointer will be returned correspondly. The orighinal dates will be coped into the new space,2 cases: 1,integars will be copied directly. 2,if char,will consider the dates as address pointing at the char,so in the new space ,also address is copied and stored....
____when dealing with pointers, make sure the pointer is valid one.use assert to perform the check.
____stark 的char 型实现。
typedef struct { uchar length; uchar allocSize; uchar* elem; }stack; void stackNew(stack *s); void stackDispose(stack *s); void stackPush(stack *s, uchar* date); void stackPop(stack *s, uchar* date); void stackNew(stack *s) { assert(s!=NULL); s->length = 0; s->allocSize = 4; s->elem = malloc(4*sizeof(uchar)); assert(s->elem != NULL); } void stackDispose(stack *s) { assert(s != NULL && s->elem != NULL); free(s->elem); } void stackPush(stack *s, uchar* date) { assert(s!=NULL && date != NULL); if(s->length == s->allocSize) { s->allocSize *= 2; s->elem = realloc(s->elem,s->allocSize); //reallocate designate size assert(s->elem != NULL); } *(s->elem+s->length) = *date; //s->elem[s->length-1] = *date; s->length += 1; } void stackPop(stack *s, uchar* date) { assert(s!=NULL && date!=NULL); assert(s->length >= 1); --s->length; *date = s->elem[s->length]; }
stack generic function
typedef struct { void* elem; uchar elemSize; uchar logicalLen; uchar allocSize; }stack; void stackNew(stack *s,uchar elemSize); void stackDispose(stack *s); void stackPush(stack *s,void* elemAdder); void stackPop(stack *s,void* elemAdder); void stackNew(stack *s,uchar elemSize) { assert(s!=NULL); assert(elemSize >= 0); //parameter check s->elemSize = elemSize; s->logicalLen = 0; s->allocSize = 4; s->elem = malloc(4*elemSize); assert(s->elem != NULL); } void stackDispose(stack *s) { assert(s != NULL && s->elem != NULL); free(s->elem); } static void stackGrow(stack*s) // use static to prenvent the calling from other files. { s->allocSize *= 2; s->elem = realloc(s->elem,s->allocSize); //reallocate designate size assert(s->elem != NULL); } void stackPush(stack *s,void* elemAdder) { // assert(s!=NULL && elemAdder != NULL); if(s->logicalLen == s->allocSize) { ////Using subfunction to focuse one the key point. stackGrow(s); } //// void* is not allowed to perform arithmetic operation void* target = (uchar*)s->elem + s->logicalLen * s->elemSize; memcpy(target,elemAdder,s->elemSize); s->logicalLen += 1; } void stackPop(stack *s, void* elemAddre) { // assert(s!=NULL && elemAdder != NULL); assert(s->logicalLen >= 1); s->logicalLen -= 1;; void* position = (uchar*)s->elem + s->logicalLen * s->elemSize; memcpy(elemAddre,position,s->elemSize); }
int main() { const char* friends[3] = {"a1","b2","c3"}; stack stringStack; uchar i; uchar* copy; stackNew(&stringStack,sizeof(uchar**)); for(i = 0;i < 3;i++) { copy =strdup(friends[i]); stackPush(&stringStack,©); } char *name; for(i = 0; i < 3; i++) { stackPop(&stringStack,&name); printf("%s ",name); free(name); } stackDispose(&stringStack); return 0; }
//在之前的程序上修改新的功能时,多了出现bug的机会
一行一行检查,避免疏忽造成的错误
就算出错了也不要紧,一行一行找,总是可以找到问题。
这世界上再也没有比程序的运行更确定的事情,这也是我喜欢这一行的原因