无法理解这段代码?

Ris*_*pta 4 c++ function comma-operator

任何人都可以帮助我理解以下代码: -

int r, countIt(int n) {
    while (r += "            2  "[n % 10] & 3, n /= 10);
    return r;
}
Run Code Online (Sandbox Code Playgroud)

我在codefights.com的挑战中找到了这段代码,https://codefights.com/challenge/v5Zg8trjoun3PTxrZ/solutions/Aj3ppbhSShixt4nBi

这是计算数字中孔数的解决方案.
例如

1111 = 0  
0000 = 4  
1234 = 0  
8888 = 8   
Run Code Online (Sandbox Code Playgroud)

我无法理解以下内容:
1.此代码的逻辑
2.逗号(,)运算符用于函数的返回数据类型
3.在字符串后使用[]运算符.
实际上整个代码.

Igo*_*nik 9

这是某种混淆的C竞赛提交吗?或编码高尔夫


首先,奇怪的声明.它只是在一行上组合了两个不相关的声明.就像

int x, y;
Run Code Online (Sandbox Code Playgroud)

相当于

int x;
int y;
Run Code Online (Sandbox Code Playgroud)

所以你的代码相当于

int r;
int countIt(int n) {...}
Run Code Online (Sandbox Code Playgroud)

这是一个鲜为人知的,幸运的是,你可以做的很少使用C语法的怪癖.


如果以这种方式编写,循环将变得更清晰:

do {
  r += "            2  "[n % 10] & 3;
  n /= 10;
} while (n);
Run Code Online (Sandbox Code Playgroud)

它基本上迭代了十进制表示中的数字n.


现在是部分r += " 2 "[n % 10] & 3;.n % 10是.的低位十进制数字n.我们使用它作为字符串文字的索引(它只是一个chars 数组),然后提取字符ASCII码的两个低位,并丢弃其余部分.我很确定,在您复制此代码的原始程序中,该文字中的字符不是空格,而是选择某些不可打印的字符,使得它们的ASCII代码的两个低位完全给出了相应数字中的"孔"数.2字符是红鲱鱼 - 它位于第12位,但实际上只使用字符0到9.

换句话说,这部分可以通过这种方式更清晰地写出:

static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int digit = n % 10;
r += numHoles[digit];
Run Code Online (Sandbox Code Playgroud)

放在一起,我们有:

int countIt(int n) {
  // number of holes in digit      0  1  2  3  4  5  6  7  8  9
  static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
  int r = 0;
  do {
    int digit = n % 10;
    r += numHoles[digit];
    n /= 10;
  } while (n);
  return r;
};
Run Code Online (Sandbox Code Playgroud)