版权所有南京大学计算机科学与技术系许畅等2022春季版 6 else if (n 0)write (-1); 7 else write(0); 8 return 0; 91 输出: 这段程序读入一个整数n,然后计算并输出符号函数sg(n)。它所对应的中间代码可以是 这样的: 1 FUNCTION main 2 READ t1 31:=t1 4 t2:=#0 5 IF v1 t2 GOTO label1 6 GOTO label2 7 LABEL labell 8t3:=#1 9 WRITE t3 10 GOTO label3 11 LABEL label2 12t4:=#0 13 IF v1 t4 GOTO label4 14 GOTO label5 15 LABEL label4 16 t5:=#1 17t6:=#0-t5 18 WRITE t6 19 GOTO label6 20 LABEL label5 21 t7:=#0 22 WRITE t7 23 LABEL label6: 24 LABEL label3 25七8:=#0 26 RETURN t8 需要注意的是,虽然样例输出中使用的变量遵循着字母后跟一个数字(如t1、V1等)的方 式,标号也遵循着label)后跟一个数字的方式,但这并不是强制要求的。也就是说,你的程序 输出完全可以使用其它符合变量名定义的方式而不会影响虚拟机小程序的运行。 可以发现,这段中间代码中存在很多可以优化的地方。首先,0这个常数我们将其赋给了 t2、4、t7、8这四个临时变量,实际上赋值一次就可以了。其次,对于t6的赋值我们可以直 接写成t6=#-1而不必多进行一次减法运算。另外,程序中的标号也有些冗余。如果你的程序 足够“聪明”,可能会将上述中间代码优化成这样: 1 FUNCTION main 2 READ t1 3v1:=t1 4 t2:=#0 5 IF v1 t2 GOTO labell 6 IF v1 t2 GOTO label2 7 WRITE t2 8 GOTO label3 9 LABEL labell 10t3:=#1 11 WRITE t3 12 GOTO label3 74
版权所有 南京大学计算机科学与技术系 许畅等 2022春季版 74 6 else if (n < 0) write (-1); 7 else write(0); 8 return 0; 9 } 输出: 这段程序读入一个整数n,然后计算并输出符号函数sgn(n)。它所对应的中间代码可以是 这样的: 1 FUNCTION main : 2 READ t1 3 v1 := t1 4 t2 := #0 5 IF v1 > t2 GOTO label1 6 GOTO label2 7 LABEL label1 : 8 t3 := #1 9 WRITE t3 10 GOTO label3 11 LABEL label2 : 12 t4 := #0 13 IF v1 < t4 GOTO label4 14 GOTO label5 15 LABEL label4 : 16 t5 := #1 17 t6 := #0 - t5 18 WRITE t6 19 GOTO label6 20 LABEL label5 : 21 t7 := #0 22 WRITE t7 23 LABEL label6 : 24 LABEL label3 : 25 t8 := #0 26 RETURN t8 需要注意的是,虽然样例输出中使用的变量遵循着字母后跟一个数字(如t1、v1等)的方 式,标号也遵循着label后跟一个数字的方式,但这并不是强制要求的。也就是说,你的程序 输出完全可以使用其它符合变量名定义的方式而不会影响虚拟机小程序的运行。 可以发现,这段中间代码中存在很多可以优化的地方。首先,0这个常数我们将其赋给了 t2、t4、t7、t8这四个临时变量,实际上赋值一次就可以了。其次,对于t6的赋值我们可以直 接写成t6 := #−1而不必多进行一次减法运算。另外,程序中的标号也有些冗余。如果你的程序 足够“聪明”,可能会将上述中间代码优化成这样: 1 FUNCTION main : 2 READ t1 3 v1 := t1 4 t2 := #0 5 IF v1 > t2 GOTO label1 6 IF v1 < t2 GOTO label2 7 WRITE t2 8 GOTO label3 9 LABEL label1 : 10 t3 := #1 11 WRITE t3 12 GOTO label3
版权所有南京大学计算机科学与技术系许畅等2022春季版 13 LABEL label2 14t6:=#-1 15 WRITE t6 16 LABEL label3 17 RETURN t2 样例2: 输入: 1 int fact(intn)】 2{ 3 1f(n==1) 4 return n; 5 else 6 return (n fact(n -1)); 7} 8 int main() 9 10 int m,result; 11 m read(); 12 if (m 1) 13 result fact (m); 14 else 15 result 1; 16 write(result); 17 return 0; 181 输出: 这是一个读入m并输出m的阶乘的小程序,其对应的中间代码可以是: 1 FUNCTION fact 2 PARAM v1 3 IF v1 ==#1 GOTO labell 4 GOTO label2 5 LABEL labell 6 RETURN v1 7 LABEL label2 8t1:=v1-#1 9 ARG t1 10 t2 :=CALL fact 11 t3:=v1*t2 12 RETURN t3 13 14 FUNCTION main 15 READ t4 16 v2:=t4 17 IF v2 >#1 GOTO label3 18 GOTO label4 19 LABEL label3 20 ARG v2 21 t5 :CALL fact 22 v3:=t5 23 GOTO label5 24 LABEL label4 25 v3:=#1 26 LABEL label5 27 WRITE v3 28 RETURN #0 这个样例主要展示如何处理包含多个函数以及函数调用的输入文件。 4.1.7样例(选做要求) 75
版权所有 南京大学计算机科学与技术系 许畅等 2022春季版 75 13 LABEL label2 : 14 t6 := #-1 15 WRITE t6 16 LABEL label3 : 17 RETURN t2 样例2: 输入: 1 int fact(int n) 2 { 3 if (n == 1) 4 return n; 5 else 6 return (n * fact(n - 1)); 7 } 8 int main() 9 { 10 int m, result; 11 m = read(); 12 if (m > 1) 13 result = fact(m); 14 else 15 result = 1; 16 write(result); 17 return 0; 18 } 输出: 这是一个读入m并输出m的阶乘的小程序,其对应的中间代码可以是: 1 FUNCTION fact : 2 PARAM v1 3 IF v1 == #1 GOTO label1 4 GOTO label2 5 LABEL label1 : 6 RETURN v1 7 LABEL label2 : 8 t1 := v1 - #1 9 ARG t1 10 t2 := CALL fact 11 t3 := v1 * t2 12 RETURN t3 13 14 FUNCTION main : 15 READ t4 16 v2 := t4 17 IF v2 > #1 GOTO label3 18 GOTO label4 19 LABEL label3 : 20 ARG v2 21 t5 := CALL fact 22 v3 := t5 23 GOTO label5 24 LABEL label4 : 25 v3 := #1 26 LABEL label5 : 27 WRITE v3 28 RETURN #0 这个样例主要展示如何处理包含多个函数以及函数调用的输入文件。 4.1.7 样例(选做要求)
版权所有南京大学计算机科学与技术系许畅等2022春季版 这节列举选做要求样例。 样例1: 输入: 1 struct Operands 2{ 3 int ol; int o2; 5}; 6 7 int add(struct Operands temp) 8{ 9 return (temp.o1 temp.02); 10 11 12 int main() 13 14 int n; 15 struct Operands op; 16 0p.o1=1; 17 0p.02=2; 18 n add(op); 19 write(n); 20 return 0; 21 输出: 样例输入中出现了结构体类型的变量,以及这样的变量作为函数参数的用法。如果你的程 序需要完成要求3.1,样例输入对应的中间代码可以是: 1 FUNCTION add 2 PARAM v1 3t2:=*v1 4 t7:=v1+#4 5 t3:=*t7 6 t1:=t2+t3 7 RETURN t1 8 FUNCTION main 9 DEC v3 8 10t9:=&v3 11*t9:=#1 12t12:=&v3+#4 13*t12:=#2 14 ARG &v3 15 t14 :CALL add 1 v2:=t14 17 WRITE v2 18 RETURN #0 如果你的程序不需要完成要求31,将不能翻译该样例输入,你的程序可以给出如下的提 示信息: Cannot translate:Code contains variables or parameters of structure type. 样例2: 输入: 1 int add(int temp[2]) 76
版权所有 南京大学计算机科学与技术系 许畅等 2022春季版 76 这节列举选做要求样例。 样例1: 输入: 1 struct Operands 2 { 3 int o1; 4 int o2; 5 }; 6 7 int add(struct Operands temp) 8 { 9 return (temp.o1 + temp.o2); 10 } 11 12 int main() 13 { 14 int n; 15 struct Operands op; 16 op.o1 = 1; 17 op.o2 = 2; 18 n = add(op); 19 write(n); 20 return 0; 21 } 输出: 样例输入中出现了结构体类型的变量,以及这样的变量作为函数参数的用法。如果你的程 序需要完成要求3.1,样例输入对应的中间代码可以是: 1 FUNCTION add : 2 PARAM v1 3 t2 := *v1 4 t7 := v1 + #4 5 t3 := *t7 6 t1 := t2 + t3 7 RETURN t1 8 FUNCTION main : 9 DEC v3 8 10 t9 := &v3 11 *t9 := #1 12 t12 := &v3 + #4 13 *t12 := #2 14 ARG &v3 15 t14 := CALL add 16 v2 := t14 17 WRITE v2 18 RETURN #0 如果你的程序不需要完成要求3.1,将不能翻译该样例输入,你的程序可以给出如下的提 示信息: Cannot translate: Code contains variables or parameters of structure type. 样例2: 输入: 1 int add(int temp[2])