Tomohiko Sakamoto 算法的晦涩 C 语法

问题描述

我偶然发现了这个版本的 Sakamoto 算法

dow(m,d,y){y-=m<3;return(y+y/4-y/100+y/400+"-bed=pen+mad."[m]+d)%7;}

我在 ideone.com 上尝试过,它确实有效。我对算法的工作原理不感兴趣,让我困惑的是语法。

我认为自己是一名中级 C 程序员,我完全不知道代码"-bed=pen+mad."[m] 部分发生了什么。

那是什么???

解决方法

这是 array subscription 上的 string literal。请记住,字符串文字实际上只是一个指向静态内存的指针。

操作等价于:

int m = 0;
char *str = "-bed=pen+mad.";
str[m];

char 是标量类型,因此您可以对值进行算术运算。

,

好的,我知道了。该算法需要一个查找表来根据月份添加值。

"-bed=pen+mad." 是一个 string,它是一个 char

的数组

它的价值是

0: ASCII '-' not relevant since the month 0 does not exist
1: ASCII 'b' = 98
2: ASCII 'e' = 101
3: ASCII 'd' = 100
4: ASCII '=' = 61
5: ASCII 'p' = 122
6: ASCII 'e' = 101
7: ASCII 'n' = 110
8: ASCII '+' = 43
9: ASCII 'm' = 109
10: ASCII 'a' = 97
11: ASCII 'd' = 100
12: ASCII '.' = 46

月份 m 用作索引,例如,如果我们在二月,即索引 2,则数组的位置 2 是 char 'e' 并且值 101 被添加到等式中。

它变得令人困惑,因为加号和等号使它看起来像一个等式,而像床、笔和疯狂这样的明显词会诱使大脑寻找不存在的意义。这只是一堆字符。

写这篇文章的人很铁杆

,
"-bed=pen+mad."[0] is '-' or,probably,45
"-bed=pen+mad."[1] is 'b' or,98
...
"-bed=pen+mad."[12] is '.' or,46
"-bed=pen+mad."[13] is '\0' or 0

因为该值最终将是 (...) % 7

"-bed=pen+mad."[0] % 7 // probably 3
"-bed=pen+mad."[1] % 7 // probably 0
...
"-bed=pen+mad."[12] % 7 // probably 4
"-bed=pen+mad."[13] % 7 // 0
,

坂本智彦的 dayofweek() 的扩展版本是 on Wikipedia

"-bed=pen+mad." 是一个常量字符数组,也可以这样写:

const char tab[] = { '-','b','e','d','=','p','n','+','m','a','.',0 };

考虑到这是 ASCII,"-bed=pen+mad." 也可以写成:

const char tab[] = { 45,98,101,100,61,112,110,43,109,97,46,0 };

现在,考虑到最终结果将是 %7,这也可以写成:

const char tab[] = { 3,3,2,5,1,4,6,0 };

现在,我们看到对于 1 到 12 之间的任何月份 m"-bed=pen+mad."[m]tab[m] 相同(全等 % 7),而 t[m-1] 与 {{1} 完全相同}} 在扩展版本中。