Wednesday, December 23, 2009

rand() and srand() in C/C++

RAND:

C++ header
C header

int rand ( void );
Generate random number

Returns a pseudo-random integral number in the range 0 to RAND_MAX.

This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using srand.

RAND_MAX is a constant defined in . Its default value may vary between implementations but it is granted to be at least 32767.

A typical way to generate pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:

( value % 100 ) is in the range 0 to 99
( value % 100 + 1 ) is in the range 1 to 100
( value % 30 + 1985 ) is in the range 1985 to 2014

Notice though that this modulo operation does not generate a truly uniformly distributed random number in the span (since in most cases lower numbers are slightly more likely), but it is generally a good approximation for short spans.

#include
#include
#include

int main ()
{
int iSecret, iGuess;

/* initialize random seed: */
srand ( time(NULL) );

/* generate secret number: */
iSecret = rand() % 10 + 1;

do {
printf ("Guess the number (1 to 10): ");
scanf ("%d",&iGuess);
if (iSecret else if (iSecret>iGuess) puts ("The secret number is higher");
} while (iSecret!=iGuess);

puts ("Congratulations!");
return 0;
}

Output:

Guess the number (1 to 10): 5
The secret number is higher
Guess the number (1 to 10): 8
The secret number is lower
Guess the number (1 to 10): 7
Congratulations!

In this example, the random seed is initialized to a value representing the second in which the program is executed (time is defined in the header ). This way to initialize the seed is generally a good enough option for most randoming needs.


SRAND:

void srand ( unsigned int seed );
Initialize random number generator

The pseudo-random number generator is initialized using the argument passed as seed.

For every different seed value used in a call to srand, the pseudo-random number generator can be expected to generate a different succession of results in the subsequent calls to rand.
Two different initializations with the same seed, instructs the pseudo-random generator to generate the same succession of results for the subsequent calls to rand in both cases.

If seed is set to 1, the generator is reinitialized to its initial value and produces the same values as before any call to rand or srand.

In order to generate random-like numbers, srand is usually initialized to some distinctive value, like those related with the execution time. For example, the value returned by the function time (declared in header ) is different each second, which is distinctive enough for most randoming needs.

#include
#include
#include

int main ()
{
printf ("First number: %d\n", rand() % 100);
srand ( time(NULL) );
printf ("Random number: %d\n", rand() % 100);
srand ( 1 );
printf ("Again the first number: %d\n", rand() %100);

return 0;
}

Output:

First number: 41
Random number: 13
Again the first number: 41


random number, random number generator


Also, check out Free ISTQB Training Material here

www.testing4success.com - Application QA/Testing     Mobile App QA/Testing     Web Testing     Training
Iphone App QA  Android App QA  Web QA 

sizeof Operator- C/C++

sizeof Operator
The sizeof operator yields the size of its operand with respect to the size of type char.

Grammar

unary-expression:
sizeof unary-expression
sizeof ( type-name )
The result of the sizeof operator is of type size_t, an integral type defined in the include file STDDEF.H. This operator allows you to avoid specifying machine-dependent data sizes in your programs.

The operand to sizeof can be one of the following:

A type name. To use sizeof with a type name, the name must be enclosed in parentheses.
An expression. When used with an expression, sizeof can be specified with or without the parentheses. The expression is not evaluated.
When the sizeof operator is applied to an object of type char, it yields 1. When the sizeof operator is applied to an array, it yields the total number of bytes in that array, not the size of the pointer represented by the array identifier. To obtain the size of the pointer represented by the array identifier, pass it as a parameter to a function that uses sizeof. For example:



#include

size_t getPtrSize( char *ptr )
{
return sizeof( ptr );
}

using namespace std;
int main()
{
char szHello[] = "Hello, world!";

cout << "The size of a char is: "
<< sizeof( char )
<< "\nThe length of " << szHello << " is: "
<< sizeof szHello
<< "\nThe size of the pointer is "
<< getPtrSize( szHello ) << endl;
}
Output

The size of a char is: 1
The length of Hello, world! is: 14
The size of the pointer is 4


When the sizeof operator is applied to a class, struct, or union type, the result is the number of bytes in an object of that type, plus any padding added to align members on word boundaries. The result does not necessarily correspond to the size calculated by adding the storage requirements of the individual members. The /Zp compiler option and the pack pragma affect alignment boundaries for members.

The sizeof operator never yields 0, even for an empty class.

The sizeof operator cannot be used with the following operands:

Functions. (However, sizeof can be applied to pointers to functions.)
Bit fields.
Undefined classes.
The type void.
Dynamically allocated arrays.
External arrays.
Incomplete types.
Parenthesized names of incomplete types.
When the sizeof operator is applied to a reference, the result is the same as if sizeof had been applied to the object itself.

If an unsized array is the last element of a structure, the sizeof operator returns the size of the structure without the array.

The sizeof operator is often used to calculate the number of elements in an array using an expression of the form:

sizeof array / sizeof array[0]

Static Variable in C++

Static Variable in C++:

You have to define the static data member outside the class declaration.

When you declare a variable or function at file scope (global and/or namespace scope), the static keyword specifies that the variable or function has internal linkage. When you declare a variable, the variable has static duration and the compiler initializes it to 0 unless you specify another value.

When you declare a variable in a function, the static keyword specifies that the variable retains its state between calls to that function.

When you declare a data member in a class declaration, the static keyword specifies that one copy of the member is shared by all instances of the class. A static data member must be defined at file scope. An integral data member that you declare as const static can have an initializer.

When you declare a member function in a class declaration, the static keyword specifies that the function is shared by all instances of the class. A static member function cannot access an instance member because the function does not have an implicit this pointer. To access an instance member, declare the function with a parameter that is an instance pointer or reference.



//statictest.h

class

statictest

{

public:

static int a;

void sum();

};

///////////////////////////////////////////////

//statictest.cpp

#include "statictest.h"

int statictest::a; // Defining outside the class. By default value of a=0.

void statictest::sum(){

a=0;

}

///////////////////////////////////////////////

//main.cpp

#include "statictest.h"

int main()

{

statictest test;

test.sum();

}

///////////////////////////////////////////////


#include

using namespace std;
class CMyClass {
public:
static int m_i;
};

int CMyClass::m_i = 0;
CMyClass myObject1;
CMyClass myObject2;

int main() {
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;

myObject1.m_i = 1;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;

myObject2.m_i = 2;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;

CMyClass::m_i = 3;
cout << myObject1.m_i << endl;
cout << myObject2.m_i << endl;
}


Output--
0
0
1
1
2
2
3
3

Static Variable in C

STATIC VARIABLE in C:

Static Variable as Local Variable in a function:

Variables defined local to a function disappear at the end of the function scope. So when we call the function again, storage for variables is created and
values are reinitialized. So if we want the value to be extent throughout the life of a program, we can define the local variable as "static." Initialization is performed only at the first call and data is retained between func calls.

Had it been global variable, it would have been available outside the scope of the function, but static variable is not available outside the scope of a function (helpful in localizing errors - as it can't be changed outside the function scope).

Static Variable as Global Variable in a File:
The Scope of the variable is limited to the file only. It cannot be used outside the file. It also retains it's value throughout the life.
It works in a same way as namespace in C++, as the same variable with the same name can be used in another file and yet will be different from the static variable in the first file.

extern in C/C++

How exactly to use extern in C and C++ ?

The extern keyword is used to tell the compiler that a data object is declared in a different *.cpp or *.c file (code unit). Its required for data objects but optional for function declarations. For example, you have two *.cpp files named A.cpp and B.cpp. B.cpp has a global int that needs to be used in A.cpp.

// A.cpp
#include
// other includes here
...
extern int hours; // this is declared globally in B.cpp

int foo()
{
hours = 1;
}



// B.cpp
#include
// other includes here
...
int hours; // here we declare the object WITHOUT extern
extern void foo(); // extern is optional on this line

int main()
{
foo();
}

Data Types in C/C++

Type--Size in Bits--Range

char--8-- -127 to +127
unsigned char--8-- 0 to 255
signed char--8-- -127 to +127
int-- 16 or 32 -- -32767 to 32767
unsigned int-- 16 or 32-- 0 to 65535
signed int-- 16 or 32-- -32767 to 32767
short int-- 16-- -32767 to 32767
unsigned short int-- 16 -- 0 to 65535
signed short int -- 16 -- -32767 to 32767
long int & signed long int-- 32 -- -2147438647 to +2147438647
unsigned long int -- 32 -- 0 to 4294967295
float -- 32 -- Six digits of precision
double -- 64 -- Ten digits of precision
long double -- 80 -- Ten digits of precision

P.S. All the data types are application in C++ as well will additional bool and wchar_t.

Sunday, January 18, 2009

Function Pointer and its relation to function parameters

Its a very basic fact but an important one so mentioning it over here will help for sure.

  • A pointer to a function must have the same type as the function. Attempts to take the address of a function by reference without specifying the type of the function will produce an error.
  • The type of a function is not affected by arguments with default values.
  • The following example shows that default arguments are not considered part of a function's type. The default argument allows you to call a function without specifying all of the arguments, it does not allow you to create a pointer to the function that does not specify the types of all the arguments. Function f can be called without an explicit argument, but the pointer badpointer cannot be defined without specifying the type of the argument:

int f(int = 0);
void g()
{
int a = f(1); // ok
int b = f(); // ok, default argument used
}
int (*pointer)(int) = &f; // ok, type of f() specified (int)
int (*badpointer)() = &f; // error, badpointer and f have
// different types. badpointer must
// be initialized with a pointer to
// a function taking no arguments.

So, it means the argument should be passed of same type as argument as it was done to function.