#include <stdio.h>
#include <stdlib.h>
main() {
int j, u[23] = {0};
while (!u[19]) {
while (u[j = rand() % 23]++)
;
putchar("uatChks rteJ r hon,neca"[j]);
}
}
是一段用于打印的模糊代码
只是另一个C黑客,
它适用于我尝试过的两种不同的在线编译器/解释器(ideone.com 和 codepad.org(,但当我使用 GCC 运行时就不行了。
当我构建它并使用 GCC 运行它时,它会打印:
,Cthehasok tre anu
在我的计算机上,我正在使用以下命令构建它:
gcc C:ProgrammingcJACH.c -o JACH
我认为问题与rand()
功能有关,也许与RAND_MAX
宏有关:
在我的编译器中,RAND_MAX
被定义为 32767
,而在 ideone.com 上,它是2147483647
。我不确定这是否真的与此有关,但我相信在运行如下测试后,rand()
是问题所在:
srand(0);
int i;
for (i=1;i<4;i++) {
printf("%d: %dn", i, rand() % 23);
}
这段代码在编译器之间产生了非常不同的结果,
海湾合作委员会:
1: 15
2: 14
3: 9
ideone.com:
1: 11
2: 0
3: 6
有谁知道如何强制我的编译器提供与 ideone.com/online 编译器相同的结果?
线性同余生成器是生成伪随机数的简单方法,可以使用很少的代码来实现。
事实上,如果您使用生成最大长度序列的序列,则无需检查已返回的值,因为它将在重复之前生成每个值一次。
此代码适用于任何系统,并且由于它不依赖于除putchar()
之外的任何库调用,因此它将始终产生相同的输出。当j
返回到其原始值零时,while()
循环将退出:
#include <stdio.h>
int main() {
int j=0;
while (putchar("nae ,hhtr tseCouk nJcra"[j=(j*93+19)%23]) && j);
return 0;
}
<小时 />更新
您提供的编号规则(1804289383、846930886、1681692777、1714636915(显示 ideone 使用 GLIBC 随机数生成器,该生成器从基于种子值初始化的 34 个整数池中计算随机数。
如果您使用默认种子值 1(不是零,实际上不允许并在内部更改为 1(,则可以完全省略初始化阶段,最终得到以下函数:
int default_rand() {
static unsigned int i=3, r[34] = { 0xf3bec5da, 0x991539b1, 0x16a5bce3, 0x6774a4cd,
0x55928aca, 0xc34a51a2, 0x73b5def3, 0x3e01511e, 0x4e508aaa, 0x61048c05,
0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41 };
i = (i+1) % 34;
return (r[i] = r[(i+3)%34] + r[(i+31)%34]) >> 1;
}
您可以亲自验证此函数生成的号码是否与调用srand(0)
或srand(1)
(ideone 链接(后对rand()
的连续调用完全相同。