Ⅰ c語言數組什麼是防止堆棧溢出
inc返回的是數組a第一個元素的地址,也就是說指針b被賦值成數組a第一個元素的地址,也指向數組a,並沒有分配新的內存,a和b指向的是同一個數組。如果需要分配新的內存,可以使用malloc。
b
=
(u8
*)
malloc(8
*
sizeof(u8));
//
動態分配8個大小為u8的空間
Ⅱ c語言數組在內存中是怎麼分配的
C語言中內存為分三類:棧區、堆區、靜態數據區。
局部變數在棧上分配,函數調用前的棧指針,要和函數返回後的棧指針一樣,否則就會出錯。
void test(void)
{
char i,a[10];
printf("0x%x", &i);
printf("0x%x", a);
printf("0x%x", a+1);
printf("0x%x", a+2);
printf("0x%x", a+3);
}
(2)c語言數組堆棧擴展閱讀
c語言數組在內存分配
示例:
#include<stdio.h>
int main()
{
int a[4] = {11,12,13,14};
int b[4] = {21,22,23,24};
int *pa = &a;
int i = 0;
while(i<8)
{
i++;
printf("now *p value = %d and",*pa);
printf("p addr value = %d ",pa);
pa++;
}
return 0;
}
Ⅲ C語言堆棧問題,數組作為函數參數到底是佔用堆空間還是棧空間啊
你這個函數只傳了一個數組的地址,說白了就是一個unsigned long int數,就一個這樣的數你覺得用得著去動用棧棧傳參嗎?X86隨便一個寄存器都能裝得下,一般AX,BX,CX,DX這幾個寄存器對於這種傳幾個字長的參數夠夠的了,只有在寄存器不夠的情況下,參數過多,或參數過大(結構體)才用得著堆棧傳參。另外提醒一下:你這個N是傳不進來的,編譯器只是根據[ ]這個符號來認定array是一個地址,N只能另外做為一個int N 的參數傳進來。
Ⅳ 怎麼用C語言編寫堆棧並能進行四則運算
3個文件,按您的要求
頭文件H
#IFNDEF _XXXX_H
#定義_XXXX_H
#定義錯誤-1
#定義MAX 100 / *定義堆棧的大小* /
靜態int堆棧[MAX]; / *定義一個一維數組堆棧* /
靜態int top = 0的; / *自定義堆棧指令* /
詮釋推(int i)的;
的pop();
#ENDIF / * _XXXX_H * /
功能文件CPP
#包括「xxxx.h」的
詮釋推(I)/ *內存操作數棧操作* /
{
??(頂部<MAX)
???
????棧[+ +頂部] = I / *棧,仍然有空間的堆棧頂部的表示移動一個位置* /
????返回0;
??}
??其他
???
????printf的(「堆棧滿了」);
????返回錯誤;
??}
}
POP()/ *刪除的操作數,並彈出操作* /
{
??VAR; / *定義要返回的頂級元素* /
??如果(top! = NULL)/ *仍然堆放元素* /
???
????VAR =棧[ - ] / *堆棧指針向下移動一個位置* /
????返回VAR / *返回的頂部堆棧元素* /
??}
??其他
????printf的(「堆棧是空的!\ n」);
??返回錯誤;
}
主文件CPP
#包括<stdio.h>
#包括<conio.h>
#包括<stdlib.h>
#包括「xxxx.h」的
無效的主要()
{
??INT M,N;
??字元L;
??整數A,B,C;
??整數K;
??{
????輸出(「\ n \ n \ t單擊以下提示輸入你需要的信息\ n」);
????輸出(「\ n \問你輸入第二個搗弄數字」);
????scanf的(「%d」,&M);
????推(M)/ *第一個操作數堆棧* /
????輸出(「\ n \問你輸入第二個搗弄數字」);
????scanf的(「%d」,&N);
????推(N); / *第二個操作數堆棧* /
????輸出(「\ n \你不想算術運算(+ / - / * / /):」);
????L = getche(); / *輸入操作符* /
????開關(L)/ *確定的運營商,依次執行代碼* /
????
??????'+':
????????= pop()方法;
????????= pop()方法;
????????C = A + B;
????????輸出(「\ n \ n \ t計算公式為:%d條\ n」,c);
????????輸出(「\ n」);
????????;
??????情況下,' - ':
????????= pop()方法;
????????= pop()方法;
????????C = A-B;
????????輸出(「\ n \ n \ t計算公式為:%d條\ n」,c);
????????輸出(「\ n」);
????????;
??????情況下,'*':
????????= pop()方法;
????????= pop()方法;
????????C = A * B;
????????輸出(「\ n \ n \ t計算公式為:%d條\ n」,c);
????????輸出(「\ n」);
????????;
??????情況下,'/':
????????= pop()方法;
????????= pop()方法;
????????C = A / B;
????????輸出(「\ n \ n \ t計算公式為:%d條\ n」,c);
????????輸出(「\ n」);
????????;
????}
????輸出(「\ t要繼續輸入計算嗎?(Y / N):」); / *提示用戶是否在程序結束* /
????L = getche();
????(L =='N')
??????退出(0);
??}(1);
}
Ⅳ C語言中的棧、堆是什麼
C語言中的堆和棧都是一種數據項按序排列的數據結構。
棧就像裝數據的桶或箱子
我們先從大家比較熟悉的棧說起吧,它是一種具有後進先出性質的數據結構,也就是說後存放的先取,先存放的後取。
這就如同我們要取出放在箱子裡面底下的東西(放入的比較早的物體),我們首先要移開壓在它上面的物體(放入的比較晚的物體)。
堆像一棵倒過來的樹
而堆就不同了,堆是一種經過排序的樹形數據結構,每個結點都有一個值。
通常我們所說的堆的數據結構,是指二叉堆。堆的特點是根結點的值最小(或最大),且根結點的兩個子樹也是一個堆。
由於堆的這個特性,常用來實現優先隊列,堆的存取是隨意,這就如同我們在圖書館的書架上取書。
雖然書的擺放是有順序的,但是我們想取任意一本時不必像棧一樣,先取出前面所有的書,書架這種機制不同於箱子,我們可以直接取出我們想要的書。
(5)c語言數組堆棧擴展閱讀:
關於堆和棧區別的比喻
使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等准備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。
參考資料來源:網路-堆棧
Ⅵ 一個C語言堆棧的問題
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedefstruct
{
chardata[50];
inttop;
}seqstack;
main()
{
chara[50]={0};
inti;
seqstack*s=(seqstack*)malloc(sizeof(seqstack));
s->top=-1;
scanf("%s",a);
for(i=0;i<strlen(a);i++)
if(a[i]=='(')
{
s->top++;
s->data[s->top]='(';
}
elseif(a[i]==')')
{
if(s->top<0)
{
printf("underflow");
break;
}
else
{
if(s->data[s->top--]!='('){
printf("error");
break;
}
}
}
if(s->top==-1)printf("correct");
elseprintf("error");
return0;
}
Ⅶ 關於C語言堆棧的問題!
C語言中堆棧說的是數據結構,和系統中的堆棧中是不一樣的,/*
**用一個靜態數組實現的堆棧。數組的長度只能通過修改#define的定義
**並對模塊重新進行編譯
*/#include"stack.h"
#include<assert.h>#define STACK_SIZE 100 /*堆棧中值數量的最大限制*//*
**存儲堆棧中值的數組和一個指向堆棧頂部元素的指針
*/
static STACK_TYPE stack[STACK_SIZE];
static int top_element =-1;/*push*/
void push(STACK_TYPE value)
{
assert(!is_full());
top_element +=1;
stack[top_element]=value;
}/*pop*/
STACK_TYPE pop(void)
{
STACK_TYPE temp;
assert(!is_empty());
temp=stack[top_element];
top_element -= 1;
return temp;
}/*top*/
STACK_TYPE top (void)
{
assert(!is_empty());
return stack[top_element];
}/*
** is _empty
*/
int is_empty(void)
{
return top_element == -1;
}/*
**is_full
*/
int is_full(void)
{
return top_element ==STACK_SIZE -1;
}這是個靜態堆棧,你可以動態的申請內存來編寫動態堆棧
Ⅷ 誰能幫我說下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語言的堆棧是怎麼回事!!
堆(heap)和棧(stack)有什麼區別??
簡單的可以理解為:
heap:是由malloc之類函數分配的空間所在地。地址是由低向高增長的。
stack:是自動分配變數,以及函數調用的時候所使用的一些空間。地址是由高向低減少的。
預備知識—程序的內存分配
一個由c/C++編譯的程序佔用的內存分為以下幾個部分
1、棧區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3、全局區(靜態區)(static)—,全局變數和靜態變數的存儲是放在一塊的,初始化的全局變數和靜態變數在一塊區域, 未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域。 - 程序結束後有系統釋放
4、文字常量區 —常量字元串就是放在這里的。 程序結束後由系統釋放
5、程序代碼區—存放函數體的二進制代碼。
二、例子程序
這是一個前輩寫的,非常詳細
//main.cpp
int a = 0; 全局初始化區
char *p1; 全局未初始化區
main()
{
int b; 棧
char s[] = "abc"; 棧
char *p2; 棧
char *p3 = "123456"; 123456在常量區,p3在棧上。
static int c =0; 全局(靜態)初始化區
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得來得10和20位元組的區域就在堆區。
strcpy(p1, "123456"); 123456放在常量區,編譯器可能會將它與p3所指向的"123456"優化成一個地方。
}
二、堆和棧的理論知識
2.1申請方式
stack:
由系統自動分配。 例如,聲明在函數中一個局部變數 int b; 系統自動在棧中為b開辟空間
heap:
需要程序員自己申請,並指明大小,在c中malloc函數
如p1 = (char *)malloc(10);
在C++中用new運算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在棧中的。
2.2
申請後系統的響應
棧:只要棧的剩餘空間大於所申請空間,系統將為程序提供內存,否則將報異常提示棧溢出。
堆:首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,
會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。
2.3申請大小的限制
棧:在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
2.4申請效率的比較:
棧由系統自動分配,速度較快。但程序員是無法控制的。
堆是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,他不是在堆,也不是在棧是直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度, 也最靈活
2.5堆和棧中的存儲內容
棧: 在函數調用時,第一個進棧的是主函數中後的下一條指令(函數調用語句的下一條可執行語句)的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,然後是函數中的局部變數。注意靜態變數是不入棧的。
當本次函數調用結束後,局部變數先出棧,然後是參數,最後棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續運行。
堆:一般是在堆的頭部用一個位元組存放堆的大小。堆中的具體內容有程序員安排。
2.6存取效率的比較
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在運行時刻賦值的;
而bbbbbbbbbbb是在編譯時就確定的;
但是,在以後的存取中,在棧上的數組比指針所指向的字元串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
對應的匯編代碼
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一種在讀取時直接就把字元串中的元素讀到寄存器cl中,而第二種則要先把指edx中,在根據edx讀取字元,顯然慢了。
?
2.7小結:
堆和棧的區別可以用如下的比喻來看出:
使用棧就象我們去飯館里吃飯,只管點菜(發出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等准備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜餚,比較麻煩,但是比較符合自己的口味,而且自由度大。
堆和棧的區別主要分:
操作系統方面的堆和棧,如上面說的那些,不多說了。
還有就是數據結構方面的堆和棧,這些都是不同的概念。這里的堆實際上指的就是(滿足堆性質的)優先隊列的一種數據結構,第1個元素有最高的優先權;棧實際上就是滿足先進後出的性質的數學或數據結構。
雖然堆棧,堆棧的說法是連起來叫,但是他們還是有很大區別的,連著叫只是由於歷史的原因針值讀
Ⅹ 數組堆棧c語言編碼
#include <stdio.h>#include <stdlib.h>#define Size 20 typedef char ElementType;typedef struct{ ElementType data[Size]; int top;}Stack; int StackFull(Stack *s){ return (s->top==Size-1);} void PushStack(Stack *s, char *buf){ if(NULL==s || NULL==buf) return; while( *buf!='\0' && *buf!='^' && !StackFull(s)) { if(*buf != ' ') s->data[++s->top] = *buf; ++buf; }} void PopStack(Stack *s){ if(NULL == s) return; while(s->top != -1) putchar(s->data[s->top--]);} int main(){ char str[Size]; Stack *s = (Stack*)malloc(sizeof(Stack)); s->top = -1; gets(str); PushStack(s, str); PopStack(s); return 0;}