面试收集—hello,world 也有新花样

今天看一篇博主的文章,提到了添加一行代码输出hello world的有趣题目,于是在网上搜,发现关于hello world的小伎俩还真不少,当然,问题的关键不在hello world上,而在这背后的原理之中。那么我们就来看一看这些小题目吧!


题目一:如下,在print()函数中填充代码,使之显示hello ,world,要求main() 不作改动

/* c/c++ code */
#include "stdio.h"
void print()
{
    
}
void main()
{
}

显然,这有两种思路来结局,因为main函数中没有任何执行代码,所以解决方案一种是在main()函数本身打主意,一种是看看能不能在main()函数执行之前就解决问题。

请看第一种解决方案(思路一):

#include <stdio.h>
#include <stdio.h>
void print()
{
#define main main(){ printf("hello,world");}\
void ccav
}
void main ()
{
}

这个解法非常巧妙,但是运用的思维却非常简单,宏定义可以定义在任何地方,在编译阶段宏定义就已经完全展开,也就说,编译完成之后,程序实际上就变成了这幅摸样:

#include <stdio.h>
void print()
{
}
void main ()
{
   printf("hello,world");
}
void ccav()
{
}

解法二(思路二)思路是这样的,抢在main函数执行之前先做点什么,代码如下:

#include "stdio.h"
void print()
{
  
  #pragma comment(linker, "/entry:print1")
  printf("hello world\n");
}
int main()
{
}
这个思路很巧妙,破除了思维定势,人们的第一印象一般是如果main函数都进不去,怎么执行,但是却忘了程序入口点是可以改的,但是需要说明的是这个依赖于具体的编译器,像我用的gcc就不行,但是在vs2008中是可以的,另外,需要说明的是(与本题无关,纯属闲话),main 函数返回值如果是void ,在g++中编译都过不了,具体分析请看 这篇博客

解法三如下,虽然我不推荐,而且也是依赖于具体的编译器,调试环境,而且这个解法有点取巧的嫌疑,但是也可以作为一个思想

#include "stdio.h"
void print()
{
}
    int tmp = printf("hello world\n");
//}
void main()
{
}
这个思路的原理是全局变量的初始化是在main函数执行之前。


题目二:一个C语言的填空题目,Helloworld

int main(){
    if(/*在此填入一个语句*/) printf("Hello");
    else printf(" World!");
}

输出 Hello World!

解法:

#include "unistd.h"
#include "stdio.h"
int main(){
        if ( !fork() || (!wait()) ) //子进程打印hello,父进程等待子进程结束  
                printf("hello");
        else
                printf("world!");//子进程结束后,父进程打印world!
}
说明:fork有一个特点,就是同一个函数有至少两个返回值,在父进程中返回非零的数,在子进程中返回0,因此呢,在上面的代码中,如果进入的是子进程,那么!fork()为1,wait()不用执行,输出hello,而如果是父进程,!fork()为0,需要接着检查,要等一会,确保了先输出hello,在输出world,需要支持的是,fork()和wait()是linux系统调用,这个程序在windows os上是跑不通的,即便是在minGW这种windows下的gcc编译器中也不行。
原文地址:https://www.cnblogs.com/obama/p/3044851.html