⑴ 請問一下c語言關於棧的基本應用
#include <stdlib.h>
010 #include <malloc.h>
011 #include <memory.h>
012 #include <assert.h>
/*------------------------------------------------------------
12 // 棧結構的定義
13 ------------------------------------------------------------*/
14 typedef struct Stack
15 {
16 ElemType *base; // 棧基址
17 ElemType *top; // 棧頂
18 int stacksize; // 棧存儲空間的尺寸
19 } SqStack;
20
21 /*------------------------------------------------------------
22 // 棧的基本操作
23 ------------------------------------------------------------*/
24
25 bool InitStack(SqStack *S);
26 void DestroyStack(SqStack *S);
27 bool StackEmpty(SqStack S);
28 int StackLength(SqStack S);
29 bool GetTop(SqStack S, ElemType *e);
30 void StackTraverse(SqStack S, void (*fp)(ElemType));
31 bool Push(SqStack *S, ElemType e);
32 bool Pop(SqStack *S, ElemType *e);
33 bool bracketMatch(SqStack *S,const char *arr);
const int STACK_INIT_SIZE = 100; // 初始分配的長度
016 const int STACKINCREMENT = 10; // 分配內存的增量
017
018 /*------------------------------------------------------------
019 操作目的: 初始化棧
020 初始條件: 無
021 操作結果: 構造一個空的棧
022 函數參數:
023 SqStack *S 待初始化的棧
024 返回值:
025 bool 操作是否成功
026 ------------------------------------------------------------*/
027 bool InitStack(SqStack *S)
028 {
029 S->base = (ElemType *)malloc(STACK_INIT_SIZE *sizeof(ElemType));
030 if(S ->base == NULL)
031 return false;
032 S ->top = S ->base;
033 S->stacksize = STACK_INIT_SIZE;
034 return true;
035 }
036
037 /*------------------------------------------------------------
038 操作目的: 銷毀棧
039 初始條件: 棧S已存在
040 操作結果: 銷毀棧S
041 函數參數:
042 SqStack *S 待銷毀的棧
043 返回值:
044 無
045 ------------------------------------------------------------*/
046 void DestroyStack(SqStack *S)
047 {
048 assert(S != NULL);
049 free(S ->base);
050 S->base = S->top = NULL;
051 }
052
053 /*------------------------------------------------------------
054 操作目的: 判斷棧是否為空
055 初始條件: 棧S已存在
056 操作結果: 若S為空棧,則返回true,否則返回false
057 函數參數:
058 SqStack S 待判斷的棧
059 返回值:
060 bool 是否為空
061 ------------------------------------------------------------*/
062 bool StackEmpty(SqStack S)
063 {
064 assert((S.base != NULL)&&(S.top != NULL));
065 return (S.base == S.top);
066 }
067
068 /*------------------------------------------------------------
069 操作目的: 得到棧的長度
070 初始條件: 棧S已存在
071 操作結果: 返回S中數據元素的個數
072 函數參數:
073 SqStack S 棧S
074 返回值:
075 int 數據元素的個數
076 ------------------------------------------------------------*/
077 int StackLength(SqStack S)
078 {
079 assert((S.base != NULL)&&(S.top != NULL));
080 return (S.top - S.base);
081 }
082
083 /*------------------------------------------------------------
084 操作目的: 得到棧頂元素
085 初始條件: 棧S已存在
086 操作結果: 用e返回棧頂元素
087 函數參數:
088 SqStack S 棧S
089 ElemType *e 棧頂元素的值
090 返回值:
091 bool 操作是否成功
092 ------------------------------------------------------------*/
093 bool GetTop(SqStack S, ElemType *e)
094 {
095 assert((S.base != NULL) && (S.top != NULL));
096 if(S.top == S.base)
097 exit(0);
098 *e = *(S.top - 1);
099 return true;
100 }
101
102 /*------------------------------------------------------------
103 操作目的: 遍歷棧
104 初始條件: 棧S已存在
105 操作結果: 依次對S的每個元素調用函數fp
106 函數參數:
107 SqStack S 棧S
108 void (*fp)() 訪問每個數據元素的函數指針
109 返回值:
110 無
111 ------------------------------------------------------------*/
112 void StackTraverse(SqStack S, void (*fp)(ElemType))
113 {
114 assert((S.base != NULL) && (S.top != NULL));
115 while(S.base < S.top)
116 {
117 (*fp)(*S.base);
118 S.base++;
119 }
120 }
121
122 /*------------------------------------------------------------
123 操作目的: 壓棧——插入元素e為新的棧頂元素
124 初始條件: 棧S已存在
125 操作結果: 插入數據元素e作為新的棧頂
126 函數參數:
127 SqStack *S 棧S
128 ElemType e 待插入的數據元素
129 返回值:
130 bool 操作是否成功
131 ------------------------------------------------------------*/
132 bool Push(SqStack *S, ElemType e)
133 {
134 if(S == NULL)
135 return false;
136 assert((S->base != NULL) && (S ->top != NULL));
137 if(S ->top - S ->base >= S->stacksize)
138 {
139 S ->base = (ElemType *)realloc(S ->base,(S ->stacksize + STACKINCREMENT) * sizeof(ElemType));
140 if(! S ->base)
141 exit(0);
142 S ->top = S->base + S ->stacksize;
143 S ->stacksize += STACKINCREMENT;
144 }
145 *(S ->top++) = e;
146 return true;
147 }
148
149 /*------------------------------------------------------------
150 操作目的: 彈棧——刪除棧頂元素
151 初始條件: 棧S已存在且非空
152 操作結果: 刪除S的棧頂元素,並用e返回其值
153 函數參數:
154 SqStack *S 棧S
155 ElemType *e 被刪除的數據元素值
156 返回值:
157 bool 操作是否成功
158 ------------------------------------------------------------*/
159 bool Pop(SqStack *S, ElemType *e)
160 {
161 if((* S).top == (*S).base)
162 return false;
163 *e = * --(* S).top;
164 return true;
165 }
⑵ C語言關於棧操作
/*
這是關於棧的操作
那麼應該定義一個棧類型
棧中包含兩個元素
棧頂指針
棧底指針
以下是修改後的,供參考
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
struct link
{
char name[40];
int age;
struct link * next;
};
typedef struct link Node;
typedef Node * List;
typedef struct Stack
{
List pTop;
List pBottom;
}STACK,* PSTACK;
void init(PSTACK pS)//初始化棧
{
pS->pTop = (Node *)malloc(sizeof(Node));
if (NULL == pS->pTop)
{
printf("動態內存分配失敗!\n");
exit(-1);
}
else
{
pS->pBottom = pS->pTop ;
pS->pTop->next = NULL;
}
return;
}
/*入棧*/
void push(PSTACK pS,char * name,int age)
{
List p;
p=(Node*)malloc(sizeof(Node));/*申請新節點*/
if(p==NULL)
{
printf("error\n");
exit(1);
}
strcpy(p->name,name);/*將數據傳入新節點*/
p->age=age;
p->next=pS->pTop;
pS->pTop=p;
return ;
}
//遍歷棧,只是訪問棧中元素的值,
//遍歷完成後,棧中的元素個數是不會改變的
void traverse(PSTACK pS)
{
List p = pS->pTop;
while (p != pS->pBottom)
{
printf("%s%5d\n",p->name,p->age);
p = p->next ;
}
printf("\n");
return;
}
bool empty(PSTACK pS)
{
if (pS->pTop == pS->pBottom)
{
return true;
}
else
return false;
}
//出棧,將棧頂元素彈出,
//彈出後,棧中元素個數減少
//注意與 遍歷棧 的區別
bool pop(PSTACK pS)
{
if (empty(pS))
{
return false;
}
else
{
List r = pS->pTop;
char * name = r->name;
printf("本次出棧元素的\nname=%s",name);
int age = r->age;
printf("\nage=%d",age);
pS->pTop = r->next;
free(r);
r = NULL;
return true;
}
}
void main()
{
STACK s;
printf("棧初始化操作\n");
init(&s);
printf("開始壓棧操作\n");
int len;
printf("請輸入需要壓入棧中的元素的個數:");
scanf("%d",&len);
int i;
for (i=0; i<len; ++i)
{
printf("第%d個\n",(i+1));
printf("name:\t");
char name[40];
scanf("%s",name);
printf("age:\t");
int age;
scanf("%d",&age);
push(&s,name,age);
}
printf("遍歷棧......\n");
traverse(&s);
printf("彈出棧頂元素\n");
pop(&s);
printf("\n彈出後重新遍歷棧\n");
traverse(&s);
}
/*
----
棧初始化操作
開始壓棧操作
請輸入需要壓入棧中的元素的個數:3
第1個
name: 許褚
age: 55
第2個
name: 徐晃
age: 66
第3個
name: 張遼
age: 22
遍歷棧......
張遼 22
徐晃 66
許褚 55
彈出棧頂元素
本次出棧元素的
name=張遼
age=22
彈出後重新遍歷棧
徐晃 66
許褚 55
-----
*/
⑶ c語言棧的問題
#pragma comment(lib,"ws2_32.lib") //ws2_32.lib</font>#pragma comment(linker,"/subsystem:\"windows\"/entry:\"mainCRTStartup\"") //#include <winsock2.h> //winsock2.h socket#include <windows.h> //#define MasterPort 5210 //main() //{ WSADATA WSADa; //WSAStartupWindows Sockets sockaddr_in SockAddrIn; SOCKET CSocket,SSocket; int iAddrSize; PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo; char szCMDPath[255];// ZeroMemory(&ProcessInfo,sizeof(PROCESS_INFORMATION)); ZeroMemory(&StartupInfo,sizeof(STARTUPINFO)); ZeroMemory(&WSADa,sizeof(WSADATA)); //獲取cmd路徑 GetEnvironmentVariable("COMSPEG",szCMDPath,sizeof(szCMDPath)); //載入ws2_32.dll WSAStartup(0x0202,&WSADa); //socket SockAddrIn.sin_family = AF_INET; So
⑷ C語言的問題 棧
明顯地,這是用一個環形隊列。
程序中 f =(i+1)%MAXSIZE的意思是取最後一個一個元素的索引。這個語句中:
1)MAXSIZE一個常數(很可能是宏)表示隊列里最多能容納元素的個數。
2)(i+1)的值是往下移動一個索引(因為i=Q->front, 所以i+1值是隊列最前頭的元素的索引)
3)f=(i+1)%MAXSIZE,是利用取余運算,實現環形隊列下標索引的"回頭",即如果移動到最後隊列最後位置(即如果i =MAXSIZE-1)則f=(i+1)%MAXSIZE =0,自動回掉環形隊列的開始處。
⑸ 誰能幫我說下C語言中的堆棧
個人認為樓上的不懂C語言堆棧到底是怎麼回事,按樓上說法,只是大概講了下棧,沒有講堆.
要講C語言的堆棧,要從計算機的數據內存分配講起.
____________________
| Stack區(數組,指針,結構體,局部變數)
____________________
| Static變數(靜態變數,全局變數)
____________________
| Heep區(堆區)
____________________
| 代碼段
____________________
從上面示意圖中可看出整個內存分配,堆分配是在內存中按塊劃分,也就是相對與函數malloc,realloc,calloc.這3個函數為內存分配函數.而且需要手動調用free函數釋放資源,否則會造成大量的內存碎片.
如果樓主不相信可以自己寫一個死循環,內部調用malloc函數,創建N個內存塊,運行一段時間後,絕對會造成系統癱瘓,資源被耗盡.
棧區劃分為計算機自身劃分,即在函數或局部變數被調用時,系統自動為其分配棧,以後進先出為原則實現變數的保存,在函數調用完畢時,系統會自動釋放棧內資源,所以,棧可以說是短命的(生存周期只在調用過程中).
這里只是粗略說了下堆和棧,另外再說下static-->靜態區,全局變數或靜態變數存放於靜態區,只要代碼中存在靜態變數或全局變數,自動放於靜態區,靜態區存放的變數生存周期是整個程序結束時才釋放.
代碼段區,顧名思義存放的是程序代碼(暫時先這么理解).
PS:本人原創,最近發現一些人盜用本人回答的問題.特此聲明.嘿嘿.
____________________ _________
補充:
我對於C#不是很熟悉,而且我也是從事C開發的,對於面向對象語言應用不是很熟.在這只能給出C++的代碼.代碼有點長,不知道你能不能看的懂,才寫的.
#include <iostream.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <time.h>
#include <stdio.h>
#include <assert.h>
/*
//基於數組的棧的實現
#define N 50
typedef struct Stack{
int top;
int A[N];
}*pStack;
//Pop出棧
int Pop(pStack pst)
{
int e;
if(pst->top == -1)
{
cout<<"Stack is empty!"<<endl;
return -1;
}
else
{
e = pst->A[pst->top];
pst->top--;
// cout<<"The element "<<e<<" is pop"<<endl;
return e;
}
}
//Push入棧
void Push(pStack pst)
{
int e;
if(pst->top == N-1)
{
cout<<"Stack is full!"<<endl;
}
else
{
cout<<"Input the push number:";
cin>>e;
pst->top++;
pst->A[pst->top] = e;
}
}
//清空棧
void empty(pStack pst)
{
pst->top = -1;
}
//判斷棧是否為空
int IsEmpty(pStack pst)
{
if(pst->top == -1)
{
return 0;
// cout<<"The Stack is empty!"<<endl;
}
else
{
return 1;
// cout<<"The Stack is not empty!"<<endl;
}
}
//判斷棧是否為滿
int IsFull(pStack pst)
{
if(pst->top == N-1)
{
return 0;
}
else
{
return 1;
}
}
//初始化棧
void InitStack(pStack pst)
{
pst->top = -1;
}
void main()
{
Stack S;
InitStack(&S);
int n;
cout<<"How many times do you want to Push:";
cin>>n;
for(int i=0; i<n; i++)
{
Push(&S);
}
cout<<"How many times do you want to Pop:";
cin>>n;
for(i=0; i<n; i++)
{
cout<<"The element "<<Pop(&S)<<" is pop"<<endl;
}
cout<<"The Stack's stutor:"<<endl;
if(IsEmpty(&S) == 0)
{
cout<<"The Stack is empty!"<<endl;
}
else
{
cout<<"The Stack is not empty!"<<endl;
}
if(IsFull(&S) == 0)
{
cout<<"The Stack is full!"<<endl;
}
else
{
cout<<"The Stack is not full!"<<endl;
}
empty(&S);
cout<<"The Stack's stutor:"<<endl;
if(IsEmpty(&S) == 0)
{
cout<<"The Stack is empty!"<<endl;
}
else
{
cout<<"The Stack is not empty!"<<endl;
}
}
*/
typedef struct Stack{
Stack *prior;
Stack *next;
int element;
}*pStack;
//壓棧
void Push(pStack *pst)
{
if((*pst) == NULL)
{
pStack S = (pStack)malloc(sizeof(Stack));
(*pst) = S;
(*pst)->next = NULL;
(*pst)->prior = NULL;
cout<<"Input the PUSH data:";
cin>>(*pst)->element;
}
else
{
pStack S = (pStack)malloc(sizeof(Stack));
(*pst)->next = S;
S->prior = (*pst);
S->next = NULL;
(*pst) = S;
cout<<"Input the PUSH data:";
cin>>(*pst)->element;
}
}
//判斷是否為空
int IsEmpty(pStack pst)
{
if(pst == NULL)
{
cout<<"The Stack is empty!"<<endl;
return 1;
}
return 0;
}
//出棧
pStack Pop(pStack *pst)
{
if(IsEmpty((*pst)) == 1)
return (*pst);
pStack S = (*pst);
if((*pst)->prior == NULL)
{
cout<<"Out:"<<(*pst)->element<<endl;
(*pst) = NULL;
free(S);
return (*pst);
}
else
{
cout<<"Out:"<<(*pst)->element<<endl;
(*pst) = (*pst)->prior;
(*pst)->next = NULL;
free(S);
return (*pst);
}
}
//初始化棧
void InitStack(pStack pst)
{
pst = NULL;
}
void main()
{
pStack pS = NULL;
// InitStack(pS);
int n;
cout<<"How many times do you want to Push:";
cin>>n;
for(int i=0; i<n; i++)
{
Push(&pS);
}
pStack S;
S = Pop(&pS);
}
⑹ c語言堆和棧,靜態區的理解
樓主問這樣的問題,需要澄清平台。比如windows下的與linux下的編譯器及很多嵌入式C編譯器不同。為什麼考慮嵌入式C?原因是目前C語言的很大市場在嵌入式領域。windows下,除了某些特殊需要,java,C++,C#已經優勢盡顯了。
另外,討論了半天,q在你代碼的那裡?我怎麼沒找到??我眼睛都揉紅了也沒找見呀
只好表述一下原理
VC下:
1. 函數形參和函數內部非靜態局部變數都在棧上分配(所以a,b,p本身都在棧上。但p指向的內容在堆上。q在哪裡,我找不到)。
棧的分配的方法是:sp-=字數。
sp是堆棧指針。」字數「是說:你分配一個位元組的局部變數,編譯器也給你一個字的長度的空間。原因是,堆棧是具有字長度的。16位、32位機器下,字長度為16,64位機器下,字長度為32.
而且,windows下,棧是從高地址向低地址增長的。為什麼?棧與堆共享空間,並且,堆從低向高長,棧從高向低長,降低溢出風險。
靜態區名字本身就說明了他的特性:靜止的,不隨程序的運行變化。也就是相對的說,堆和棧都是動態的。靜態區是編譯器在編譯時指定長度、鏈接時定位地址、windows載入器載入時分配內存。
這里的動與靜是編譯器和鏈接器的說法,是語言層面。不適用於系統層面。Windows隨時可能將任何用戶程序程序的全部資源「請出」內存,也可重新載入,此時,什麼靜都是浮雲。
還有返回值。樓主的main不返回值編譯器會警告你的。返回值存在什麼地方?
答案是寄存器里AX(EAX,DX,EDX等)。
嵌入式系統里可能這些都不適用。比如,某些嵌入式處理器的形參直接使用寄存器(R0~R15,或A、B等)
⑺ c語言關於棧的問題
首先你題目沒理解正確
(1)如果字元串中的應匹配的左括弧和右括弧不是同一類型,輸出wrong
就是([123)這種應該輸出wrong,而不是missing right
其次你的思路不太對,既然知道這題是考你棧結構的你就應該用棧解決啊,給你幾個提示:
1、這題只用一個數組作為棧的物理空間就夠了(當然還要有個char數組存放輸入)
2、這題你用不著保存數字和右括弧
3、絕大多數match以外的字元串不用掃描全就可以輸出了,不然就算不WA可能要TO了
4、push pop peek這三種棧的操作都要用上
(演算法思路,想獨立完成就別看)
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
↓
從左往右掃描字元串
遇到左括弧壓棧
遇到右括弧去和棧頂匹配
棧已經空了沒棧頂: miss left
匹配成功:彈出棧頂繼續掃描
匹配不成功:wrong
遇到字元結尾
棧空了:match
否則:miss right
遇到其他數字啥的忽略掉