一条语句中的逻辑

今天在网上无意间看到一道笔试题,初看十分简单,再看要求发现还是比较曲折的:
    

函数原形已经给出:int p(int i, int n); 
功能:调用该函数,打印如下格式的输出,例p(
17); 
1 
2 
3 
4 
5 
6 
7 
6 
5 
4 
3 
2 
1 
即每行一个数字。(注意:N只打印一次) 
要求: 
函数中唯一能够调用的函数就是printf。 
只使用一条语句,如果你真的不能用一条语句,每增加一条语句扣1分。 
不准使用如下的关键字:typedef, 
enumdowhileforswitchcasebreakcontinuegoto,  
until, 
if,  ..具体很多我也忘了,反正能用的不多。 
不能使用逗号表达式和?:表达式。 
标准:(总分10分) 
1. 每多一条语句扣1分,即每多一个;就扣1分 
2. 每使用一次if或?:扣2分  
3. 每使用一次for,while, swith各扣4分 

 

初看,打印出这些数字,简单!我们刚学C的时候什么没打印过啊, 再往下看,不能用循环,不能用条件判断, 而且只能用一条语句。。。。。
我们来分析一下困难与可能的解决办法:
1.不能用循环,要打印出那么多数字,只有一个办法了,那就是递归
2.不能用条件判断,我们知道,递归是需要有终止条件的,不然就无穷递归了,那么我们需要作条件判断来终止递归,可是那些常用的条件判断语句又不能用,怎么办? 看看C中的&&运算符:

expression1 && expression2;

只有在Expression为true的情况下,才会继续执行expression2,这也就相当于条件判断语句

if(expression1) expression2;


好,这两个问题都有了相应的解决方案,现在要做的就是用你的逻辑把这些语句巧妙的组合起来, 可以说答案是多种多样的,下面就是一个比较简单的:

int p(int i, int n)
{
    return ((i < n && printf("%d\n",i) && p(i+1,n)) || 1&& (printf("%d\n",i));
}

打印1,2,3,4,5,6是在递归的时候, 而打印7,6,5,4,3,2,1则是在递归回归的时候, 前一个语句要"或"一下1,就是为了保证后面的打印语句在回归时能够执行到。

可能很多人会觉得这种笔试题没有什么意义, 因为在实际项目中不可能写这么tricky的代码,写的麻烦,读的心烦,维护起来乱成一团。。。但是这短短的一句语句,却是十分考验人的,对递归算法,对C运算符,对逻辑智商都是有着不低的要求。所以,我觉得这是一个好题,好到让我担心没人能在规定时间里做出来:)

(搬自以前blog, 2007-08-04)

原文地址:https://www.cnblogs.com/baiyanhuang/p/1730742.html