链式栈

新建节点类snode.cls

Option Explicit

 

Public data As Integer

Public nextnode As SNODE

新建链表类linkstack.cls

Public top As SNODE

 

‘栈的初始化

Public Sub initstack()

Set top = Nothing

End Sub

 

‘入栈

Public Sub push(e As Integer)

Dim n As SNODE

Set n = New SNODE

n.data = e

Set n.nextnode = top

Set top = n

End Sub

 

‘出栈

Public Function pop() As Integer

If top Is Nothing Then

MsgBox “栈已经空了”

Exit Function

Else

Dim n As SNODE

Set n = top

Set top = n.nextnode

pop = n.data

End If

End Function

应用

Option Explicit

Public a As linkstack

 

Private Sub CommandButton1_Click()

Set a = New linkstack

a.initstack

a.push 123

End Sub

 

Private Sub CommandButton2_Click()

MsgBox a.pop()

End Sub

2021年3月16日

 

 

 

 

 

 

顺序栈

数组实现栈,保存到模块中

Public Const MaxSize As Integer = 10

 

Public Type SeqStack

Data(0 To MaxSize – 1) As Integer

top As Integer

End Type

 

‘栈的初始化

Public Sub initStack(st As SeqStack)

st.top = -1

End Sub

 

‘压栈

Public Sub push(st As SeqStack, e As Integer)

If st.top = MaxSize – 1 Then

MsgBox (“栈已满”)

Exit Sub

Else

st.top = st.top + 1

st.Data(st.top) = e

End If

End Sub

 

‘出栈

Public Function pop(st As SeqStack) As Integer

If st.top = -1 Then

MsgBox (“栈已满”)

Exit Function

Else

pop = st.Data(st.top)

st.top = st.top – 1

End If

End Function

 

2021年3月16日

单片机 定时器0中断

中断在单片机中有着至关重要的地址。

#include<reg52.h>

 

unsigned int num;

sbit led1=P1^0;

 

void main()

{

    TMOD=0x01; //设置定时器0的工作方式为1

    TH0=(65536-45872)/256;    //定时器装初始值11.0592M晶振定时50ms的计数为45872

    TL0=(65536-45872)%256;

    EA=1; //总中断开

    ET0=1; //定时器0中断开

    TR0=1; //启动定时器

    while(1)

    {

        if(num==20)

        {

            num=0;

            led1=~led1;

        }

    }

}

 

void T0_timer() interrupt 1

{

    TH0=(65536-45872)/256;

    TL0=(65536-45872)%256;

 

    num++;

}

递归

递归是个什么东西呢,从字面意思来理解好像是先给再还回来,事实上它也就是这个意思,从函数的角度讲就是自己调用自己。

如果以前没有学习过递归,看到下面的这个程序,你可能不理解什么意思。

#include
“stdio.h”

 

void wstring(int
n)

{

    if(n==0)

    {

        printf(我是第%d次调用了\n”,n);

        return;

    }

    else

    {

        printf(我是第%d次调用了\n”, n);

        wstring(n-1);

    }

}

 

int main()

{

    wstring(10);


return 0;

}

再改动一点细节,不知道是否好理解一些了。

#include
“stdio.h”

 

void wstring(int
n)

{

    if(n==0)

    {

        printf(我是第%d次调用了\n”,n);

        return;

    }

    else

    {

        printf(我是第%d次调用了\n”, n);

        n = n – 1;

        wstring(n);

    }

}

 

int main()

{

    wstring(10);


return 0;

}

这个程序确实不好理解,如果换成这样是不是很明确了。

#include
“stdio.h”

 

void wstring(int
n)

{

    for(int i=n;i>=0;–i)

    {

        printf(我是第%d次调用了\n”, i);

    }

}

 

int main()

{

    wstring(10);


return 0;

}

上述的例子就是递归,常用给出的例子是斐波那契数列,1,1,2,3,5,8,……,这个数列的通项公式即an=an-1+an-2,n>=3,如果用递归的写法,示例如下

#include
“stdio.h”

 

int Febo(int
n)

{

    if(n==1 || n==2)

    {

        return 1;

    }

    else

    {

        return Febo(n – 1) + Febo(n-2);

    }

}

 

int main()

{

    int m = 12;

    printf(%d项为:%d\n”, m,Febo(m));


return 0;

}

 

 

我们再用循环写一次

#include
“stdio.h”

 

int Febo(int
n)

{

    if (n == 1 || n == 2)

    {

        return 1;

    }

    else

    {

        int an1 = 1, an2 = 1, an3;

        for(int i=3;i<=n;++i)

        {

            an3 = an1 + an2;

            an1 = an2;

            an2 = an3;

        }

        return an3;

    }

}

 

int main()

{

    int m = 12;

    printf(%d项为:%d\n”, m,Febo(m));


return 0;

}

我看到相关的参考资料上说,递归和循环是可以相互转换的,我也不太确定是不是所有的情况都可以。

递归运算牵扯到压栈出栈操作,不仅花费的时间多而且占用的空间也多,容易造成溢出,你可以试一下用上面递归的方法求第100项的运算结果,你会发现消耗的时间比较长。

递归解决问题的思想还有很巧妙的。

2021年3月11日

指针与函数

函数存储在一段内存中,必然也有地址,就有了指向函数的指针,称之为函数指针。

#include
“stdio.h”

 

int add(int
x,int
y)

{

    return
x + y;

}

 

int main()

{

    int(*pf)(int ,int);

    pf = add;

    int a = (*pf)(1,1);

    printf(“%d\n”,a);


return 0;

}

有了函数指针,我们可以把函数当类似变量来传递了,参见下面的示例

#include
“stdio.h”

 

int add(int
x,int
y)

{

    return
x + y;

}

 

int sub(int
x,int
y)

{

    return
xy;

}

 

int cou(int (*pf)(int,int),int
x,int
y)

{

    return (*pf)(x, y);

}

 

int main()

{

    int a = cou(add, 1, 1);

    int b = cou(sub, 8, 4);

    printf(“%d\n”, a);

    printf(“%d\n”, b);


return 0;

}

 

指针

变量为什么要有类型,它不仅仅存储了地址,还存储了类型相应的字节数,这个说明同样适用于指针类型。

#include
“stdio.h”

#include
“stdlib.h”

 

int main()

{


int a = 123;


int *pa = NULL;

pa = &a;

printf(“%d\n”,*pa);


return 0;

}

分配内存,动态的分配内存非常重要,很多操作都是建立在动态分配内存的基础上的

#include
“stdio.h”

#include
“stdlib.h”

 

int main()

{

    int *pa = NULL;

    pa =(int*)malloc(sizeof(int));

    *pa = 123;

    printf(“%d\n”,*pa);


return 0;

}