程序设计主要有哪些方法
1、结构化程序设计
在结构化程序设计中,任何程序段的编写都基于3种结构:分支结构、循环结构和顺序结构。程序具有明显的模块化特征,每个程序模块具有惟一的出口和入口语句。结构化程序的结构简单清晰,模块化强,描述方式贴近人们习惯的推理式思维方式,因此可读性强。
2、面向对象程序设计
面向对象程序设计方法是尽可能模拟人类的思维方式,使得软件的开发方法与过程尽可能接近人类认识世界、解决现实问题的方法和过程,也即使得描述问题的问题空间与问题的解决方案空间在结构上尽可能一致,把客观世界中的实体抽象为问题域中的对象。
程序设计的分类
1、按照结构性质,有结构化程序设计与非结构化程序设计之分。前者是指具有结构性的程序设计方法与过程。它具有由基本结构构成复杂结构的层次性,后者反之。
2、按照用户的要求,有过程式程序设计与非过程式程序设计之分。前者是指使用过程式程序设计语言的程序设计,后者指非过程式程序设计语言的程序设计。
3、按照程序设计的成分性质,有顺序程序设计、并发程序设计、并行程序设计、分布式程序设计之分。按照程序设计风格,有逻辑式程序设计、函数式程序设计、对象式程序设计之分。
程序设计主要方法有面向结构的方法和面向对象的方法。\x0d\x0a结构化程序设计\x0d\x0a\x0d\x0a 随着计算机的价格不断下降,硬件环境不断改善,运行速度不断提升。程序越写越大,功能越来越强,讲究技巧的程序设计方法已经不能适应需求了。记得是哪本书上讲过,一个软件的开发成本是由:程序设计 30% 和程序维护 70% 构成。这是书上给出的一个理论值,但实际上,从我十几年的工作经验中,我得到的体会是:程序设计占 10%,而维护要占 90%。也许我说的还是太保守了,维护的成本还应该再提高。下面这个程序,提供了两种设计方案,大家看看哪个更好一些那?\x0d\x0a\x0d\x0a 题目:对一个数组中的100个元素,从小到大排序并显示输出。(BASIC)\x0d\x0a\x0d\x0a 方法1:冒泡法排序,同时输出。 \x0d\x0a\x0d\x0aFOR I=1 TO 100\x0d\x0a FOR J=I+1 TO 100\x0d\x0a IF A[I] >A[J] THEN T=A[J]: A[J]=A[I]: A[I]=T\x0d\x0a NEXT J\x0d\x0a ? A[I]\x0d\x0aNEXT I\x0d\x0a\x0d\x0a 方法2:冒泡法排序,然后再输出。\x0d\x0a\x0d\x0aFOR I=1 TO 100\x0d\x0aFOR J=I+1 TO 100\x0d\x0aIF A[I] >A[J] THEN T=A[J]: A[J]=A[I]: A[I]=T\x0d\x0aNEXT\x0d\x0aNEXT\x0d\x0a\x0d\x0aFOR I=1 TO 100\x0d\x0a? A[I]\x0d\x0aNEXT \x0d\x0a\x0d\x0a 显然,“方法1”比“方法2”的效率要高,运行的更快。但是,从现在的程序设计角度来看,“方法2”更高级。原因很简单:(1)功能模块分割清晰——易读;(2)也是最重要的——易维护。程序在设计阶段的时候,就要考虑以后的维护问题。比如现在是实现了在屏幕上的输出,也许将来某一天,你要修改程序,输出到打印机上、输出到绘图仪上;也许将来某一天,你学习了一个新的高级的排序方法,由“冒泡法”改进为“快速排序”、“堆排序”。那么在“方法2”的基础上进行修改,是不是就更简单了,更容易了?!这种把功能模块分离的程序设计方法,就叫“结构化程序设计”。\x0d\x0a\x0d\x0a面向对象的程序设计\x0d\x0a\x0d\x0a 随着程序的设计的复杂性增加,结构化程序设计方法又不够用了。不够用的根本原因是“代码重用”的时候不方便。面向对象的方法诞生了,它通过继承来实现比较完善的代码重用功能。很多学生在应聘工作,面试的时候,常被问及一个问题“你来谈谈什么是面向对象的程序设计”,学生无言,回来问我,这个问题应该怎么回答。我告诉他,你只要说一句话就够了“面向对象程序设计是对数据的封装;范式(模板)的程序设计是对算法的封装。”后来再有学生遇到了这个问题,只简单的一句对答,对方就对这个学生就刮目相看了(学生后来自豪地告诉我的)。为什么那?因为只有经过彻底的体会和实践才能提炼出这个精华。\x0d\x0a\x0d\x0a 面向对象的设计方法和思想,其实早在70年代初就已经被提出来了。其目的就是:强制程序必须通过函数的方式来操纵数据。这样实现了数据的封装,就避免了以前设计方法中的,任何代码都可以随便操作数据而因起的BUG,而查找修改这个BUG是非常困难的。那么你可以说,即使我不使用面向对象,当我想访问某个数据的时候,我就通过调用函数访问不就可以了吗?是的,的确可以,但并不是强制的。人都有惰性,当我想对 i 加1的时候,干吗非要调用函数呀?算了,直接i++多省事呀。呵呵,正式由于这个懒惰,当程序出BUG的时候,可就不好捉啦。而面向对象是强制性的,从编译阶段就解决了你懒惰的问题。\x0d\x0a\x0d\x0a 巧合的是,面向对象的思想,其实和我们的日常生活中处理问题是吻合的。举例来说,我打算丢掉一个茶杯,怎么扔那?太简单了,拿起茶杯,走到垃圾桶,扔!注意分析这个过程,我们是先选一个“对象”------茶杯,然后向这个对象施加一个动作——扔。每个对象所能施加在它上面的动作是有一定限制的:茶杯,可以被扔,可以被砸,可以用来喝水,可以敲它发出声音......;一张纸,可以被写字,可以撕,可以烧......。也就是说,一旦确定了一个对象,则方法也就跟着确定了。我们的日常生活就是如此。但是,大家回想一下我们程序设计和对计算机的操作,却不是这样的。拿DOS的操作来说,我要删除一个文件,方法是在DOS提示符下:c:>del 文件名。注意看这个过程,动作在前(del),对象在后(文件名),和面向对象的方法正好顺序相反。那么只是一个顺序的问题,会带来什么影响那?呵呵,大家一定看到过这个现象:File not found. “啊~~~,我错了,我错了,文件名敲错了一个字母”,于是重新输入:c:>del 文件名2。不幸又发生了,计算机报告:File read only. 哈哈,痛苦吧:)。所以DOS的操作其实是违反我们日常生活中的习惯的(当然,以前谁也没有提出过异议),而现在由于使用了面向对象的设计,那么这些问题,就在编译的时候解决了,而不是在运行的时候。obj.fun(),对于这条语句,无论是对象,还是函数,如果你输入有问题,那么都会在编译的时候报告出来,方便你修改,而不是在执行的时候出错,害的你到处去捉虫子。\x0d\x0a\x0d\x0a 同时,面向对象又能解决代码重用的问题——继承。我以前写了一个“狗”的类,属性有(变量):有毛、4条腿、有翘着的尾巴(耷拉着尾巴的那是狼)、鼻子很灵敏、喜欢吃肉骨头......方法有(函数):能跑、能闻、汪汪叫......如果它去抓耗子,人家叫它“多管闲事”。好了,狗这个类写好了。但在我实际的生活中,我家养的这条狗和我以前写的这个“狗类”非常相似,只有一点点的不同,就是我的这条狗,它是:卷毛而且长长的,鼻子小,嘴小......。于是,我派生一个新的类型,叫“哈巴狗类”在“狗类”的基础上,加上新的特性。好了,程序写完了,并且是重用了以前的正确的代码——这就是面向对象程序设计的好处。我的成功只是站在了巨人的肩膀上。当然,如果你使用VC的话,重用最多的代码就是MFC的类库。
<stdio.h>
void
input_data(int
*l,int
*r,int
data[100][100])
{
int
i,j,k
printf("输入矩阵行数:")
scanf("%d",l)
printf("输入矩阵列数:")
scanf("%d",r)
printf("按行输入数据,数据间用空格间隔:\n")
for(i=0i<*li++)
for(j=0j<*rj++)
scanf("%d",&data[i][j])
}
int
add_subtra(int
m1[100][100],int
l1,int
r1,
int
m2[100][100],int
l2,int
r2,char
m,int
rm[100][100])
{
int
i,j
if(l1!=l2
||
r1!=r2)
{
printf("矩阵数据错误1.\n")
return
}
if(m=='+')
for(i=0i<l1i++)
for(j=0j<r1j++)
rm[i][j]=m1[i][j]+m2[i][j]
else
for(i=0i<l1i++)
for(j=0j<r1j++)
rm[i][j]=m1[i][j]-m2[i][j]
}
int
mul(int
m1[100][100],int
l1,int
r1,
int
m2[100][100],int
l2,int
r2,int
m[100][100])
{
int
i,j,k
if(l1!=r2
)
{
printf("矩阵数据错误2.\n")
return
}
for(i=0i<l1i++)
for(j=0j<r2j++)
{
m[i][j]=0
for(k=0k<r1k++)
m[i][j]+=m1[i][k]*m2[k][j]
}
}
int
output(int
m[100][100],int
l,int
r)
{
int
i,j
for(i=0i<li++)
{
for(j=0j<rj++)
printf("%3d
",m[i][j])
printf("\n")
}
}
int
main()
{
int
d1[100][100],d2[100][100],d[100][100]
int
l1,r1,l2,r2
int
i,j,k
char
mark[2]
printf("输入第一个矩阵数据:\n")
input_data(&l1,&r1,d1)
printf("输入的第一个矩阵:\n")
output(d1,l1,r1)
printf("输入第二个矩阵数据:\n")
input_data(&l2,&r2,d2)
printf("输入的第二个矩阵:\n")
output(d2,l2,r2)
printf("指定运算符(+/-/*):")
scanf("%s",mark)
while(mark[0]!='+'
&&
mark[0]!='-'
&&
mark[0]!='*')
{
printf("符号错误请重新输入(+/-/*):")
scanf("%s",mark)
}
switch(mark[0])
{
case
'+':
case
'-':
add_subtra(d1,l1,r1,d2,l2,r2,mark[0],d)
break
case
'*':
mul(d1,l1,r1,d2,l2,r2,d)
break
}
//output(d1,l1,r1)
//output(d2,l2,r2)
printf("运算:%c,计算结果为:\n",mark[0])
output(d,l1,r2)
system("pause")
}
两个运算矩阵可以是大小不同的,
输出结果由被乘数矩阵的行和乘数矩阵的列决定,
你要求的输出格式比较烦,没时间不够啦!有时间再玩吧。
看了 bang 的博客对微信小程序的技术方案有了更深入的理解:
微信小程序必须要符合两个刚需: 管控 & 体验
(1)DLS:想要对开发者进行管控,最好的方法就是自己设计一套框架,让开发者按照自己框架的规范进行编码,利用这套DLS(针对某一特定的领域设计的计算机语言)可以更好的针对不同的需求去优化。
(2)JS环境:写过小程序的开发者都了解,小程序中是无法调用任何DOM API的,为什么呢?是因为小程序实现了js的运行环境与浏览器分离,运行在单独的js引擎上,脱离了浏览器,一切DOM操作在你的JS中是无法操作的,而小程序的核心JS是运行在浏览器中的,这样做的 好处 和 坏处 是什么呢?
(1)因为小程序是寄生在原生下的应用,通过native接口,我们可以用js调用一些原生的组件和方法,做出一些H5无法完成的任务和体验。
(2)退出小程序后,小程序后,小程序可以在后台运行5分钟,用户再次打开时,不需要重洗渲染小程序。
(3)同时得益于在原生环境下,小程序可以预加载多个WKWebView,可以省去WKWebView加载时间,提高用户体验。
以上是通过bang的博客以及自己的理解记下的。
以下是自己最于最近的现象的一些见解唠叨:
(1)微信小程序平台的管理机制:小程序的管控机制其实很大程度上是效仿苹果对于旗下应用的管控机制。苹果对自家的应用或者语言的监控可谓是家长对于孩子般的照顾了,当然这和其自身利益和自身价值是分不开的,对于前阶段苹果对于混合开发的动作(当然这和安全隐患有着关系,如JSPatch调用私有API),大家可以搜索一下2016年之前和2016年之后Object-C和Swift的语言排行,相信可以看到一下原因。所以对旗下产品的管控对于其自身利益又着很大的作用。
(2)支付宝小程序和微信小程序:支付宝小程序刚推出时,我看了一下它的文档,确实和小程序很像,抄袭理念也是自然的了。这个我不考虑,只是写一些对与两个超级平台的不同看法(纯属个人见解,欢迎一起分享讨论),两个小程序确实存在着竞争,但是我认为(不考虑两个巨头对于市场的战略竞争),两个不同的平台都拥有着自己不同优势产品细分领域下的深层的挖掘,比如说,在微信小程序上,我们可以对其社交进行不同的细分,这种场景对于支付宝来说并不合适的,但是在支付宝小程序中,金融类领域相对于微信来说是其优势,在支付宝中对其进行深层次的挖掘也会带来不一样的效益。其实关键在于两家超级平台对于旗下优势产品的大数据层次的开放程度,这些数据对寄生或者共存在其生态下的商户来说是可遇不可求的。这些数据和资源足可以再次创造多个的美团和饿了么了,对于小公司的吸引力是很大的。所以个人认为支付宝和小程序胜出关键在于对数据的开发和不同时间节点的营销了,不同时间节点的营销同样是很重要的,这个就是天时了。一个产品的成功,不仅仅靠的技术,理念,甚至体验,因为这些都是可以改变的,但是天时足可以影响一个产品的成败。天时,地利,人和才是其成功的关键。关于两个超级平台的发展,我们只能静静地观察了,因为对于吃瓜群众的我而言,现在只能说说理解,发发牢骚(其实很多人都是了),但是我感觉这对个人的成长也是有很大的好处的。