题目:
# include <stdio.h>
void hello () { printf(“ Hello, world!\n”); }
int main ()
{
hello(); return 0;
}
试修改上面的程序,使其输出变成:
Begin
Hello, world!
End
限制:( 1 )不能对 main() 进行任何修改;( 2 )不能修改 hello() 中的 printf 语句,也不能在 hello() 中增加任何其他可执行语句。
解法一:
#include <stdio.h>
#include <stdarg.h>
void hello ()
{
printf(" Hello, world!\n");
}
int main ()
{
hello();
return 0;
}
int printf(const char *format, ...)
{
va_list unnamed_p;
char *p, *sval;
char *m = "Begin\n";
char *n = "End\n";
unsigned int value_i;
va_start(unnamed_p, format);
for(p = (char *)m; *p; p++) //输出"Begin\n"
{
putchar(*p);
}
for (p = (char *)format; *p; p++ ) //输出printf函数的参量
{
putchar(*p);
}
for(p = (char *)n; *p; p++) //输出"End\n"
{
putchar(*p);
}
va_end(unnamed_p);
return 0;
}
分析一:
若老师的目的是:一是学习“重写”printf方法;二是读懂printf,学习printf算法的编程思想。则可采用上述解法。
1、C语言中printf函数的算法深刻的体现了数据与操作的独立性,极大的增强了printf的可重用性。
2、printf函数对于可变形参的处理,使我们想输出几类或几个形参,就可以输出几类或几个形参。
3、printf函数作为一个构件来看,其对接口的要求也相当的宽松,可以做到不限制接口参数的个数。
4、此解法不严格的说法是:重写printf方法。但严格的说,并不是重写。和编译的过程有关,当编译器发现当前.CPP文件中有printf函数时,便不再在C库中寻找printf函数(相当于将其屏蔽掉了),这样,我们将再也无法在本.CPP中的printf辖域内使用C库中的printf函数。
5、而重写的一个重要表现是:我们可以使用父类中虽已在子类中重写的方法(只需要定义一个父类的对象,使用此对象调用方法即可)。
6、单就“重写”printf来说,有一个好处,例如,公司的单据或文件格式通常都是固定的,只需要对printf做一次“重写”,就不用再关心此类操作了。这体现了数据是可变的,但操作以及数据结构却可以保持相对长时间的不变性的思想与经验。
解法二:
#include <stdio.h>
class Test
{
public:
Test(){printf("Begin\n");}
~Test(){printf("End\n");}
};
Test Test1;
void hello()
{
printf(" Hello, world!\n");
}
int main ()
{
hello();
return 0;
}
分析二:
1、全局变量Test1初始化先于main()函数的执行,Test1通过Test类的constructor--Test()初始化,此时,便将“Begin”打印出来了。
2、析构函数的执行时间:如果此析构函数对应的类定义的对象是个局部对象,那么在此对象退出作用域时调用析构函数;如果是全局对象,则在整个程序结束(main()函数中调用return(),exit()等等)时析构;如果这个对象被分配在自由存储区中,当delete这个对象时调用析构函数。本解法二定义的是全局对象,在main()执行结束后,调用析构函数~Test(),此时,便将“End”打印出来了。
解法三:
#include <stdio.h>
#define printf(x) printf("Begin\n"x"End\n")
void hello()
{
printf(" hello,world!\n");
}
int main()
{
hello();
return 0;
}
总结:
最终,老师选择以解法二作为此题的正确答案,其对解法一的评价是该解法修改了printf语句。但我个人认为,解法一并没有修改hello() 中的 printf 语句,满足此题的第二个限制条件。若严格按照老师的意图,此题的限制条件二应改为“不能修改hello() 中的 printf 语句以及printf函数,也不能在 hello() 中增加任何其他可执行语句。”