个性和共性,对共性的封装。新的语言是如何诞生的
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的,这就可以说是一种新的计算机语言,新的计算机语言就这样诞生了!
当然,现在的计算机语言不可能就是这么简单就产生了,但是具体思路就是这样:对已有的语言进行封装,使之更容易解决某一方面的问题。
先来看这样一个程序:
/*
**用户依次输入:字符串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的,这就可以说是一种新的计算机语言,新的计算机语言就这样诞生了!
当然,现在的计算机语言不可能就是这么简单就产生了,但是具体思路就是这样:对已有的语言进行封装,使之更容易解决某一方面的问题。
相关文章推荐
- VB→C++→C#→VB.NET,语言的共性和个性
- 我们认真研究了“洪荒之力”的诞生,以及网络语言如何改变我们的说话方式
- 我是如何设计并实现一门程序设计语言——一门函数式编程语言Lucida的诞生
- Struts2如何封装请求参数
- 如何封装C++类,输出dll
- 如何对ado.net做比较好的封装?
- SplendidCRM 如何添加及使用中文语言包
- SAPUI5 (21) - 如何实现多语言
- 如何处理C++构造函数中的错误——兼谈不同语言的错误处理
- 如何设计一门语言(八)——异步编程和CPS变换
- 如何进行代码封装
- 如何设计一门语言(八)——异步编程和CPS变换
- 如何用 ANTLR 4 实现自己的脚本语言?-博客-云栖社区-阿里云
- 关于在C/C++语言中,函数如何返回数组,数组如何作为参数传递以及返回数组的函数该如何调用问题的总结
- 如何在《拓林思Turbolinux 10 Desktop (多国语言桌面版)》下安装FLASH插件?
- C语言概述及如何上机运行C程序
- Android 如何修改Sim卡语言自适应
- c#对于如何释放资源的解释,又让我对此语言有更进一步的理解
- Eclipse环境下 java如何调第三方jar包或自己封装好的工具类
- 开发工具IntelliJ IDEA如何定义语言和文件类型