在没有条件语句或运算符的情况下重写一段C代码?

在没有条件语句或运算符的情况下重写一段C代码?,c,C,我在一次技术面试中,面试官给了我一段这样的代码 int a=1; a++; ...something.. ...something. if(a==25) a=0; 他让我重写这段代码,而不使用switch、if-else或if条件的三元运算符。如何做到这一点?其实很简单: a *= (a != 25); 如果a等于25,则将a乘以0,否则将a乘以1 如果您也不允许测试相等性,那么这里有一个完整的算术方法: unsigned int v = a - 25; /* t

我在一次技术面试中,面试官给了我一段这样的代码

  int a=1;
  a++;
  ...something..
  ...something.
  if(a==25)
   a=0;

他让我重写这段代码,而不使用switch、if-else或if条件的三元运算符。如何做到这一点?

其实很简单:

a *= (a != 25);
如果a等于25,则将a乘以0,否则将a乘以1

如果您也不允许测试相等性,那么这里有一个完整的算术方法:

unsigned int v = a - 25;

/* test for bits set and put result in lsb of v */
v |= v >> 16;
v |= v >> 8;
v |= v >> 4;
v |= v >> 2;
v |= v >> 1;

/* set a to a if lsb of v is 1, else set to 0 */
a *= v & 1;

这不使用“开关,if-else或三元运算符”

记住赋值只是一个普通表达式,因此可以用作另一个表达式的一部分。例如,您可以使用短路逻辑and运算符:

a == 25 && (a = 0);

您需要在赋值周围加括号,因为赋值小于
&&
运算符。

由于您使用的是未初始化的变量,因此提出的问题给出了未定义的行为。因此,您可以自由编写任何您喜欢的代码(只要它可以编译)

参见C标准6.3.2.1p2:

如果左值指定自动存储持续时间的对象,则 可以用寄存器存储类声明(从未声明过 该对象未初始化(未声明) 使用初始值设定项,且之前未对其进行赋值 要使用),该行为未定义


在我看来,这是一个聪明的答案:尽管你用这种方式回答问题时要优雅一些是明智的。

如果上下文暗示的是一个计数循环,
a
总是重复周期
0..24
,那么也许数学上更吸引人的解决方案是

a = (a+1) % 25;
但是,在
a
可以是任何东西的情况下,这当然不起作用,只有在
a==25
的情况下,才应该重置它,而
a==26
的情况应该被忽略


面试官可能会喜欢它,如果你搜索这样的“语义”解决方案,并且可以解释什么时候使用它。

我想面试官希望你使用这句话,而不是
,如果

a %= 25;

另一个有趣的答案可能是

for ( ; a == 25 ; ) {
    a = 0; break;
}

这不使用“if-else”、“switch”或“trialoperator”

Was
a
不确定,就像你发布的一样,或者它被初始化为什么?也许是离题的,但如果我在面试中遇到这样的问题,我会离开那里。@zubergu这是一个无用的问题,不能告诉你一个人是否适合这份工作。这是一个虚构的场景,在真实的项目中你永远不会遇到。@Stijn。我完全同意。更糟糕的是,这个代码是UB。这是分裂。看看我的答案。已经被否决了。面试中的问题应该设计成能让应聘者发挥出最好的一面。这又是一个愚蠢的面试问题;我只是好奇,它下面不是还有一根树枝吗?我想说问题中的语法更具可读性。@legends2k不,当有多个代码路径时会出现分支,这只有一个(首先是测试,然后是乘法)。当然,这不包括编译器优化,这可能会决定分支速度更快25可能需要分支,但这不是最初的问题所在。@AndreyT我添加了一个在任何机器上都应该没有分支的版本。从来没说过这么快,伙计?int不是静态存储类类型是从哪里得到的?另外,问题是如何重写它,而不是它必须是可编译的-1@Zaibis:当然可以,但你如何重新编写可能产生任何结果的内容?如果我在采访中看到这样的问题,那将是我想到的第一件事——他们希望你浪费时间分析无法解决的问题的解决方案。GRE定量部分有很多这样的问题,如果你不学会正确地分析它们,你将永远无法获得有竞争力的分数。在面试中,雇主正在评判你的分析能力——如果我是面试官,我决不会雇佣一个不指出
a
未初始化的人。请注意,在此期间,问题被更改为初始化变量a!这是不等价的。如果a为26,则将其设置为1。这取决于上下文-我认为在此上下文中,有疑问的是隐式假设
a
始终从0开始递增。如果我是一名面试官,我会很高兴得到这样一个答案。我有一个类似的想法,但是用while而不是for
for ( ; a == 25 ; ) {
    a = 0; break;
}