如何理解“入棧、讀棧、出棧”?
一、如何理解“入棧、讀棧、出棧”?
入棧是指將前面的電路塊的結(jié)果存入臨時(shí)寄存器,需要與后面的電路共同作用時(shí)用讀棧指令,最后輸出用出棧指令,雖然都要是并聯(lián)輸出,但讀棧與出棧指令都有相關(guān)的元件或電路塊與前面的臨時(shí)結(jié)果共同作用再產(chǎn)生輸出
二、入棧退棧的計(jì)算?
棧是一種數(shù)據(jù)結(jié)構(gòu),它按照先進(jìn)后出的原則存儲(chǔ)數(shù)據(jù),先進(jìn)入的數(shù)據(jù)被壓入棧底,最后的數(shù)據(jù)在棧頂,需要讀數(shù)據(jù)的時(shí)候從棧頂開(kāi)始彈出數(shù)據(jù)(最后一個(gè)數(shù)據(jù)被第一個(gè)讀出來(lái))。 棧是只能在某一端插入和刪除的特殊線性表。用桶堆積物品,先堆進(jìn)來(lái)的壓在底下,隨后一件一件往堆。取走時(shí),只能從上面一件一件取。堆和取都在頂部進(jìn)行,底部一般是不動(dòng)的。 棧就是一種類似桶堆積物品的數(shù)據(jù)結(jié)構(gòu),進(jìn)行刪除和插入的一端稱棧頂,另一堆稱棧底。插入一般稱為進(jìn)棧(PUSH),刪除則稱為退棧(POP)。 棧也稱為后進(jìn)先出表(LIFO表)。
例如:有一個(gè)數(shù)列(23,45,3,7,3,945) 我們先對(duì)其進(jìn)行進(jìn)棧操作,則進(jìn)棧順序?yàn)?23,45,3,7,3,945 我們?cè)趯?duì)其進(jìn)行出棧操作,則出棧順序?yàn)?945,3,7,3,45,23 進(jìn)棧出棧就像只有一個(gè)口的長(zhǎng)筒,先把數(shù)據(jù)一個(gè)個(gè)放入筒內(nèi),而拿出的時(shí)候只有先拿走上邊的,才能拿下邊的。
三、8086入棧出棧指令?
棧是一種具有特殊訪問(wèn)形式的存儲(chǔ)空間,特殊性在于數(shù)據(jù)后進(jìn)先出。
8086提供入棧(PUSH)和出棧(POP)指令:比如push ax表示將AX寄存器中數(shù)據(jù)送入棧中,pop ax表示將棧頂取出數(shù)據(jù)送入AX寄存器中(數(shù)據(jù)的存取按小端存放的規(guī)則)
有關(guān)棧存儲(chǔ)空間的位置,8086提供了ss(段寄存器):sp(偏移地址
棧的操作都是以字為單位的
四、商棧怎么變成高級(jí)商棧?
商棧可以提升裝修檔次、品味,提高商品種類、檔次,升級(jí)為高級(jí)商棧
五、棧頂和棧底的區(qū)別?
區(qū)別:使用效果不同,位置不同。
六、商棧怎么變成特殊商棧?
普通商棧默認(rèn)都是保護(hù)茶店,要看經(jīng)商之道在周圍組合指定的店鋪、都升到四級(jí),才能變成特定的高級(jí)商棧。
七、進(jìn)程棧與線程棧的關(guān)系?
內(nèi)核棧、用戶棧
32位Linux系統(tǒng)上,進(jìn)程的地址空間為4G,包括1G的內(nèi)核地址空間-----內(nèi)核棧,和3G的用戶地址空間-----用戶棧。
內(nèi)核棧,是各個(gè)進(jìn)程在剛開(kāi)始建立的時(shí)候通過(guò)內(nèi)存映射共享的,但是每個(gè)進(jìn)程擁有獨(dú)立的4G的虛擬內(nèi)存空間從這一點(diǎn)看又是獨(dú)立的,互不干擾的(只是剛開(kāi)始大家都是映射的同一份內(nèi)存拷貝)
用戶棧就是大家所熟悉的內(nèi)存四區(qū),包括:代碼區(qū)、全局?jǐn)?shù)據(jù)區(qū)、堆區(qū)、棧區(qū)
用戶棧中的堆區(qū)、棧區(qū)即為進(jìn)程堆、進(jìn)程棧
進(jìn)程堆、進(jìn)程棧與線程棧
1.線程棧的空間開(kāi)辟在所屬進(jìn)程的堆區(qū)與共享內(nèi)存區(qū)之間,線程與其所屬的進(jìn)程共享進(jìn)程的用戶空間,所以線程棧之間可以互訪。線程棧的起始地址和大小存放在pthread_attr_t 中,棧的大小并不是用來(lái)判斷棧是否越界,而是用來(lái)初始化避免棧溢出的緩沖區(qū)的大小(或者說(shuō)安全間隙的大小)
2.進(jìn)程初始化的時(shí)候,系統(tǒng)會(huì)在進(jìn)程的地址空間中創(chuàng)建一個(gè)堆,叫進(jìn)程默認(rèn)堆。進(jìn)程中所有的線程共用這一個(gè)堆。當(dāng)然,可以增加1個(gè)或幾個(gè)堆,給不同的線程共同使用或單獨(dú)使用。----一個(gè)進(jìn)程可以多個(gè)堆
3、創(chuàng)建線程的時(shí)候,系統(tǒng)會(huì)在進(jìn)程的地址空間中分配1塊內(nèi)存給線程棧,通常是1MB或4MB或8MB。線程棧是獨(dú)立的,但是還是可以互訪,因?yàn)榫€程共享內(nèi)存空間
4.堆的分配:從操作系統(tǒng)角度來(lái)看,進(jìn)程分配內(nèi)存有兩種方式,分別由兩個(gè)系統(tǒng)調(diào)用完成:brk()和mmap(),glibc中malloc封裝了
5.線程棧位置-內(nèi)存分布測(cè)試代碼
[cpp] view plain copy
#include
#include
#include
#include
#include
#include
#include
void* func(void* arg)
{
long int tid = (long int)syscall(SYS_gettid);
printf("The ID of this thread is: %ldn", tid );
static int a=10;
int b=11;
int* c=(int *)malloc(sizeof(int));
printf("in thread id:%u a:%p b:%p c:%pn",tid,&a,&b,c);
printf("leave thread id:%ldn",tid);
sleep(20);
free((void *)c);
}
void main()
{
pthread_t th1,th2;
printf("pid=%un",(int)getpid());
func(NULL);
int ret=pthread_create(&th1,NULL,func,NULL);
if(ret!=0)
{
printf("thread1[%d]:%sn",th1,strerror(errno));
}
ret=pthread_create(&th2,NULL,func,NULL);
if(ret!=0)
{
printf("thread2[%d]:%sn",th2,strerror(errno));
}
pthread_join(th1,NULL);
pthread_join(th2,NULL);
}
輸出:
[le@localhost threadStack]$ ./threadStack_main pid=16433
The ID of this thread is: 16433
in thread id:16433 a:0x60107c b:0x7fffc89ce7ac c:0x1b54010
leave thread id:16433
The ID of this thread is: 16461
The ID of this thread is: 16460
in thread id:16461 a:0x60107c b:0x7f6abb096efc c:0x7f6ab40008c0
leave thread id:16461
in thread id:16460 a:0x60107c b:0x7f6abb897efc c:0x7f6aac0008c0
leave thread id:16460
主線程調(diào)用func后
[le@localhost threadStack]$ sudo cat /proc/16433/maps
00400000-00401000 r-xp 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00600000-00601000 r--p 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00601000-00602000 rw-p 00001000 fd:02 11666 /home/le/code/threadStack/threadStack_main
01b54000-01b75000 rw-p 00000000 00:00 0 [heap]
7f6abb899000-7f6abba4f000 r-xp 00000000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abba4f000-7f6abbc4f000 ---p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc4f000-7f6abbc53000 r--p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc53000-7f6abbc55000 rw-p 001ba000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc55000-7f6abbc5a000 rw-p 00000000 00:00 0
7f6abbc5a000-7f6abbc70000 r-xp 00000000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbc70000-7f6abbe70000 ---p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe70000-7f6abbe71000 r--p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe71000-7f6abbe72000 rw-p 00017000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe72000-7f6abbe76000 rw-p 00000000 00:00 0
7f6abbe76000-7f6abbe97000 r-xp 00000000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc073000-7f6abc076000 rw-p 00000000 00:00 0
7f6abc095000-7f6abc097000 rw-p 00000000 00:00 0
7f6abc097000-7f6abc098000 r--p 00021000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc098000-7f6abc099000 rw-p 00022000 fd:00 105796545 /usr/lib64/ld-2.17.so
7f6abc099000-7f6abc09a000 rw-p 00000000 00:00 0
7fffc89b0000-7fffc89d1000 rw-p 00000000 00:00 0 [stack]
7fffc89fe000-7fffc8a00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
兩個(gè)子線程啟動(dòng)后
[le@localhost threadStack]$ sudo cat /proc/16433/maps
00400000-00401000 r-xp 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00600000-00601000 r--p 00000000 fd:02 11666 /home/le/code/threadStack/threadStack_main
00601000-00602000 rw-p 00001000 fd:02 11666 /home/le/code/threadStack/threadStack_main
01b54000-01b75000 rw-p 00000000 00:00 0 [heap]
7f6aac000000-7f6aac021000 rw-p 00000000 00:00 0
7f6aac021000-7f6ab0000000 ---p 00000000 00:00 0
7f6ab4000000-7f6ab4021000 rw-p 00000000 00:00 0
7f6ab4021000-7f6ab8000000 ---p 00000000 00:00 0
7f6aba897000-7f6aba898000 ---p 00000000 00:00 0
7f6aba898000-7f6abb098000 rw-p 00000000 00:00 0 [stack:16461]
7f6abb098000-7f6abb099000 ---p 00000000 00:00 0
7f6abb099000-7f6abb899000 rw-p 00000000 00:00 0 [stack:16460]
7f6abb899000-7f6abba4f000 r-xp 00000000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abba4f000-7f6abbc4f000 ---p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc4f000-7f6abbc53000 r--p 001b6000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc53000-7f6abbc55000 rw-p 001ba000 fd:00 100678959 /usr/lib64/libc-2.17.so
7f6abbc55000-7f6abbc5a000 rw-p 00000000 00:00 0
7f6abbc5a000-7f6abbc70000 r-xp 00000000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbc70000-7f6abbe70000 ---p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe70000-7f6abbe71000 r--p 00016000 fd:00 105796566 /usr/lib64/libpthread-2.17.so
7f6abbe71000-7f
八、push是進(jìn)棧還是出棧?
push是入棧。
Stack棧,一種運(yùn)算受限的線性表。限定僅在表尾進(jìn)行插入和操作的線性表。這一棧就成為棧點(diǎn)。把一個(gè)元素加入到棧里,就叫做進(jìn)棧,也叫做入棧,或壓棧,英文名字叫做push。
入棧(PUSH)就是將一個(gè)數(shù)據(jù)存入SP指向的當(dāng)前堆棧地址,然后SP指向堆棧內(nèi)的下一個(gè)存儲(chǔ)空間;出棧(POP)就是讓SP返回前一個(gè)存儲(chǔ)空間,然后讀出這個(gè)地址內(nèi)存儲(chǔ)的數(shù)據(jù)。
九、硬件棧和模擬棧的區(qū)別?
硬件堆棧:是通過(guò)寄存器SPH,SPL做為索引指針的地址,是調(diào)用了CALL,RCALL等函數(shù)調(diào)用指令后硬件自動(dòng)填充的堆棧!
軟件堆棧:是編譯器為了處理一些參數(shù)傳遞而做的堆棧,會(huì)由編譯器自動(dòng)產(chǎn)生和處理,可以通過(guò)相應(yīng)的編譯選項(xiàng)對(duì)其進(jìn)行編輯。
十、單棧和雙棧的區(qū)別?
1.雙棧思路。因題目只對(duì)時(shí)間復(fù)雜度有要求,而對(duì)空間復(fù)雜度無(wú)要求。因此我們可以創(chuàng)建兩個(gè)棧,一個(gè)棧用于存儲(chǔ)實(shí)際數(shù)據(jù),另一個(gè)棧用于存儲(chǔ)最小元素,getMin()方法只需直接返回存儲(chǔ)最小元素棧的最頂層元素即可。
雙棧思路時(shí)間復(fù)雜度為O(1),空間復(fù)雜度為O(n)。
2.單棧思路。假設(shè)該題對(duì)時(shí)間復(fù)雜度和空間復(fù)雜度都要求為O(1)時(shí),我們就可使用該方法實(shí)現(xiàn)。單棧顧名思義就是只創(chuàng)建一個(gè)棧,我們進(jìn)行入棧操作時(shí)可push()兩次,第一次為實(shí)際數(shù)據(jù),第二次為最小元素(即每個(gè)實(shí)際數(shù)據(jù)后面均跟著最小元素),getMin()方法只需直接返回棧頂元素即可。
本網(wǎng)站文章僅供交流學(xué)習(xí) ,不作為商用, 版權(quán)歸屬原作者,部分文章推送時(shí)未能及時(shí)與原作者取得聯(lián)系,若來(lái)源標(biāo)注錯(cuò)誤或侵犯到您的權(quán)益煩請(qǐng)告知,我們將立即刪除.