能力值:
( LV2,RANK:10 )
|
-
-
2 楼
在前面的介绍队列的小节中源代码,并不优美,极易上溢或下溢。队尾指针超越了队列空间的上界(即队满)而不能做入队操作,称之为上溢。队头指针小于了队列空间的下界(即队空)而不能做出队操作,称之为下溢。
为了防止队列的上溢、下溢,统计队列的元素总数以及队列的大小,我们可以定义如下结构:
Queue strcut
front dword 0
rear dword 0
count dword 0
queueSize dword 5
element dword 5 dup(0)
Queue ends
源代码
源代码Queue2.asm:
.
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include queue.inc
.data
QueueA queue<> ;声明队列结构的变量
szCaption db '消息框!',0
szText db 100 dup(0)
szCharsFormat db '第%d出队:%d',0
.code
;-----------------------------------------------------------------
;置空队
InitQueue proc uses esi q:ptr queue
mov esi,q
mov (queue ptr [esi]).front,0
mov (queue ptr [esi]).rear,0
mov (queue ptr [esi]).count,0
ret
InitQueue endp
;判队空,队空返回1,队非空返回0
QueueEmpty proc uses esi q:ptr queue
mov esi,q
mov eax,(queue ptr [esi]).count
cmp eax,0
jg LE1
mov eax,1
jmp LE2
LE1:
mov eax,0
jmp LE2
LE2:
ret
QueueEmpty endp
;判队满,队满返回1,队未满返回0
QueueFull proc uses esi q:ptr queue
mov esi,q
mov eax,(queue ptr [esi]).count
cmp eax,(queue ptr [esi]).queueSize
jl LF1
mov eax,1
jmp LF2
LF1:
mov eax,0
jmp LF2
LF2:
ret
QueueFull endp
;入队 ,队满返回-1,入队成功返回1
EnQueue proc uses esi ebx q:ptr queue,newElement:dword
mov esi,q
;队满上溢
invoke QueueFull,esi
cmp eax,1
je L1
;队列元素个数加1
inc (queue ptr [esi]).count
;新元素插入到队尾
mov eax,newElement
mov ebx,(queue ptr [esi]).rear
mov (queue ptr [esi]).element[ebx*4],eax
;将队尾指针加1
inc (queue ptr [esi]).rear
mov eax,1
jmp L2
L1:
mov eax,-1
jmp L2
L2:
ret
EnQueue endp
;出队,队空则返回-1,出队成功返回元素
DeQueue proc uses esi ebx q:ptr queue
mov esi,q
invoke QueueEmpty,q
;队空下溢
cmp eax,1
je LD1
;取队头元素
mov ebx,(queue ptr [esi]).front
mov eax,(queue ptr [esi]).element[ebx*4]
;队列元素个数减1
dec (queue ptr [esi]).count
;将队头指针加1
inc (queue ptr [esi]).front
jmp LD2
LD1:
mov eax,-1
jmp LD2
LD2:
ret
DeQueue endp
start:
;入队
invoke EnQueue,addr QueueA,1
cmp eax,-1
je LM2
invoke EnQueue,addr QueueA,2
invoke EnQueue,addr QueueA,3
invoke EnQueue,addr QueueA,5
invoke EnQueue,addr QueueA,7
;出队
mov ecx,5
LM1:
invoke DeQueue,addr QueueA
push ecx
invoke wsprintf,addr szText, addr szCharsFormat, QueueA.front,eax
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
pop ecx
loop LM1
invoke ExitProcess,NULL
LM2:
end start
MakeFile:
NAME=Queue2
OBJS=$(NAME).obj
LINK_FLAG=/subsystem:windows
ML_FLAG=/c /coff
$(NAME).exe:$(OBJS)
Link $(LINK_FLAG) $(OBJS)
.asm.obj:
ml $(ML_FLAG) $<
clean:
del *.obj
定义队列结构的文件如下:
queue.inc
queue struct
front dword 0
rear dword 0
count dword 0
queueSize dword 5
element dword 5 dup(0)
queue ends
笔者实测发现,过程EnQueue内部声明了标号L1,L2,则过程QueueFull内部不能声明一样的L1,L2,因为EnQueue调用了QueueFull。对于没有嵌用关系的过程,则其标号可以一样。此处的标号指的是标号名加冒号的格式。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
等我学会了我在发表我的意见先收藏
|