I explain functions in detail in Chapter 8, but that won’t stop us from making use of a few from the standard library before that. Let’s do a quick reprise of what’s going on when you use functions and cover some of the terminology they introduce. A function is a named, self-contained block of code that carries out a specific task. Often, this will involve it performing some operation on data that you supply and then returning the result of that operation to your program. In those circumstances in which a function returns a value that is numeric, the function can participate in an arithmetic expression just like an ordinary variable. In general, a call to a function looks like this: FunctionName(argument1, argument2, ... ) Depending on the function in question, you can supply zero, one, or more values for it to work with by placing them in parentheses after its name when you call it from your program. The values you pass to the function in this way are called arguments. Like all values in C++, the arguments you pass to a function, and the value it returns to your program, have types that you must take care to conform with in order to use the function. You can access some numerical functions that you can apply to integers by adding an#includedirective for the Theabs()function returns the absolute value of the argument, which can be of typeintor typelong. The absolute value of a number is just its magnitude, so taking the absolute value of a negative number returns the number with a positive sign, whereas a positive number will be returned unchanged. The value returned by theabs()function will be of the same type as the argument, for example: int value = -20; The <sctdlib> Thediv()function takes two arguments, both of typeint. It returns the result of dividing the first argument by the second as well as the remainder from the operation in the form of a structure of typediv_t. I go into structures in detail later on, so for the moment you’ll just see how to access the quotient and the remainder from what is returned by thediv()function through an example: int value = 93; The first two statements define the variablesvalueanddivisorand give them the initial values 93 and 17, respectively. The next statement calls thediv()function to dividevaluebydivisor. You store the resulting structure of typediv_tthat is returned by the function in the variableresults, which is also of typediv_t. In the first output statement, you access the quotient fromresultsby appending the namequottoresults, separated by a period. The period is called the member access operator, and here you’re using it to access thequotmember of theresultsstructure. Similarly, in the last statement you use the member access operator to output the value of the remainder, which is available from theremmember of theresultsstructure. Any structure of typediv_twill have members with the namesquotandrem, and you always access them by using the member access operator. Note that you could have used literals directly as arguments to thediv()function. In this case, the statement calling the function would be div_t results = std::div(93, 17); Theldiv()function performs the same operation as thediv()function, but on arguments of typelong. The result is returned as a structure of typeldiv_t, which has membersquotandremthat are of typelong. CAUTION The Being able to generate random numbers in a program is very useful. You need to be able to build randomness into game programs, for instance; otherwise, they become very boring very quickly. The Therand()function return a random integer as typeint. The function doesn’t require any arguments, so you can just use it like this: int random_value = std::rand(); // A random integer You store the integer that’s returned by therand()function here in the variablerandom_value, but you could equally well use it in an arithmetic expression, for example: int even = 2*std::rand(); The value returned by therand()function will be a value that is from 0 toRAND_MAX.RAND_MAXis a symbol that is defined in BecauseRAND_MAXis defined by a preprocessing macro (you’ll learn what a preprocessing macro is in Chapter 10), it isn’t within thestdnamespace, so you don’t need to qualify the name when you use it. Any symbol that’s defined by a macro won’t be in thestdnamespace because it isn’t a name that refers to something. By the time the compiler gets to compile the code, such a symbol will no longer be present because it will have already been replaced by something else during the preprocessing phase. Making the Sequence Start at Random Usingrand()as you have so far, the sequence of numbers will always be the same. This is because the function uses a default seed value in the algorithm that generates the random numbers. This is fine for testing, but once you have a working game program, you’ll really want different sequences each time the program runs. You can change the seed value that will be used to generate the numbers by passing a new seed value as an integer argument to thesrand()function that is defined in std::srand(13); // Set seed for rand to 13 The argument to thesrand()function must be a value of typeunsigned int. Although the preceding statement will result inrand()generating a different sequence from the default, you really need a random seed to get a different sequence fromrand()each time you execute a program. Fortunately, the clock on your computer provides a ready-made source of random seed values. The std::srand((unsigned int)std::time(0)); There are a few things that you’ll have to take on trust for the moment. The argument to thetime()function here is0. There’s another possibility for the argument, but you don’t need it here so you’ll ignore it. The subexpression(unsigned int)serves to convert the value returned by thetime()function to typeunsigned int, which is the type required for the argument to thesrand()method. Without this, the statement wouldn’t compile. Type conversion is something else that you’ll look into later. Let’s put a working example together that makes use of random number generation. Try It Out: Generating Random IntegersHere’s the code: // Program 2.5 Using Random Integers #include int main() { cout << "First we will use the default sequence from rand().n"; cout << endl << "Now we will use a new seed for rand().n"; cout << "Three random integer from 0 to " << RAND_MAX << ": " On my system I get the following output: First we will use the default sequence from rand(). Three random integer from 0 to 32767: 6334 18467 41
Now we will use a new seed for rand().
HOW IT WORKS This is a straightforward use of therand()function, first with the default seed to start the sequence: cout << "A random integer from 0 to " << RAND_MAX << ": " Each call torand()returns a value that will be from 0 toRAND_MAX, and you call the function three times to get a sequence of three random integers. Next, you set the seed value as the current value of the system clock with this statement: srand((unsigned int)time(0)); // Set a new seed This statement will generally result in a different seed being set each time you execute the program. You then repeat the statement that you executed previously with the default seed set. Thus, each time you run this program, the first set will always produce the same output, whereas with the second set, the output should be different.
blog comments powered by Disqus |
|
|
|
|
|
|
|