国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

什么是棧,為什么函數(shù)式編程語言都離不開棧?

這篇具有很好參考價值的文章主要介紹了什么是棧,為什么函數(shù)式編程語言都離不開棧?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


一、什么是棧,什么是FILO

? 棧是一種具有特殊訪問方式的存儲空間,它的特殊性在于,最后進(jìn)入這個空間的數(shù)據(jù),最先出去,可以畫圖來描述一下這種操作方式。

假設(shè)有一個盒子和三本書,依次將三本書他們放入盒子中。

入棧模擬圖

什么是棧,為什么函數(shù)式編程語言都離不開棧?

? 現(xiàn)在有一個問題,如果一次只能取一本,我們?nèi)绾螌鴱暮凶又腥〕鰜恚?/p>

? 顯然必須從盒子的最上邊開始取,依次取出,和放入的順序剛好相反。

出棧模擬圖

什么是棧,為什么函數(shù)式編程語言都離不開棧?

? 從程序化的角度來講,應(yīng)該有一個標(biāo)記,這個標(biāo)記一直指示著盒子最上邊的書。

? 如果說,上圖中的盒子就是一個棧,我們可以看出棧的兩個基本操作:入棧和出棧。入棧就是將一個新元素放到棧頂,出棧就是從棧頂取出一個元素,棧頂?shù)脑乜偸亲詈笕霔?,需要出棧時,有最先被從棧中取出。棧的這種操作被稱為:LIFO(last in first out),后進(jìn)先出

二、棧的作用是什么,為什么編程語言函數(shù)調(diào)用都選擇用棧?

? 為何現(xiàn)如今所有的編程語言都會采用棧來進(jìn)行函數(shù)調(diào)用?函數(shù)調(diào)用的狀態(tài)之所以用棧來記錄是因為這些數(shù)據(jù)的存活時間滿足“先進(jìn)后出”(FILO)順序,而棧的基本操作正好就是支持這種順序訪問的。下面用一組程序舉例。

void test1(){}

void test2() {
	test1();
}

void test3() {
	test2();
}

int main() {
	test3();
}

這個程序運行的順序為:main() ——》 test3() ——》 test2() ——》 test1() ——》 return from test1() ——》 return from test2() ——》 return from test3() ——》 return from test4().

? 可以看到,調(diào)用者的生命周期總是長于被調(diào)用者的生命周期,并且后者在前者之內(nèi)。被調(diào)用者的數(shù)據(jù)總是后于調(diào)用者的,而其釋放順序總是先于調(diào)用者,所以正好可以滿足LIFO順序,選用棧這種數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)函數(shù)調(diào)用則是一種自然而然的選擇。

什么是棧,為什么函數(shù)式編程語言都離不開棧?

三、使用C模擬實現(xiàn)解析棧

? 前面說過棧的兩個基本操作,入棧和出棧,都只是對棧頂進(jìn)行操作,??梢杂脭?shù)組實現(xiàn)也可以用鏈表實現(xiàn),這里講解用數(shù)組實現(xiàn),因為數(shù)組實現(xiàn)相對來說更優(yōu)一些,數(shù)組實現(xiàn)在尾部插入數(shù)據(jù)代價比較小。

1.結(jié)構(gòu)體的定義

? 由于各種操作都只在棧頂進(jìn)行,選擇定義一個top來記錄棧頂?shù)奈恢?,為了?jié)省空間選擇定義一個capacity來記錄最大長度,如果等于top的話進(jìn)行擴(kuò)容。

typedef int STDataType;
typedef struct StackNode {
	STDataType* arr;
	int capacity;
	int top;
}STNode;

2.棧的創(chuàng)建及銷毀

? 由于函數(shù)內(nèi)有對參數(shù)指針的引用,加上assert預(yù)防程序崩潰,易于調(diào)試,top初始化為-1(也可以初始化為0,個人偏向初始化為-1),兩者的區(qū)別就是一個是棧頂指向棧頂數(shù)據(jù),一個指向棧頂數(shù)據(jù)的下一個,其實本質(zhì)上差不多。

void STInit(STNode* pst)
{
	assert(pst);
	pst->arr = NULL;
	pst->capacity = 0;
	pst->top = -1;
}

void STDestroy(STNode* pst)
{
	assert(pst);
	free(pst->arr);
	pst->arr = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

3.實現(xiàn)入棧操作

? 如果棧已經(jīng)滿了,則進(jìn)行擴(kuò)容,將數(shù)據(jù)放到棧頂。

void STPush(STNode* pst,STDataType x)
{
	assert(pst);
	if (pst->capacity==pst->top+1)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* temp = NULL;
		temp = (STDataType*)realloc(pst->arr,sizeof(STDataType) * newcapacity);
		if (temp == NULL)
		{
			perror("malloc error");
			return;
		}
		pst->arr = temp;
		pst->capacity = newcapacity;
	}
	pst->arr[++pst->top] = x;
}

4.獲取棧頂元素及出棧操作

? 出棧操作將棧頂元素向下移動即可,甚至無需刪除數(shù)據(jù),因為再次進(jìn)行入棧會將其覆蓋掉。獲取棧頂元素要獲取top的下一個位置,因為top是先存后加。

bool STEmpty(STNode* pst)
{
	return pst->top == -1;
}

void STPop(STNode* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}

STDataType STTop(STNode* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	return pst->arr[pst->top];
}

5.獲取棧中有效元素個數(shù)

由于數(shù)組偏移度是從0開始存數(shù)據(jù),所以指向棧頂?shù)膖op比實際上個數(shù)要少1,真正有效元素個數(shù)要將top+1。

int StackSize(STNode* pst)
{
	assert(pst);
	return pst->top+1;
}

源代碼分享

//stack.h
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int STDataType;
typedef struct StackNode {
	STDataType* arr;
	int capacity;
	int top;
}STNode;


void STInit(STNode* pst);
void STPush(STNode* pst,STDataType);
void STPop(STNode* pst);
void STDestroy(STNode* pst);
bool STEmpty(STNode* pst);
STDataType STTop(STNode* pst);
//stack.c
#include "stack.h"


bool STEmpty(STNode* pst)
{
	return pst->top == -1;
}



void STInit(STNode* pst)
{
	assert(pst);
	pst->arr = NULL;
	pst->capacity = 0;
	pst->top = -1;
}

void STDestroy(STNode* pst)
{
	assert(pst);
	free(pst->arr);
	pst->arr = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

void STPush(STNode* pst,STDataType x)
{
	assert(pst);
	if (pst->capacity==pst->top+1)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* temp = NULL;
		temp = (STDataType*)realloc(pst->arr,sizeof(STDataType) * newcapacity);
		if (temp == NULL)
		{
			perror("malloc error");
			return;
		}
		pst->arr = temp;
		pst->capacity = newcapacity;
	}
	pst->arr[++pst->top] = x;
}

void STPop(STNode* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}

STDataType STTop(STNode* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	return pst->arr[pst->top];
}

int StackSize(STNode* pst)
{
	assert(pst);
	return pst->top+1;
}

//test.c
#include "stack.h"

void test1()
{
	STNode ST;
	STInit(&ST);
	STPush(&ST, 1);
	STPush(&ST, 2);
	STPush(&ST, 3);
	STPush(&ST, 4);
	STPush(&ST, 5);
	STPush(&ST, 6);
	STPush(&ST, 7);
	while (!STEmpty(&ST))
	{
		printf("%d ", STTop(&ST));
		STPop(&ST);
	}
	STDestroy(&ST);
}


int main()
{
	test1();
}

什么是棧,為什么函數(shù)式編程語言都離不開棧?

?本文收錄于數(shù)據(jù)結(jié)構(gòu)理解與實現(xiàn)

下幾期會繼續(xù)帶來棧的練習(xí)題以及與棧剛好相反的堆(FIFO)。如果文章對你有幫助記得點贊收藏關(guān)注。文章來源地址http://www.zghlxwxcb.cn/news/detail-457591.html

