首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这段代码可以在线运行,但不是来自我自己的编译器。

这段代码可以在线运行,但不是来自我自己的编译器。
EN

Stack Overflow用户
提问于 2014-12-02 19:23:04
回答 1查看 168关注 0票数 0
代码语言:javascript
复制
#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

在我的计算机上,我使用以下命令构建它:

代码语言:javascript
复制
gcc C:\Programming\c\JACH.c -o JACH

我认为问题与rand()函数有关,可能与RAND_MAX宏有关:

在我的编译器中,RAND_MAX被定义为32767,而在ideone.com上,定义为2147483647。我不确定这是否真的与此有关,但我确信,在运行了这样的测试之后,rand()就是问题所在:

代码语言:javascript
复制
srand(0);
int i;
for (i=1;i<4;i++) {
    printf("%d: %d\n", i, rand() % 23);
}

这段代码在编译器之间产生了非常不同的结果,

gcc:

代码语言:javascript
复制
1: 15
2: 14
3: 9

ideone.com:

代码语言:javascript
复制
1: 11
2: 0
3: 6

有人知道我怎样才能强迫编译器提供与ideone.com/online编译器相同的结果吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-02 20:13:50

线性同余发生器是一种生成伪随机数的简单方法,可以使用非常少的代码来实现。

实际上,如果您使用一个生成最大长度序列的值,那么就不需要检查已经返回的值,因为它将在重复之前生成每个值一次。

此代码将在任何系统上工作,而且由于它不依赖于除putchar()之外的任何库调用,所以它总是产生相同的输出。当while()循环返回到其原始值为零时,j循环将退出:

代码语言:javascript
复制
#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),则可以完全省略初始化阶段,最后得到以下函数:

代码语言:javascript
复制
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;
}

您可以自己验证,此函数在调用rand()srand(1) (同上的链接)之后生成的数字与对(同上的链接)的连续调用完全相同。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27257271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档