问答题
[说明]
以下[C程序]是对某电码明文(原文)进行加密形成密文。其加密算法如下。
假定原文为C
1C
2C
3……C
n,加密后形成的密文为S
1S
2S
3……S
n其中n为小于256的任意自然数。首先读入正整数Key(Key>1)作为加密钥匙,并将密文字符位置按顺时针方向连成一个环,如图4-12所示。

图4-12 密文字符环示意图
加密时从S
1位置起顺时针计数,当数到第Key个字符位置时,将原文中的字符放入该密文字符位置中,同时从环中除去该字符位置;接着从环中下一个字符位置起继续计数,当再次数到第Key个字符位置时,将原文中字符C
2放入其中,并从环中除去该字符位置;依此类推,直至n个原文字符全部放入密文环中。由此产生的S
1S
2……S
n即为原文的密文。
例如,原文:One World One Dream。当Key=5时,其密文为:me OnWlanD oOedrer;当Key=6时该原文的密文为:oeDn OedrrOn Wma le。程序使用示例如图4-13所示。
【正确答案】
【答案解析】本案例是对一字符串根据正整数key进行加密处理。C程序中原文存放在数组old中,用函数 decode(old, key)将原文old加密成密文,并返回存放密文字符数组的首指针。了解加密算法和存放原文与密文的数据结构及完成加密功能的函数名称后,再仔细阅读程序,分析给出的语句在加密过程中的作用,就能逐步求得解答。
主函数main用来接收输入参数并输出加密结果。仔细阅读程序,可知加密函数decode在main之后定义而被main引用,在引用前应给予说明。因此(1)空缺处是用来说明函数decode的,其所填入的内容是“*decode()”。
主函数中用while循环语句读入原文并存放在数组old[]中,控制条件是已接收255个字符或回车符。在C语言中规定,一个字符串数据总是以‘/0’为结束标志。在接收字符过程中,变量num总是指向下一个要接收的字符存放位置。如果已接收255个字符,就应该把‘/0’放入old[255];如果遇到回车符,因其不是原文字符,则应该把‘/0’放入old[num-1]中。因此(2)空缺处需要使用C语言中的条件语句来完成相应的功能,该空缺处所填入的内容是“(num==255)?num:num-1”。
函数decode把存放在old中的原文按key值进行加密,加密结果存放在以new为首地址的字符串中,并将该地址返回。这此信息可从函数一开始的“char *decode(old,key)”和函数结束处的"return (new);”得知。函数decode中调用另一个函数length(old),以计算数组old中的字符个数,并利用此长度去分配存储空间。该存储空间用于存放密文,空间的首地址指针为loop,类型为CODE。借鉴语句“new=(char *)malloc((length+1) *sizeof(char));”可得,(3)空缺处所填入的内容是“CODE*”,使之成为待加密的双向环状链表。
在函数decode中,对待加密的双向环状链表加密之后,利用for循环语句找出应从环中去除字符的位置,因此(4)空缺处所填入的内容是“p->forward”,使指针p指向下一个节点。按题干说明的加密算法,应把*old放入该节点,并要把该节点从双向链表中删除。(5)、(6)即为将该节点从链表中脱钩,节点本身仍然存在,可以通过loop[i]的形式取其密文。因此(5)、(6)空缺处所填入的内容分别是“p->forward”和“p->backward”。
函数strlen的功能是计算字符串的长度。它先取字符串进行判别,即是否为字符串的结束标志‘/0’,是则结束;否则应使S指向该串的下一个字符,同时计数器加1。因此(7)空缺处所填入的内容是“*s++”。