到了這里,關(guān)于什么是棧,為什么函數(shù)式編程語言都離不開棧?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • c語言中為什么函數(shù)傳參大多數(shù)用指針類型

    在C語言中,函數(shù)傳參大多數(shù)使用指針類型的原因主要有兩個: 允許在函數(shù)內(nèi)部修改實參的值:C語言中的函數(shù)參數(shù)傳遞是按值傳遞的,即將實參值拷貝一份到形參中進(jìn)行操作,對參的修改不會影響實參。而通過使用指類型參數(shù),可以將實參的地址傳遞給函數(shù),從而在函數(shù)內(nèi)部

    2024年02月09日
    瀏覽(24)
  • C語言文本為什么不包括庫函數(shù)和預(yù)處理命令

    C語言文本為什么不包括庫函數(shù)和預(yù)處理命令

    C語言的文本不包括庫函數(shù)和預(yù)處理命令 是因為庫函數(shù)和預(yù)處理命令并不是C語言本身的一部分, 它們是由 C語言標(biāo)準(zhǔn)庫 和 預(yù)處理器 提供的功能。 C語言 標(biāo)準(zhǔn)庫 是一組預(yù)定義的函數(shù)和常量, 用于提供常見的功能,如輸入輸出、字符串處理、數(shù)學(xué)計算等。 這些庫函數(shù)是由C語言

    2024年02月09日
    瀏覽(36)
  • 【C語言】scanf和strcpy這類關(guān)鍵字和函數(shù)為什么不安全,使用VS編譯會報錯

    【C語言】scanf和strcpy這類關(guān)鍵字和函數(shù)為什么不安全,使用VS編譯會報錯

    首先先說解決方法: 在程序最頂端加入這個代碼段 這主要是微軟的 C 運行時庫實現(xiàn)將這些函數(shù)標(biāo)記為不安全,主要原因是這些函數(shù)缺乏對輸入長度的邊界檢查,容易導(dǎo)致緩沖區(qū)溢出漏洞。 會產(chǎn)生這樣的報錯: 即: C4996?? ?\\\'strcpy\\\': This function or variable may be unsafe. Consider usin

    2024年02月14日
    瀏覽(21)
  • 【編程語言 · C語言 · 函數(shù)指針】

    由于指針可以指向任何存儲器位置中的地址,因此它們也可以指向可執(zhí)行代碼的開頭。 函數(shù)指針或函數(shù)指針指向內(nèi)存中函數(shù)的可執(zhí)行代碼。函數(shù)指針可以存儲在數(shù)組中,也可以作為參數(shù)傳遞給其他函數(shù)。 函數(shù)指針聲明使用 * 就像使用任何指針一樣: (*func_name)? 周圍的括號很

    2024年02月10日
    瀏覽(26)
  • 什么是可視化編程?為什么它如此重要?

    什么是可視化編程?為什么它如此重要?

    可視化編程,又叫可視化程序設(shè)計,一直以來就是備受討論的“熱門技術(shù)”。一方面,程序員抵觸它,覺得它不如用代碼開發(fā)。另一方面,對于產(chǎn)品經(jīng)理等稍微懂點開發(fā)的業(yè)余人員,它確實能提供價值。所以,它到底是什么呢?本文將從可視化編程的定義、應(yīng)用、優(yōu)勢等三個

    2024年02月12日
    瀏覽(20)
  • C# 編程語言有什么特點?

    C# 編程語言有什么特點?

    在開始前我有一些資料,是我根據(jù)網(wǎng)友給的問題精心整理了一份「C#的資料從專業(yè)入門到高級教程」, 點個關(guān)注在評論區(qū)回復(fù)“888”之后私信回復(fù)“888”,全部無償共享給大家?。?!C#(C Sharp)是一種由Microsoft開發(fā)的多范式編程語言,最初發(fā)布于2000年。以下是C#編程語言的一

    2024年01月22日
    瀏覽(25)
  • 為什么編程都建議不要用拼音命名

    為什么編程都建議不要用拼音命名

    我們看看知乎答主舉的搞笑例子,一句話全部都是shi,表達(dá)起來確實困難。 上面這個回答,一句話全部都是“shi”,表達(dá)起來確實困難。并且讓人誤解 那么編程都建議不要用拼音命名,主要有以下原因: 可讀性差 :使用拼音命名的變量、函數(shù)名等很難被其他人理解,特別是

    2024年02月04日
    瀏覽(24)
  • Rust編程語言入門之函數(shù)式語言特性:-迭代器和閉包

    閉包(closures) 迭代器(iterators) 優(yōu)化改善 12 章的實例項目 討論閉包和迭代器的運行時性能 閉包:可以捕獲其所在環(huán)境的匿名函數(shù)。 閉包: 是匿名函數(shù) 保存為變量、作為參數(shù) 可在一個地方創(chuàng)建閉包,然后在另一個上下文中調(diào)用閉包來完成運算 可從其定義的作用域捕獲值

    2023年04月08日
    瀏覽(27)
  • inline內(nèi)聯(lián)函數(shù)為什么不能是虛函數(shù)?

    1. inline內(nèi)聯(lián)函數(shù)為什么不能是虛函數(shù)? 虛函數(shù)可以是內(nèi)聯(lián)函數(shù) ,內(nèi)聯(lián)是可以修飾虛函數(shù)的, 但是當(dāng)虛函數(shù)表現(xiàn)多態(tài)性的時候不能內(nèi)聯(lián) 。 理由如下:內(nèi)聯(lián)是在發(fā)生在編譯期間,編譯器會自主選擇內(nèi)聯(lián),而虛函數(shù)的多態(tài)性在運行期,編譯器無法知道運行期調(diào)用哪個代碼,因此

    2024年02月21日
    瀏覽(28)
  • 編程語言MoonBit新增矩陣函數(shù)的語法糖

    編程語言MoonBit新增矩陣函數(shù)的語法糖

    1. 新增矩陣函數(shù)的語法糖 新增矩陣函數(shù)的語法糖,用于方便地定義局部函數(shù)和具有模式匹配的匿名函數(shù): 2. 新增使用 T::{ ... } 構(gòu)造結(jié)構(gòu)體的語法 這個新語法可用于顯式的指定結(jié)構(gòu)體的類型,并會使得結(jié)構(gòu)體內(nèi)有更好的補全: 3. 正式移除 var id = expr 的語法 4. 增加了新的關(guān)鍵

    2024年01月23日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包