问题描述
我偶然发现了这个版本的 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} 完全相同}} 在扩展版本中。