Generate a random number using the C Preprocessor

2019-01-23 17:34发布

问题:

I would like to generate a random number or string using the C Preprocessor ... um ... I don't even know if this is possible, but I am trying to create variables on the fly (strings would be helpful here) and assign them values (integers). So there are a few things I am trying to do but the basic question remains - can I create a random string or number using the preprocessor.

回答1:

I take your question that you want to have a way of creating unique identifier tokens through the preprocessor.

gcc has an extension that is called __COUNTER__ and does what you expect from its name. You can combine this with macro concatenation ## to obtain unique identifiers.

If you have a C99 compiler you can use P99. It has macros called P99_LINEID and P99_FILEID. They can be used as

#include "p99_id.h"

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

and similarily for P99_FILEID.

The first mangles a name from your tokens and the line number and a hash that depends on the number of times the file "p99_id.h" had been included. The second macro just uses that hash and not the line number such that a name is reproducible at several places inside the same compilation unit.

These two macros also have counterparts P99_LINENO and P99_FILENO that just produce large numbers instead of identifier tokens.



回答2:

Based on 1999-01-15 Jeff Stout (thanks to @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;
}

Output:

247524236
3009541994
1129205949


回答3:

Don't do this in C. You'll end up confusing people. If you need to create variables on the fly, use malloc and realloc and maintain an array of their values.

To answer your question, no. The preprocessor doesn't include a random number generator. You can generate random numbers at runtime (with rand()), but if you really need them at compile time, you'll have to write your own preprocessor and run your code through it. Or you could just use 4, which was randomly determined by a roll of a fair 100 sided die.