本文的编程环境: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[n] && code[n] != ch;n++)
        ;

if(!code[n])
    {
        printf("error!");
        return;
    }

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

printf("%d",func[n](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[n].ch && item[n].ch != ch;n++)
        ;

if(!item[n].ch)
    {
        printf("error!");
        return;
    }

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

printf("%d",item[n].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[n].ch && item[n].ch != ch;n++)
        ;

if(!item[n].ch)
    {
        printf("error!");
        return;
    }

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

printf("%d",item[n].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[n] && code[n] != ch;n++)
        ;

if(!code[n])
    {
        printf("error!");
        return;
    }

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

printf("%d",f[n](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的,这就可以说是一种新的计算机语言,新的计算机语言就这样诞生了!

当然,现在的计算机语言不可能就是这么简单就产生了,但是具体思路就是这样:对已有的语言进行封装,使之更容易解决某一方面的问题。

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

  1. 【转CSDN常高伟】如何学习一门新的语言

    原文:http://blog.csdn.net/chgaowei/archive/2011/05/29/6452793.aspx 这两天在看<编程人生>,这本书确实非常不错.而且看得也特别 ...

  2. 幼谈苹果新开发语言:Swift和苹果的用心

    今天是个值得纪念的日子:由于苹果的WWDC大会.苹果的每次WWDC(全球开发人员大会)举行都让我们像打了肾上腺素这么兴奋.幸福.惊叹.震撼.深思. 今年也不例外,最关键的是苹果带来了它的一门新开发语言 ...

  3. 新程序语言 Wyvern 将不同Web语言融合在一起

    如果你是一名Web开发者,你最喜欢哪种编程语言? CSS? JavaScript? PHP? HTML 5?为什么选择这种语言?卡内基梅隆大学的研究人员现在开发出一种新的语言,试图将所有这些语言结合在 ...

  4. SMLT中增加新的语言

    1.SMLT,增加新的语言,如果提示NLS错误 ->2 2.se38中执行RSCPINST,在NLS中增加新的语言 3.选中语言,选择菜单 import language 4.输入补丁文件路径, ...

  5. ubuntu下使用Tesseract-ocr(编译、安装、使用、训练新的语言库)

    本文前半部分是来自http://www.qisanfen.com/?p=185的一篇文章,主要讲了安装.训练的大致流程,注意如果需要训练语言库需要把所需要的库安装完整 后半部分大致是官方wiki的翻译 ...

  6. 如何学习一门新的语言

    这两天在看<编程人生>,这本书确实非常不错.而且看得也特别的轻松.其中有几个人都谈到了如何学习新的语言,但是给我最深刻的是google的首席java架构师joshua bloch.正好最近 ...

  7. 如何快速的学习一门新的语言

    前言 程序的世界变化非常快,总是出新的框架,新的语言,新的名词,如何那快速的跟上这些变化,使自己保持竞争力,而不落伍呢? 语言设计的目的 笔记觉的,首先要看一下这门语言设计的目的是什么,主要想解决哪方 ...

  8. PCA9555PW 原厂封装 新到货

    PCA9555PW 74HC1G14GV 74VC1G11GW NX2301P PBSS5240T TPS53353DQPR CYUSB3035-BZXI 以上型号,对的上绝对优势价格出,实单可谈

  9. 模块的封装之C语言类的继承和派生

    [交流][微知识]模块的封装(二):C语言的继承和派生 在模块的封装(一):C语言的封装中,我们介绍了如何使用C语言的结构体来实现一个类的封装,并通过掩码结构体的方式实 现了类成员的保护.这一部分,我 ...

最新文章

  1. 为全局变量赋值_Postman全局变量设置和运用
  2. Vijos p1165 火烧赤壁 离散化+单调栈
  3. SQL2008R2 Reporting Services 報表產生器 3.0 快速上手
  4. DL之Attention-ED:基于TF NMT利用带有Attention的 ED模型训练、测试(中英文平行语料库)实现将英文翻译为中文的LSTM翻译模型过程全记录
  5. 静态链表和动态链表 区别
  6. php 12小时,使用php怎么将12小时制转换为24小时制
  7. 编辑距离问题(Edit Distance Problem)
  8. android am start activity,adb shell am start -n package/.XXXactivity命令学习汇总
  9. ofo现在还有退路吗?
  10. 基于Windows AD的单点登录系统
  11. java实现选择排序(思路与实现)
  12. 节后 威金/Viking 来拜年
  13. 二进制转十六进制(参考XYJ)
  14. Google推出移动搜索 80亿网页、8亿图片尽在掌中
  15. 堡垒机和跳板机的三大区别分析-行云管家
  16. *关键字retry:很像goto语句,跳到标记处
  17. 初探直播客户端(android)技术
  18. 网络攻防实践 第八周作业
  19. 基于改进的 CASA 模型反演30m分辨率NPP
  20. 关于今天烧坏树莓派板子一事的所思所想

热门文章

  1. 如何修改图片分辨率为300dpi?怎么样修改照片的分辨率?
  2. 小车PWM调速-串口控制
  3. html5 3d模型资源,玩转 HTML5 下 WebGL 的 3D 模型交并补
  4. 计算机网络——第三章 数据链路层(详细附图)
  5. 小程序scroll-view,滚动到最低_小程序滚动到底部
  6. python鼠标点击事件
  7. java midi版本_java-为特定MIDI设备开发软件
  8. Spring 4.x 源码系列4-创建bean实例
  9. 大数据开发之Hive篇3-Hive数据定义语言
  10. oracle的userenv和nls_lang详解