1.定義與概念
棧
棧是允許在同一端進行插入和刪除操作的特殊線性表。允許進行插入和刪除操作的一端稱為棧頂(top),另一端為棧底(bottom);棧底固定,而棧頂浮動;棧中元素個數為零時稱為空白棧。插入一般稱為進棧(PUSH),刪除則稱為退棧(POP)。棧也稱為後進先出表。
viod *malloc(size_t size)
向系統申請分配指定size個位元組的記憶體空間。傳回型別是 void* 類型。void* 表示未確定類型的指標。C,C++規定,void* 類型可以通過類型轉換強制轉換為任何其它類型的指標。如果分配成功則返回指向被分配記憶體的指標(此儲存區中的初始值不確定),否則返回null 指標NULL。當記憶體不再使用時,應使用free()函數將記憶體塊釋放。函數返回的指標一定要適當對齊,使其可以用於任何資料對象。
realloc原型是extern void *realloc(void *mem_address, unsigned int newsize);
先判斷當前的指標是否有足夠的連續空間,如果有,擴大mem_address指向的地址,並且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有資料從頭到尾拷貝到新分配的記憶體地區,而後釋放原來mem_address所指記憶體地區(注意:原來指標是自動釋放,不需要使用free),同時返回新分配的記憶體地區的首地址。即重新分配儲存空間塊的地址。
2.代碼實現
/*********************************************//* 使用棧將二進位轉換成八/十/十六進位 *//* By Jo 17/05/01 *//********************************************/#include <stdio.h>#include <stdlib.h>#include <math.h>#define STACK_INIT_SIZE 20 //棧初始化大小#define STACKINCREMENT 10 //棧擴容時每次增加大小typedef char ElemType; //以字元形式儲存位元據typedef struct{ElemType *base; //棧低指標ElemType *top; //棧頂指標int stackSize; //棧尺寸}sqStack;//函數功能:初始化棧(為棧分配記憶體空間)//參數*s :棧對象地址 void InitStack(sqStack *s){s->base = (ElemType*)malloc(STACK_INIT_SIZE * sizeof(ElemType));if (!s->base) exit(0);s->top = s->base;s->stackSize = STACK_INIT_SIZE;}//函數功能:資料入棧//參數 *s :棧對象地址//參數 e :待入棧資料void Push(sqStack *s, ElemType e){if (s->top - s->base >= s->stackSize) //棧當前容量大於儲存容量,拓展棧大小{s->base = (ElemType*)realloc(s,(STACK_INIT_SIZE + STACKINCREMENT) * sizeof(ElemType));if (!s->base) exit(0);}*(s->top) = e;s->top++;}//函數功能:資料出棧//參數 *s :棧對象地址//參數 *e :待存放出棧資料的對象地址void Pop(sqStack *s, ElemType *e){if (s->base == s->top) return;*e = *--(s->top); //棧始終指向棧頂,所以棧頂指標先減1再取出值}//函數功能:擷取棧長度//參數s :棧資料對象//(函數若要修改實參,使用指標->;若只是查詢等不修改實參,使用對象本身.)int StackLen(sqStack s){return (s.top - s.base);}//函數功能:清空棧 //參數 *s :棧對象地址void ClearStack(sqStack *s){s->top = s->base;}//函數功能:銷毀棧 //參數 *s :棧對象地址void DestoryStack(sqStack *s){int i, len;len = s->stackSize;for (i = 0; i < len; i++){free(s->base); //從棧底逐資料釋放 s->base++;}s->top = s->base = NULL;s->stackSize = 0;}//函數功能:十六進位轉換//參數 c :待轉換成十六進位表示的字元char ToHexChar(char c){switch (c){case 10:return 'A';case 11:return 'B';case 12:return 'C';case 13:return 'D';case 14:return 'E';case 15:return 'F';default:return c+48; //字元‘0-9’轉換到數字0-9 }}int main(){//1.二進位轉換成十進位/*ElemType c;sqStack s;int len, i, sum = 0;InitStack(&s);printf("輸入位元 以#結束。 \n");scanf("%c",&c); //每次從鍵盤緩衝區唯讀一個字元while (c != '#'){Push(&s, c);scanf("%c",&c);}getchar(); //把‘\n’從緩衝區中去掉len = StackLen(s);printf("二進位棧當前容量為:%d \n",len);for (i = 0; i < len; i++){Pop(&s, &c);sum = sum + (c - 48)*pow(2, i);}printf("二進位轉換成十進位為:%d \n", sum);*///2.二進位轉換成八進位/*ElemType c;sqStack s, sOct;int len, lenOct, i, temp = 0;InitStack(&s);InitStack(&sOct);printf("輸入位元 以#結束。 \n");scanf("%c", &c); //每次從鍵盤緩衝區唯讀一個字元while (c != '#'){Push(&s, c);scanf("%c", &c);}getchar(); //把‘\n’從緩衝區中去掉len = StackLen(s);printf("二進位棧當前容量為:%d \n", len);int count = 0;for (i = 0; i < len; i++){Pop(&s, &c);temp = temp + (c - 48)*pow(2, count);count++;if (count == 3 || (s.top == s.base)){Push(&sOct, temp); //低位放在棧底temp = 0;count = 0;}}lenOct = StackLen(sOct);printf("八進位棧當前容量為:%d \n", lenOct);printf("二進位轉換成八進位為:");for (i = 0; i < lenOct; i++){Pop(&sOct, &c);printf("%d", c);}*///3.二進位轉換成十六進位///*ElemType c;sqStack s, sHex;int len, lenHex, i, temp = 0;InitStack(&s);InitStack(&sHex);printf("輸入位元 以 # 結束。 \n");scanf("%c", &c); //每次從鍵盤緩衝區唯讀一個字元while (c != '#'){Push(&s, c);scanf("%c", &c);}getchar(); //把‘\n’從緩衝區中去掉len = StackLen(s);printf("二進位棧當前容量為:%d \n", len);int count = 0;for (i = 0; i < len; i++){Pop(&s, &c);temp = temp + (c - 48)*pow(2, count);count++;if (count == 4 || (s.top == s.base)) //與八進位的重要區別{Push(&sHex, temp); //低位放在棧底temp = 0;count = 0;}}lenHex = StackLen(sHex);printf("十六進位棧當前容量為:%d \n", lenHex);printf("二進位轉換成十六進位為:");char tempChar;for (i = 0; i < lenHex; i++){Pop(&sHex, &c);tempChar = ToHexChar(c);printf("%c", tempChar);}//*/return 0;}
3.結果