您的位置:首页 > 编程语言

个性和共性,对共性的封装。新的语言是如何诞生的

2013-07-29 17:10 295 查看
本文的编程环境:tcc.exe,tlink.exe,c0s.obj,cs.lib,maths.lib,emu.lib。

先来看这样一个程序:

/*

**用户依次输入:字符串a,一个字符ch、字符串b,根据字符ch“+”或“-”对a和b进行运算,将结果显示出来

*/

main()

{
    char a[20];

    char b[20];

    char ch;

    gets(a);

    printf("%c\n",ch = getch());

    gets(b);

    if(ch != '+' && ch!='-')

    {

        printf("error!");

        return;

    }

    printf("-------------\n");

    if(ch == '+')printf("%d",atoi(a) + atoi(b));

    if(ch == '-')printf("%d",atoi(a) - atoi(b));

}

这是一个支持加法和减法计算的小程序,如果想要让它支持乘法和除法,只需要在最后的判断中加入对‘*’和‘/'的判断在就好了。

现在来分析一下这个小程序:蓝色部分是这个程序的共性,即不管输入的是什么,都是一样的处理;剩下两句是个性:即对输入的进行了加和减的运算。

接下来对这个程序进行个性与共性的分离:

现有的共性已经摆在这里,我们也没有多大的改动空间了(即使使用一个函数代替蓝色部分,但这实质上只是转移了位置而已,不是共性与个性分离)。

来分析一下个性的部分,这两个都是对两个数据进行一个字符的运算,这里就体现了共性:运算和一个字符,有了这样的思路就可以把运算和字符进行

封装:

char * code = "+-";

int add(int a, int b){return a + b;};

int sub(int a, int b){return a - b;};

int (*func[2])(int, int) = {add,sub};

main()

{

    char a[20];

    char b[20];

    char ch;

    int n;

    gets(a);

    printf("%c\n",ch = getch());

    gets(b);

    for(n = 0;code
&& code
!= ch;n++)

        ;

    if(!code
)

    {

        printf("error!");

        return;

    }

    printf("---------------\n");

    printf("%d",func
(atoi(a),atoi(b)));

}

把字符和运算分别放在了两个数组,首先对字符判断,然后执行相应位置的程序。这时main(){}里面的内容是共性,外面的也是共性,但是他们的层次不同,外面的是通过main里面的个性进行更高一层次的分析抽象出来的共性。对比一下这两个程序,除了代码量第二个比第一个多以外,不管从哪里看都是第二个好一点。如果对第二个进行扩展,也是很简单的事:只需在两个数组中加上相应的运算字符和函数。

但是这样的封装也带来了一个问题:字符个运算两个相互独立,在这一层次上这是两个个性,如果字符和函数数组内的元素不是一一对应怎么办?既然出现了问题,那么我们再来重复上一个步骤:把这两个个性在更高一层次找到共性。

运算和字符能有什么共性呢?我们可以把它们封装在一起啊。

typedef struct

{

    char ch;

    int (*f)(int, int);

}ItemType;

int add(int a, int b){return a + b;};

int sub(int a, int b){return a - b;};

ItemType item[2] = {'+',add,'-',sub};

main()

{

    char a[20];

    char b[20];

    char ch;

    int n;

    gets(a);

    printf("%c\n",ch = getch());

    gets(b);

    for(n = 0;item
.ch && item
.ch != ch;n++)

        ;

    if(!item
.ch)

    {

        printf("error!");

        return;

    }

    printf("---------------\n");

    printf("%d",item
.f(atoi(a),atoi(b)));

}

看,这里诞生一了一个新东西:ItemType,这是一个新类型,里面放着运算字符,和运算函数指针。这是为了解决这个为题而诞生的新数据类型。

再继续进行,这只是一个程序,如果想要其他程序也可以使用这些东西,那么可以把这里面的共性再进行与个性分离,可以吧共性放在一个h文件中,使用时就调用它

建一个ys2.h

typedef struct

{

    char ch;

    int (*f)(int, int);

}ItemType;

func(ItemType * item)

{

    char a[20];

    char b[20];

    char ch;

    int n;

    gets(a);

    printf("%c\n",ch = getch());

    gets(b);

    for(n = 0;item
.ch && item
.ch != ch;n++)

        ;

    if(!item
.ch)

    {

        printf("error!");

        return;

    }

    printf("---------------\n");

    printf("%d",item
.f(atoi(a),atoi(b)));

}

ys2.c要使用它

#include "ys2.h"

int add(int a, int b){return a + b;};

int sub(int a, int b){return a - b;};

ItemType item[2] = {'+',add,'-',sub};

main()

{

    func(item);

}

这样就可以扩大使用范围,为什么没有吧红色部分封装进去呢?如果封装进去那么这个头文件就成了单纯的解决加减的,而运算应该是个性,是由编写者丰富的,可以写一些其他的运算。

再继续进行,如果这是一个很复杂的问题,到这里还是很麻烦,那么我们可以搭建一个新的开发工具,使用这个工具专门开发解决这个问题的程序。

先编写一个main.c

extern char * code;

extern int (**f)(int, int);

main()

{

    char a[20],b[20],ch;

    int n;

    gets(a);

    printf("%c\n",ch = getch());

    gets(b);

    for(n = 0;code
&& code
!= ch;n++)

        ;

    if(!code
)

    {

        printf("error!");

        return;

    }

    printf("---------------\n");

    printf("%d",f
(atoi(a),atoi(b)));

}

对main.c只编译不连接,生成main.obj

然后编写一个开发环境:cc.exe

char (*str[3]) = { "echo off","tcc -c %","tlink c0s main %,%,,cs"};

char buffer[100];

void creat(char * old, char * name ,char * new)

{

    int i;

    char a[2] = {0,0};

    new[0] = 0;

    for(i = 0;old[i];i++)

    {

        if(old[i] != '%')

        {

            a[0] = old[i];

            strcat(new,a);

        }

        if(old[i] == '%')

        {

            strcat(new,name);

        }

    }

}

main(int n,char ** name)

{

    int i;

    if(n<2){printf("hello,but there is no files name");return;}

    for(i = 0;str[i];i++)

    {

        creat(str[i],name[1],buffer);

        system(buffer);

    }

}

cc.exe就是一个新的开发环境了,编写mc.c

char * code = "+-*/";

int add(int a, int b){return a + b;};

int sub(int a, int b){return a - b;};

int mul(int a, int b){return a * b;};

int div(int a, int b){return a / b;};

int (*func[4])(int, int) = {add,sub,mul,div};

int (**f) (int, int) = func;

输入cc mc编译,新的开发环境就对应了新的开发模式,即开发程序的模式就不一样了。如果对这些已有的语言封装呢?

写一个mc.h

#define YUNSUAN(str) char * code = str;

#define NEW int

#define OP1 (int a, int b){return a

#define OP2 b;};

#define FUNCTION int (*func[])(int, int) = {

#define MAKE_IT };int (**f) (int, int) = func;

然后就可以这样写程序了

#include "mc.h"

YUNSUAN("+-")

NEW add OP1 + OP2

NEW sub OP1 - OP2

FUNCTION add,sub

MAKE_IT

这一段代码是属于cc的,这就可以说是一种新的计算机语言,新的计算机语言就这样诞生了!

 

当然,现在的计算机语言不可能就是这么简单就产生了,但是具体思路就是这样:对已有的语言进行封装,使之更容易解决某一方面的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息