assembly - 玛丽:如何打印姓名
问题描述
我有一个问题,希望用户输入名字和姓氏,然后打印出来。这个问题还希望我在名字和姓氏之间也打印一个空格,我无法弄清楚如何做到这一点。我也这样做了,如果用户输入“$”,程序将停止接受输入并继续打印子程序。到目前为止,这是我的代码。
/main program
FirstNameLoop, JnS SubInputFirstName
Load Name
Add One
Store Name
Jump FirstNameLoop
LastNameLoop, Jns SubInputLastName
Load Name
Add One
Store Name
Jump LastNameLoop
/subroutine for inputting firstname
SubInputFirstName, Hex 0
Input
Store Temp
Subt Comma
Skipcond 400
Jump StoreFirstName
Load Comma
Add One
StoreI Name
Jump LastNameLoop
StoreFirstName, Load Temp
StoreI Name
JumpI SubInputFirstName
End, JnS subPrintString
Load NamePrint
Add One
Store NamePrint
Jump End
Finish, Halt
/subroutine for entering last name
SubInputLastName, HEX 0
Input
Store Temp
Subt Dollar
Skipcond 400
Jump StoreLastName
Jump End
StoreLastName, Load Temp
StoreI Name
JumpI SubInputLastName
/subroutine for printing name
subPrintString, HEX 0
LoadI NamePrint
Store Temp
Subt Period
Skipcond 400
Jump PrintName
Jump Finish
PrintName, Load Temp
Output
JumpI subPrintString
NamePrint, HEX 300
Dollar, Dec 36
Name, HEX 300
One, DEC 1
Temp, DEC 0
Space, DEC 32
Comma, DEC 44
Period, DEC 46
解决方案
计算机几乎可以记住任何东西,但必须准确地告诉它要记住什么以及何时这样做,否则它没有被编程记住的信息可能会丢失而无法恢复。
由于您将名字和姓氏存储在同一个数据结构中,因此一旦开始打印,程序就无法知道名字的结束位置和姓氏的开始位置——这些信息已经丢失。(事实上,一旦请求姓氏的首字母,该信息就会丢失。)
有许多方法可以捕获并将信息从存在的地方传递到需要的地方。首先,我们查看程序中信息仍然存在的点——它位于名字输入和姓氏输入之间的逻辑转换处。这是程序中我们知道一些特别的东西(关于名字和姓氏)的唯一一点。当程序看到该,
字符时,它会停止输入名字并转换为输入姓氏。(我们可以将程序视为状态机,并将它们的各个部分视为状态:这里程序在逻辑上从名字输入状态转换为姓氏输入状态。)
作为从输入名字到输入姓氏的逻辑转换的一部分,您可以
(a) 捕获当前姓名指针,因为它指向姓氏的第一个字符(尚未捕获)。在此转换中捕捉到这一点后,稍后打印代码可以询问并回答以下问题:这是姓氏的第一个字符,如果是,则在输出中插入一个空格。
(b) 在第一个名称循环中放置一个计数器(但不在第二个名称循环中)。当名字循环完成时,计数器将停止递增,因此它将保持名字的长度。稍后,打印代码可以询问和回答我们是否打印了与名字中的字符一样多的问题,以便在名字的最后一个字符之后在输出中插入一个空格。
(c) 在从名字条目到姓氏条目的转换时,在名称字符串数据结构中直接输入一个空格,以便打印输出将在它们之间打印一个空格,而无需真正了解名字和姓氏的任何特殊信息。
(d) 将名字和姓氏存储在不同的数据结构中(两个单独的字符串)。打印第一个字符串,然后打印一个空格,然后打印第二个字符串。
同样,作为从接受姓氏转换到打印的一部分,您应该.
在字符串中附加一个字符,以便打印例程知道在哪里停止。否则,您可能会寻找 0 (nul) 字符而不是.
用于输出打印终止的字符。
您正在使用子例程,但在遇到转换而不是“返回”时直接从子例程跳回主例程 - 虽然这是有效的,但它是非常糟糕的形式,因为它是非结构化的控制流。这种控制流是 Dijkstra在 1968 年发表“Go To Statement Considered Harmful ”的原因。
没有办法用结构化的伪代码或 C 来编写控制流——在任何现代编程语言中,我们都不能直接从子程序/函数跳转到另一个子程序/函数中的任何地方,例如main
. 一个函数唯一能做的就是return
它的调用者。这样,一个函数可以在同一程序中的任何其他函数中使用,甚至可以从某个其他函数的多个位置或多个其他函数中使用。一个函数,一旦编写,也可以在另一个程序中使用。
有许多可能的解决方案,其中之一是子程序将返回一个答案,告诉调用者是否发生了转换。然后调用者使用答案来决定是留在循环中还是过渡到main
.
另一种解决方案是将更多功能移动到子例程中,例如,输入整个名字。循环和递增将在子例程中进行,因此,只有在输入了整个名字后,它才会返回给调用者。将main
简单地调用一个子例程,然后调用另一个(循环已移至子例程中)。
第二个子程序实际上是第一个子程序的副本,只有一个区别,即用于转换的字符。通过抽象转换字符的概念——将,
or$
作为参数传递——相同的子例程可以用于名字和姓氏条目。
推荐阅读
- python-3.x - Python Jira:按版本名称获取版本发布日期
- excel - Excel VBA 验证任何值
- angular - 有没有办法合并两个表单数组控件?
- javascript - 如何计算传递的回调函数中的参数个数?
- regex - 如何使用正则表达式从段落中获取字符串?
- xslt - 如何通过 XSLT 获取行数和字段值的总和?
- android - 拒绝剪贴板访问 com.google.android.as for (Android P 版本)
- regex - 具有多个元字符的 grep -E
- javascript - 如何制作一个不和谐机器人,当他运行命令时会向用户发送特定代码?有点像帐户生成器
- r - 具有多个商店多个产品的时间序列