使用C预处理器生成随机数

17

我想使用C预处理器生成一个随机数或字符串......我甚至不知道这是否可能,但我正在尝试动态创建变量(字符串在这里很有用),并给它们分配值(整数)。因此,我正在尝试做一些事情,但是基本问题仍然存在 - 我可以使用预处理器创建随机字符串或数字吗。


1
简而言之:不行。您将需要编写自己的简单预处理器。别忘了设计一种测试您的随机源代码的方法。 - Peter G.
1
你看过这个吗?http://www.ciphersbyritter.com/NEWS4/RANDC.HTM 1999-01-15 Jeff Stout - rlb.usa
6
你真的需要“随机”,还是只需要“唯一”的变量名?如果是后者,可以考虑使用__LINE__来创建唯一的变量名。 - Paul R
1
我认为Paul已经确定了OP真正想做的事情。 - R.. GitHub STOP HELPING ICE
2个回答

22

根据1999年1月15日Jeff Stout的说法(感谢@rlb.usa)

#define UL unsigned long
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
#define MWC   (znew+wnew)
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
#define CONG  (jcong=69069*jcong+1234567)
#define KISS  ((MWC^CONG)+SHR3)
/*  Global static variables: 
    (the seed changes on every minute) */
static UL z=362436069*(int)__TIMESTAMP__, w=521288629*(int)__TIMESTAMP__, \
   jsr=123456789*(int)__TIMESTAMP__, jcong=380116160*(int)__TIMESTAMP__;


int main(int argc, _TCHAR* argv[]){
    cout<<KISS<<endl;
    cout<<KISS<<endl;
    cout<<KISS<<endl;
}

输出:

247524236
3009541994
1129205949

1
嵌入式系统的实现非常好。两个答案都很好。 - Xofo
它的意思是:“每一分钟种子都会改变”。是什么事件导致了它的改变? - user10133158
@user10133158 __TIMESTAMP__ 是一个编译器变量,精度为1分钟。因此,每次编译的不同分钟,种子都会改变。 - nergeia
2
这是误导性的,因为它没有使用预处理器来计算随机数,正如 OP 所请求的那样。相反,它插入了一块 C 代码块,将被编译成计算数字的代码。 - ScottJ
@ScottJ 不,代码处于预处理阶段。 - nergeia
1
@nergeia 无稽之谈。使用 gcc -E(仅预处理器)运行它以查看结果:cout<<(((((z=36969*(z&65535)+(z>>16))<<16)+((w=18000*(w&65535)+(w>>16))&65535))^ (jcong=69069*jcong+1234567))+(jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5)))<<endl; - ScottJ

16

我理解你的问题是想要通过预处理器创建唯一标识符的方法。

gcc有一个称为__COUNTER__的扩展,可以根据其名称实现你期望的功能。你可以与宏连接符##结合使用以获得唯一标识符。

如果你有一个C99编译器,你可以使用P99。它有名为P99_LINEIDP99_FILEID的宏。它们可以被用作

#include "p99_id.h"

P99_LINEID(some, other, tokens, to, make, it, unique, on, the, line)

类似地,对于P99_FILEID的处理也是如此。

第一个宏会从您的标记、行号和取决于文件“p99_id.h”被包含的次数的哈希中弄乱名称。第二个宏只使用该哈希而不是行号,以便在同一编译单元的多个位置上复制名称。

这两个宏还有相应的对应物P99_LINENOP99_FILENO,它们只会生成大型数字而不是标识符标记。


2
那个扩展不是 __COUNTER__ 吗?https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html - Alyssa Haroldsen
1
想要补充一下,__COUNTER__ 在其他编译器中也是可用的,比如 MSVC。只需注意,__COUTER__ 仅对预处理器当前解析的文件唯一(对于每个源文件解析,它从 0 开始)。 - Florian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接