`

从C语言中printf开始

阅读更多

 

题目:

 

 

# 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() 中增加任何其他可执行语句。

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics