张贴者
班发之前的教程讨论过
什么是编程 ,我们试图实现什么,答案是构成有效程序的指令列表。 现在,我们将讨论我们如何着手这样做。每个程序都以一个规范开头,这可能是来自最新客户的数百页文档,也可能是您教授的一小段文字,介于两者之间。
规范非常重要,规范编写是程序设计的一个完整分支,在此不做讨论。 重要的是,否则该规范是正确的,要使用众所周知的计算格言,将垃圾归入垃圾中。
几年前发生的一个例子是,我收到了一份Windows软件的10-20页规范。 规范似乎很合理,所以我开始研究它,我唯一注意到的是在程序菜单中,尽管第一个下拉菜单中包含诸如通常在Windows程序的“文件”菜单上找到“打开”,“保存”,“另存为”等。 我向客户提出了这一点,并询问他们是否要考虑对显然是“文件”菜单的此菜单使用“文件”一词。
我得到他们正在考虑的答复,他们预计大约需要2周的时间,而在此期间什么也不做。 现在我想起我还年轻,经验不足和愤世嫉俗,那时我认为他们不可能对规范进行太多更改,并且由于我无能为力,因此我继续进行研究,但前提是尽管需要修改的许多工作将是相关且有用的。 2周后我收到新规范时,这是一个错误,其中没有任何一件东西与我收到的原始规范有相似之处。 我必须完全重新开始。 这是规范错误的一种情况,以至于有关用户界面中单个单词的问题导致整个规范的完整更改。 我不得不说,对我来说,这是一个独特的例子,自那以后我再也没有出现过错的说明。
作为程序员,规范不是您的责任,请记住您的责任是创建计算机将遵循的指令列表。 但是,您有责任阅读和理解该规范。 如果要求不明确,不合理或不完整,则应在规范上提出疑问。 遵循以下规范:
该程序将允许用户输入3个整数值。 确认前两个值的总和小于第三个值后,程序将计算三角形的面积,该三角形的边长为3个输入的长度。 然后它将在屏幕上为用户打印该区域。
那么,这有什么问题呢? 停下来想一想。
除其他错误外,您可能已经发现此规范不完整,因为它没有说明如果输入的前两个值的总和大于或等于第三个值应该怎么做,这是不合逻辑的,因为如果条件是输入的前两个值小于第三个值,则该值不能构成三角形的边长,因此无法进行面积计算,最后尚不清楚,因为它没有明确说明一旦打印了该值该怎么办用户所在的区域,大概退出。
规格很少是完美的,在最终达成一致之前,规格要经过多次迭代并不少见。
因此,我们现在已经阅读了该规范,程序员现在有责任确保他们拥有实现该规范所需的所有信息。 请注意,规范将告诉您必须要发生的事情,而不一定是如何使事情发生的,因此,在这一点上,您可以确保自己知道如何解决上一个教程中讨论的问题。 在网上或按照已知的标准和书籍进行研究是为了确保您知道如何解决问题。
找到了解决问题的方法之后,您就可以开始编码了,对吗? 现在是进行一些程序设计的时候了,现在需要多少设计以及设计的存储位置取决于程序的复杂性,用户的经验和程序的目的,这是错误的。 例如,由经验丰富的程序员作为临时项目工具编写的简单程序(即仅使用一两天)可能只需要对程序设计进行一点思考。 由经验不同的程序员团队编写的任何复杂程序都需要书面设计。
设计中的信息量是一个可移动的盛宴,从对程序将如何组合的一般描述到列出程序中的功能以及目的的高度详细的设计不等。 有许多可用的设计方法,例如伪编码,UML,YORDON,SDL,您可以选择使用什么。
设计似乎是一个不必要的阶段,我让一些经理相信了这一点,并坚持认为编程是从没有设计阶段开始的,但是,花在设计上的每个小时,您可能会节省一小时以上的更改时间。
一旦有了设计,就不会陷入僵局。 它只是给出有关程序编写方式的最新想法。 我认为我没有看到一个最终代码与初始设计完全匹配的项目。 随着规格的变化,设计也会随之变化。 但是拥有它将为开始编码提供明确的位置,并最终导致更好的可维护性代码。
设计完成后,就可以开始编码了。 但是,在这一点上值得一提的是编码标准。 您使用的编码标准取决于负责您所从事项目的人员。 这可能是您,您的老师,您的经理或您工作的公司。 编码标准很重要,特别是在团队中工作时,因为它指定了将用于代码的布局以及不使用的语言的任何功能(例如,在我从事过的许多嵌入式项目中)内存非常有限,编码标准已指定不得使用malloc。 拥有编码标准的原因主要是再次维护。 每个人都使用相同的风格来编写代码,这意味着每个人都可以更轻松地阅读彼此的代码。
最后,一旦程序完成,您就可以开始测试了。 现在这是一个问题,您能否定义一个成功的测试? (在这里思考)
答案在某种程度上取决于测试的目的,但是在这一点上,我所看到的最好的定义是该软件的第一个版本是成功的测试失败了,并且突出了可以修复的错误。 这样做的合理性是,在任何规模较大的项目中,首次正确编写的可能性都非常接近于0。因此,如果存在错误,则所有通过的测试都不能突出显示它们。
成功的测试并不意味着该软件没有漏洞,仅表示您的测试不够广泛。
测试不必涉及运行任何代码。 同行评审的源代码也是一种很好的测试形式。 在这里,您可以围坐在一张桌子旁,逐行浏览代码,并检查代码是否存在逻辑错误,是否符合标准和编程错误。 实际上,这可能会引发错误,而这些错误在通过运行软件进行测试时不会明显。
实际上,我可以编写与测试一样多的测试内容,因此a会将大部分主题留给另一个教程,但是我会这么说。 如果您的教授给您提供了示例输入和输出的作业,仅用这些值进行测试是不够的。 您可以打赌,您的教授将拥有一套不同的测试值来测试您的程序,这是您的底钱。
在决定如何测试某些代码时,您应该寻找极限值并测试极限值和介于两者之间的一些值。 以这个功能为例
short Example(short input)
{
long output;
if (input < 0 || 1000 < input)
{
return -1;
}
output = (long)input * (1000L – (long)input) * 370L;
output /= 100000;
return (short)output;
}
此功能的规格如下。
函数Example使用单个short参数。 如果此参数的值在0 <= parameter <= 1000范围内,则该函数将返回相同范围内的值,否则它将返回-1。
您应该使用哪些测试值? (在这里思考)
记住我说的话,至少需要测试参数的限制。 此函数的参数有2个限制,分别是0和1000,这是您需要测试的2个值。 嗯,不,这样的限制定义了两个值,分别在限制内和限制外,因此您需要测试-1、0、1000、1001,这并不是因为短参数本身有一些限制,最小和最大值(在limits.h中定义)h SHRT_MIN(-32768)和SHRT_MAX(32767)。 因此,要测试的完整限制是
SHRT_MIN
-1
0
1000
1001
SHRT_MAX
另外,正如我所说,您应该检查范围中间的一些数字,随机说
-12378
-7342
-56
45
246
943
1873年
7324
23487
实际上,这是一个相当简单的函数,一个2字节短的字符串只有65536个可能的值,因此在这种情况下检查每个输入值是完全可行的,但是在很多情况下,由于太多的输入值,因此无法检查每个输入值。 在这种情况下,能够确定极限是一个重要的工具。
这里总结一下是编写程序的过程图
-------------------
| |
------->| Specification |
| | |
| -------------------
| |
| |
| v
| -------------------
| | Design |
|<-------| Including |<-----------
| | working out how | |
| ------------------- |
Specification | |
Error Found | |
| v |
| ------------------- |
| | |----------->|
|<-------| Programming | |
| | |<--- Design
| ------------------- | Flaw Found
| | | |
| | Bug Found |
| v | |
| ------------------- | |
| | |---- |
--------| Testing |------------
| |
-------------------
正如您在任何阶段看到的那样,您可以返回上一个阶段,并且经常这样做。
对于那些想要金星的人,这里有一些问题需要回答
- 函数示例提供了一个非常原始的实现?
- 在函数示例中,为什么变量输出很长?
- 为什么在使用之前将参数输入强制转换为很长的时间?
- 为什么以下对函数示例的不良测试例程? 你能纠正吗?
int main(int argc, char **argp) { short in=SHRT_MIN; short out; int good = 1; for(in=SHRT_MIN; in<=SHRT_MAX; in++) { out = Example(in); if (in < 0 || in > 1000) { if (out != -1) { printf("ERROR: Example(%d) = %d, should be -1\n", in, out); good = 0; } } else if (out < 0 || out > 1000) { printf("ERROR: Example(%d) = %d, should be in the range 0 - 1000\n", in, out); good = 0; } } if (good == 1) { printf("No errors detected\n"); } }
From: https://bytes.com/topic/c/insights/738833-tutorial-2-how-program