Tuesday 30 April 2013

Introduction to strings

Variables that can store non-numerical values that are longer than one single character are known as strings.
The C++ language library provides support for strings through the standard string class. This is not a
fundamental type, but it behaves in a similar way as fundamental types do in its most basic usage.
A first difference with fundamental data types is that in order to declare and use objects (variables) of this type we
need to include an additional header file in our source code: <string> and have access to the std namespace

// my first string
#include <iostream>
#include <string>
//using namespace std;
int main ()
{
string mystring = "This is a string";
cout << mystring;
return 0;
}
//This is a string
As you may see in the previous example, strings can be initialized with any valid string literal just like numerical
type variables can be initialized to any valid numerical literal. Both initialization formats are valid with strings:
string mystring = "This is a string";
string mystring ("This is a string");
Strings can also perform all the other basic operations that fundamental data types can, like being declared without
an initial value and being assigned values during execution:
// my first string
#include <iostream>
#include <string>
//using namespace std;
int main ()
{
string mystring;
mystring = "This is the initial string content";
cout << mystring << endl;
mystring = "This is a different string content";
cout << mystring << endl;
return 0;
}
//This is the initial string content
//This is a different string content
For more details on C++ strings, you can have a look at the string class reference.

Monday 29 April 2013

Initialization of variables

When declaring a regular local variable, its value is by default undetermined. But you may want a variable to store
a concrete value at the same moment that it is declared. In order to do that, you can initialize the variable. There
are two ways to do this in C++:
The first one, known as c-like, is done by appending an equal sign followed by the value to which the variable will
be initialized:
type identifier = initial_value ;
For example, if we want to declare an int variable called a initialized with a value of 0 at the moment in which it is
declared, we could write:
int a = 0;
The other way to initialize variables, known as constructor initialization, is done by enclosing the initial value
between parentheses (()):
type identifier (initial_value) ;
For example:
int a (0);
Both ways of initializing variables are valid and equivalent in C++.
// initialization of variables
#include <iostream>
using namespace std;
int main ()
{
int a=5; // initial value = 5
int b(2); // initial value = 2
int result; // initial value
undetermined
a = a + 3;
result = a - b;
cout << result;
return 0;
}

Scope of variables

All the variables that we intend to use in a program must have been declared with its type specifier in an earlier
point in the code, like we did in the previous code at the beginning of the body of the function main when we
declared that a, b, and result were of type int.
A variable can be either of global or local scope. A global variable is a variable declared in the main body of the
source code, outside all functions, while a local variable is one declared within the body of a function or a block.

Global variables can be referred from anywhere in the code, even inside functions, whenever it is after its
declaration.
The scope of local variables is limited to the block enclosed in braces ({}) where they are declared. For example, if
they are declared at the beginning of the body of a function (like in function main) their scope is between its
declaration point and the end of that function. In the example above, this means that if another function existed in
addition to main, the local variables declared in main could not be accessed from the other function and vice versa.

Saturday 27 April 2013

Declaration of variables

In order to use a variable in C++, we must first declare it specifying which data type we want it to be. The syntax
to declare a new variable is to write the specifier of the desired data type (like int, bool, float...) followed by a valid
variable identifier. For example:
int a;
float mynumber;
These are two valid declarations of variables. The first one declares a variable of type int with the identifier a. The
second one declares a variable of type float with the identifier mynumber. Once declared, the variables a and
mynumber can be used within the rest of their scope in the program.
If you are going to declare more than one variable of the same type, you can declare all of them in a single
statement by separating their identifiers with commas. For example:
int a, b, c;
This declares three variables (a, b and c), all of them of type int, and has exactly the same meaning as:
int a;
int b;
int c;
The integer data types char, short, long and int can be either signed or unsigned depending on the range of
numbers needed to be represented. Signed types can represent both positive and negative values, whereas
unsigned types can only represent positive values (and zero). This can be specified by using either the specifier
signed or the specifier unsigned before the type name. For example:
unsigned short int NumberOfSisters;
signed int MyAccountBalance;
By default, if we do not specify either signed or unsigned most compiler settings will assume the type to be
signed, therefore instead of the second declaration above we could have written:
int MyAccountBalance;
with exactly the same meaning (with or without the keyword signed)
An exception to this general rule is the char type, which exists by itself and is considered a different fundamental
data type from signed char and unsigned char, thought to store characters. You should use either signed or
unsigned if you intend to store numerical values in a char-sized variable.
short and long can be used alone as type specifiers. In this case, they refer to their respective integer
fundamental types: short is equivalent to short int and long is equivalent to long int. The following two
variable declarations are equivalent:
short Year;
short int Year;
Finally, signed and unsigned may also be used as standalone type specifiers, meaning the same as signed int
and unsigned int respectively. The following two declarations are equivalent:
unsigned NextYear;
unsigned int NextYear;
To see what variable declarations look like in action within a program, we are going to see the C++ code of the
example about your mental memory proposed at the beginning of this section:
// operating with variables
#include <iostream>
using namespace std;
int main ()
{
// declaring variables:
int a, b;
int result;
// process:
a = 5;
b = 2;
a = a + 1;
result = a - b;
// print out the result:
cout << result;
// terminate the program:
return 0;
}
4
Do not worry if something else than the variable declarations themselves looks a bit strange to you. You will see
the rest in detail in coming sections.

Fundamental data types

When programming, we store the variables in our computer's memory, but the computer has to know what kind of
data we want to store in them, since it is not going to occupy the same amount of memory to store a simple
number than to store a single letter or a large number, and they are not going to be interpreted the same way.
The memory in our computers is organized in bytes. A byte is the minimum amount of memory that we can
manage in C++. A byte can store a relatively small amount of data: one single character or a small integer
(generally an integer between 0 and 255). In addition, the computer can manipulate more complex data types that
come from grouping several bytes, such as long numbers or non-integer numbers.
Next you have a summary of the basic fundamental data types in C++, as well as the range of values that can be
represented with each one:

* The values of the columns Size and Range depend on the system the program is compiled for. The values
shown above are those found on most 32-bit systems. But for other systems, the general specification is that int
has the natural size suggested by the system architecture (one "word") and the four integer types char, short,
int and long must each one be at least as large as the one preceding it, with char being always 1 byte in size.
The same applies to the floating point types float, double and long double, where each one must provide at
least as much precision as the preceding one.

Identifiers In Language


  • A valid identifier is a sequence of one or more letters, digits or underscore characters (_). Neither spaces nor punctuation marks or symbols can be part of an identifier. 


  • Only letters, digits and single underscore characters are valid. In addition, variable identifiers always have to begin with a letter. 

  • They can also begin with an underline character (_), but in some cases these may be reserved for compiler specific keywords or external identifiers, as well as identifiers containing two successive underscore characters anywhere. In no case they can begin with a digit.


  • Another rule that you have to consider when inventing your own identifiers is that they cannot match any keyword of the C++ language nor your compiler's specific ones, which are reserved keywords.


  • The standard reserved keywords are: asm, auto, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register,reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while Additionally, alternative representations for some operators cannot be used as identifiers since they are reserved words under some circumstances: and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq Your compiler may also include some additional specific reserved keywords.


  • Very important: The C++ language is a "case sensitive" language. 


  • That means that an identifier written in capital letters is not equivalent to another one with the same name but written in small letters. 


  • Thus, for example, the RESULT variable is not the same as the result variable or the Result variable. These are three different variable identifiers.

Variables and Data Types.

The usefulness of the "Hello World" programs shown in the previous section is quite questionable. We had to write
several lines of code, compile them, and then execute the resulting program just to obtain a simple sentence
written on the screen as result. It certainly would have been much faster to type the output sentence by ourselves.
However, programming is not limited only to printing simple texts on the screen. In order to go a little further on
and to become able to write programs that perform useful tasks that really save us work we need to introduce the
concept of variable.
Let us think that I ask you to retain the number 5 in your mental memory, and then I ask you to memorize also
the number 2 at the same time. You have just stored two different values in your memory. Now, if I ask you to add
1 to the first number I said, you should be retaining the numbers 6 (that is 5+1) and 2 in your memory. Values
that we could now for example subtract and obtain 4 as result.
The whole process that you have just done with your mental memory is a simile of what a computer can do with
two variables. The same process can be expressed in C++ with the following instruction set:
a = 5;
b = 2;
a = a + 1;
result = a - b;
Obviously, this is a very simple example since we have only used two small integer values, but consider that your
computer can store millions of numbers like these at the same time and conduct sophisticated mathematical
operations with them.
Therefore, we can define a variable as a portion of memory to store a determined value.
Each variable needs an identifier that distinguishes it from the others, for example, in the previous code the
variable identifiers were a, b and result, but we could have called the variables any names we wanted to invent,
as long as they were valid identifiers.

Thursday 25 April 2013

The following shows a concatenation operator for the string class:
#include <iostream.h>
#include <string.h>
class string {
private:
char *str;
public:
constructors and destructors as before
string operator+ (const string& rhs) const
{
char *s;
// create a new C style string holding
// the concatenated text
s = new char [strlen(str)+strlen(rhs.str)+1];
strcpy(s,str);
strcat(s,rhs.str);
// create a new `string', initialising it with the C
// style string
string newstring(s);
// delete the C style string, no longer needed
delete [] s;
// return a copy of the newly created string
return newstring;
}
void print() const
{
cout << str;
}

Operators as Member Functions

It is possible to define operators for classes. These operators can be infix binary operators
or unary operators. It is only possible to define operators that use an existing C++ operator
symbol, and the precedence of the symbol cannot be changed. There are some operators
that cannot be defined, these are:
. .* :: ?: sizeof # ##
Unary operators are defined as a member function taking no parameters, binary operators
are defined as member functions that take one parameter—the object on the right hand side
of the operator.
When defining an assignment operator (operator=) always declare it to take a reference
to the object on the right hand side of the assignment operator and return a reference to the
object on the left of the operator; this will permit assignments to be chained (a = b = c;).
Also declare the parameter (the object on the right of the operator) to be const to prevent
accidental modification and also to permit const objects to be used on the right hand side
of the assignment operator.
class string {
char *str;
public:
string& operator= (const string& rhs)
{
// delete the current string
delete [] str;
// allocate enough room for the new one
str = new char [ strlen(rhs.str) + 1 ];
// copy in the string
strcpy(str, rhs.str);
return *this; // see 2.2.12
}
};

Member Functions

Member functions are functions that are defined or declared within the body of a class
definition. They form part of the class description. Member functions are normally used to
provide operations on the class data. As they form part of the class definition, each instance
(variable) of the class will have associated with it the operations defined within the class.
By making the functions that modify or read the data contained in the class member
functions we know that any code that sets or reads the data incorrectly must be within the
class itself. This helps debugging and makes it easier to produce abstract data types.
Member functions are also referred to as class methods.
If the code for a member function is defined within the class, then that member function will
be treated as an inline function (see 1.12); more normally the member function is declared
within the class and defined elsewhere. The scope resolution operator, ::, is used to specify
the class to which the function belongs.
An alternative way of defining the print method from the string class shown above
would be:
class string {
private:
char *str;
public:
constructors and destructors
// declare the print method
void print() const;
};
// define the print method
void string::print() const
{
cout << str;
}

Constructors and Destructors

Constructor methods are called when an object is created, destructor methods are called
when the object is destroyed. For automatic objects this will be on entry and exit from the
block in which the object is defined. Constructors are frequently used for memory allocation
and initialisation, destructors could be used for deallocation of storage in a data structure.
For a class called string, the constructor is called string and the destructor is called
~string.
Constructors cannot return a value, but it is also invalid to declare them as returning void.
Several constructors can be specified, as long as they have different parameter lists.
Aconstructor that takes no parameters is called the default constructor, and a constructor
that takes an object of the same class as its parameter is called the copy constructor.
The copy constructor takes a reference to an object of the same class. So that const
objects can be used as an initialiser, the parameter should be declared to be const.
class string {
char *str;
public:
string() {} // default constructor
string(const string& s) {}
// copy constructor
~string() {} // destructor
If a constructor can take parameters, then the parameters can be specified using the
following syntax:
string s(parameters);
There are also two methods of calling the copy constructor after having first constructed a
new temporary object:
string s = string(parameters);
or the abbreviated form:
string s = parameter;
For example, the following are all valid ways of initialising a string using a char *
initialiser; the first uses a constructor that takes a char * parameter, the others use the
char * constructor to create a new object, and then use the copy constructor to initialise
the object:
string s1("one");
string s2 = string("two");
string s3 = "three";
The copy constructor is used for passing parameters by value; constructors are also needed
when returning values from functions.
string search(const string s, char c)
{
return string(strchr(s.str,c));
}

When the search function is called, the argument is copied and a new string created
using the copy constructor to initialise it. When the string value is returned from
search, again a new string is created, but this time the constructor used is the one that
takes a char * parameter.

Objects

An object is an instance of a class. For object read variable!
Every time we define a variable we get a new object which has all the properties of the
associated class. This is the same as with the built-in types of C (float, int etc.)—they
have certain properties (range of values, operations etc), the bonus is that we can make up
our own as well!

Structures

Structures are similar to classes, but the default is for members to be public rather than
private. Therefore structures can contain both data and functions.

Wednesday 24 April 2013

Classes

The Class Construct
Aclass definition gives the data and the operations that apply to that data. The data can be
private, public or protected enabling data hiding and construction of Abstract
Data Types (ADTs).
An example of a simple class is given below:
#include <iostream.h>
#include <string.h>
class string {
char *str;
public:
string() // default constructor, takes
// no parameters
{
str = NULL;
}
string(const char *s)
// constructor with `char *' argument
{
str = new char [strlen(s) + 1];
strcpy(str,s);
}
string(const string& t)
// copy constructor, takes a reference
// to another string as the parameter
{
str = new char [strlen(t.str) + 1];
strcpy(str,t.str);
}
~string() // destructor
{
delete [] str;
}
void print() const
// print a string
{
cout << str;
}
};
int main()
{
string s1; // use default constructor
string s2("hello world");
// use constructor with `char *' argument
string s3(s2);
// use copy constructor
// print the strings
s1.print();
s2.print();
s3.print();
return 0;
}

Object Oriented Programming

Rationale
C++ started life as “C with classes”. A class contains the data and the operations needed
on the data, and so the class defines the interface to the data. Classes permit the definition
of abstract data types (ADTs) in a similar way to the packages of ADA and the modules
of Modula-2. If the interface to the object is well designed then all the details will be within
the class, making it easier to identify code that is accessing the data incorrectly. This is part
of way to an object oriented programming language (OOPL).
For a programming language to fully support OOP it should also support inheritance and
polymorphism.
inheritance defining a class in terms of another; adding features to the existing
class
polymorphism applying the same operation to objects of different classes (but each
must be in the same family, derived from a common base class), the
behaviour will be different, even though the operation is the same
The classic example of inheritance and polymorphism is that of shapes in a graphics library.
Abase class, shape, stores the colour and location, and new classes are derived from the
base class inheriting the common features of all shapes. If any shape is asked to draw itself,
the behaviour will be different (circles and squares look different) even though they are
undergoing the same operation; this is polymorphism.
Much work is being done in the fields of object oriented analysis (OOA) and object
oriented design (OOD), but unfortunately this is beyond the scope of this course (and
possibly beyond the capabilities of the author!). However, the following rules of thumb for
object oriented programming in C++ from Stroustrup [1] will suffice:
– If you can think of “it” as a separate idea, make it a class .
– If you can think of “it” as a separate entity, make it an object of some class .
– If two classes have something significant in common, make that commonality a base
class.
– If a class is a container of objects, make it a template .
Deriving a class from another (inheritance) and including a class object within another are
often referred to as is-a and has-a relationships. In C++:
is-a publicly derived from another class
has-a implemented in terms of; either has a class object as a member or is privately
derived from another class
For example, a Ford Mondeo is-a car, and a car has-a engine (sorry about the grammar!).
Therefore, engine could be a member of car, and FordMondeo could be publicly derived
from car.

Tuesday 23 April 2013

References and const


const references can be initialised with non-const objects; the object referred to will not
be modifiable through the reference. Plain references cannot be initialised with a const
object, as that would allow a const object to be changed.
{
int i = 1;
const int j = 2;
const int& k = i; // OK
int& l = j; // illegal
k = 3; // illegal, even though reference is
// to i which is not const

Reference Parameters

References are also sometimes used as parameters to functions. In this case, the
initialisation of the reference takes place when the actual parameters are copied into the
formal parameters, e.g.
#include <iostream.h>
#include <iomanip.h>
void fred(int i, int& j)
{
i = 3; // assign to a local copy of the
// first argument
j = 4; // modify variable in caller's scope
}
int main()
{
int a = 1, b = 2;
cout << setw(2) << a << b; // prints "1 2"
fred(a,b);
cout << setw(2) << a << b; // prints "1 4"
return 0;
}
Needless to say, references are actually implemented using pointers!

Pointers vs. References

Pointers in C++ operate in precisely the same way as pointers in C. To declare a pointer, you
must state the type of the object that the pointer will point to, e.g. to declare a variable i as
being a pointer to int:
int *i;
The pointer is then used in one of two ways: by making the pointer point to some already
existing data; or by making the pointer point to some currently unused memory and then
storing data via the pointer. Examples of both methods are given below:
int i = 10;
int *ptr2int;
ptr2int = &i; // make ptr2int point to i
*ptr2int = 20; // change the value of i
ptr2int = new int; // ask for enough memory to
// store an integer
cin >> *ptr2int; // store data in this newly
// allocated memory
The * and & operators are more or less the opposites of each other. & is used to generate a
pointer, and * is used to follow a pointer to find what is at the other end. The opposite
nature of the two is shown by the fact that *&i is the same as i (given the declarations
above), but &*i is not legal as you are attempting to treat i as a pointer.
References are ways of introducing a new name for an existing object. References must be
initialised to refer to some existing object, and this cannot be changed! For example,
consider the code below:
int i = 1, j = 2;
int& k = i; // k refers to i, i.e. k
// is an alias for i
cout << setw(2) << i << j << k; // prints " 1 2 1"
k = j; // assigns 2 to i
cout << setw(2) << i << j << k; // prints " 2 2 2"
Note that the assignment to k did not make k refer to j, instead it modified the value of the
object that k referred to.

Monday 22 April 2013

Stream Library

The stream library is used for a common interface to input and output routines across
built-in types and your own types.
There are three streams available (cin, cout and cerr for standard input, standard
output and standard error streams respectively) and they are used in the following way:
#include <iostream.h>
int main()
{
int i = 45;
float f = 34.678;
cout << i; // print i
cout << f; // print f
cout << "\nEnter an integer: ";
// print a string
cin >> i; // read an integer
cout << i << f; // print i and f
return 0;
}
A range of manipulators exist to allow formatting of output. [ Remember that if all else
fails, printf is still there! ] Standard manipulators include:
oct use octal
dec use decimal
hex use hexadecimal
endl newline ('\n')
ends end of string ('\0')
flush flush stream
ws skip white space
setbase(int) use base specified
setfill(int) set fill character
setprecision(int) set number of digits printed
setw(int) set field width
Declarations for these manipulators are in iomanip.h. For example:
cout << setw(8) << 1 << setw(8) << setfill('#') << 2
<< endl;
cout << hex << 123 << ' ' << oct << 123 << endl;
prints:
1#######2
7b 173
The setw manipulator applies only to the next numeric or string value printed, hence the
need for two calls to setw above. The setfill manipulator modifies the state of the
stream, and will apply to all subsequent output on that stream.

void type

Functions can be declared as returning void, meaning they do not return a value.
void can also be used in the parameter list of a function. C++ differs from ANSI C on the
meaning of a function declaration with a null argument list, e.g. fred();, in ANSI C this
means that the function can take any number of arguments, in C++ it means that this
function does not take any parameters, i.e. C++'s fred(); is equivalent to ANSI C's
fred(void);. C++ accepts fred(void); for compatibility with ANSI C.
The generic pointer type is void * as it is in ANSI C, but again there is a difference. C++
will allow the assignment of any pointer to a void * variable or parameter, but the reverse
always requires a cast. In ANSI C, both assignments are permitted without a cast.
void fred();
// A function that takes no parameters and
// does not return a value.
void *harry();
// A function that takes no parameters and
// returns a pointer to void
void *jim(void *);
// A function that takes a void * parameter
// and returns a pointer to void
int main()
{
int i;
int *ptr2int;
float *ptr2float;
i = fred();
// illegal, fred does not return a value
fred(i);
// illegal, fred takes no parameters
ptr2int = harry();
// illegal, cast required for (void *) to (int *)
ptr2int = (int *)harry();
ptr2float = (float *)harry();
// OK, casts used
ptr2int = (int *)jim(ptr2float);
// OK, no cast needed for pointer to anything to
// void *
return 0;
}

new and delete Operators

new and delete are used for dynamic allocation of memory space. They have a major
advantage over malloc and free: constructors and destructors (see 2.2.4) for the objects
created or destroyed will be called.
There are two forms of new and delete, depending on whether a single object or an array
of objects is required:
pf = new float; for a single float
pf = new float [ num ]; for an array of floats
You should use the corresponding form of delete when destroying the objects created with
new, i.e.
delete pf; for a single object
delete [] pf; for an array of objects
This will ensure that the destructor is called for each object in the array.
new returns 0 (NULL) on failure.
The following example program illustrates the use of new and delete.
#include <stdio.h>
int main()
{
int num_chars;
char *name;
printf("how many characters in your string? ");
scanf("%d",&num_chars);
name = new char [num_chars + 1];
// allocate enough room for num_chars characters
// + 1 for the '\0'
if (name != NULL) {
// do something with name
delete [] name;
// remove name from the heap
}
return 0;
}
It is possible to set up a function to handle out of memory errors when using new; the
function set_new_handler (declared in new.h) is used to register the handler:
#include <iostream.h>
#include <new.h>
#include <stdlib.h>
#include <limits.h>
void newError()
{
fprintf(stderr,"new failed: out of memory\n");
exit(1);
}
int main()
{
char *ptr;
set_new_handler(newError);
ptr = new char [ULONG_MAX];
return 0;
}
This program sets up a handler that prints an error message and aborts the program if the
heap is full.

Inline Functions

Function definitions that are qualified with the inline keyword act like macros, that is, the
code is inserted at each invocation of the function. However, unlike preprocessor macros,
inline functions are much safer. Copies of the parameters are still taken and type
checking of the parameters is performed. Compilers are at liberty to ignore an inline
instruction, and many will do so for functions that are too long or complicated (each
compiler will have its own idea about what this means!). Also, if the address of the function
is ever used (perhaps assigned to a pointer), then the compiler will have to generate a normal
function (it is difficult to take the address of a function that does not exist!), though this may
be in addition to the insertion of the code wherever the function is called.

inline int strlen(char *str)
{
int i = 0;
while (str++ != '\0')
i++;
return i;
}

Sunday 21 April 2013

Functions with a Variable Number of Parameters

Functions can be written which can take any number of parameters. It is now possible to
write your own equivalent of printf1. To write functions with a variable number of
parameters it is necessary to use the macros, va_start and va_end, which are defined in
the header file, stdarg.h. Individual unnamed parameters can be obtained with the
va_arg macro, or the vprintf range of print routines can be used to print a list of
unnamed parameters.
The first of the following examples uses vfprintf to print the unnamed parameters, the
second extracts the unnamed parameters one by one using va_arg.
#include <stdio.h> // for fprintf
#include <stdlib.h> // for exit
#include <stdarg.h> // for variable num of args macros
void error(char *format ...)
{
va_list args;
va_start(args, format);
// make args point to first unnamed parameter
fprintf(stderr, "ERROR: ");
// print start of error message
vfprintf(stderr, format, args);
// print all unnamed arguments
fprintf(stderr, "\n");
// move onto newline
va_end(args);
// tidy up
exit(1);
// return to OS with exit status of 1
}
int main()
{
int i = -1;
error("invalid value %d encountered", i);
return 0;
}
But you shouldn't! Use operator<< instead
#include <stdio.h>
#include <stdarg.h>
void sum(char *message ...)
{
int total = 0;
va_list args;
int arg;
va_start(args, message);
while ((arg = va_arg(args, int)) != 0)
total += arg;
printf(message, total);
va_end(args);
}
int main()
{
sum("The total of 1+2+3+4 is %d\n", 1, 2, 3, 4, 0);
return 0;
}
We must make sure that the function knows which is the last actual parameter, otherwise
we may try to remove too many parameters from the stack. In the first example, we used the
vfprintf function, which is the printf function to use in conjunction with a variable
number of arguments. Like printf, the number of conversion characters must match the
number of extra parameters. In the second example a special trailing value is used to
indicate the last parameter.
In ANSI C the parameter list is written
func(named parameters, ...)
That is a comma precedes the ellipsis (...).

Name Mangling

As it is possible to overload functions (e.g. in the example above there are three print
functions) and as it is possible to use C++ with your existing linker, there must be some
mechanism to generate a unique name for each overloaded function. Each function's name,
number and type of parameters are combined to produce a unique name. This process is
called name mangling. Occasionally name mangling is not required, one example is linking
with C code. To turn the mangling off, a linkage specification can be used when declaring
the C routines that will be used:
extern "C" void fred(int);
fred(int) will now no longer be mangled. If the linkage specification is not used, and
fred is declared as void fred(int) an error such as Undefined: fred_Fi will be
produced when linking. fred_Fi is the mangled name of void fred(int)
When a group of C functions need to be declared, they can be placed in a linkage
specification block:
extern "C" {
int printf(char *fmt ...);
int scanf(char *fmt ...);
}

Default Values for Function Parameters

Functions can be called with fewer actual parameters than formal parameters. The
unspecified parameters are given default values.
void fred(int one, float two = 1.23, char three = 'c')
{}
The arguments with default values must be the last parameters in the parameter list.
In this example, fred can then be called with 1, 2 or 3 parameters, e.g.
fred(6,7.2,'z');
fred(6,7.2);
fred(6);
When declaring functions that take parameters with default values, subsequent declarations
cannot specify the default values already specified in earlier declarations, but they can add
new default values. When declaring a function before use, specify the default values in the
first declaration, e.g.
void fred(int one, float two = 1.23, char three = 'c');
int main()
{
fred(6, 7.2);
}
void fred(int one, float two, char three)
{}

Saturday 20 April 2013

Overloading of Functions and Operators

Several different functions can be given the same name. C++ will choose one of the
functions at compile time , given the type and number
of parameters in the function call.

The following print functions print an int, a string and an array of int:

#include <stdio.h>
#include <string.h>
void print(int i)
// print an integer
{
printf("%d\n", i);
}
void print(char *str)
// print a string
{
printf("%s\n", str);
}
void print(int a[], int elem)
// print an array of integers
{
for (int i = 0; i < elem; i++) printf("%d\n", a[i]);
}
int main()
{
int i = 6;
char *str = "hello";
int vals[] = { 1, 2, 3, 4 };
print(i); // call print(int)
print(str); // call print(char *)
print(vals,sizeof(vals)/sizeof(int));
// call print(int [], int)
return 0;
}
It should be noted that there are better ways of handling printing of user defined types in
C++.

Function Definitions and Declarations

C++ uses the same format of function definition as defined in the ANSI C standard. The
types of the parameters are specified within the round brackets following the function name.
C++ function declarations are used to provide checking of the return type and parameters
for a function that has not yet been defined. C++ declarations are the same as ANSI C
prototypes.
The advantage of using function declarations and the new style definitions is that C++ will
check that the type of the actual parameters are sensible —not necessarily the same. Either
the types must be the same, or all the applicable standard and user defined type conversions
are tried to see if a match can be found.
Some C++ implementations will not accept the old K&R declaration style at all.
double minimum(double a, double b)
// C++ and ANSI C function definition
{
return a < b ? a : b;
}
double maximum(a, b)
// old fashioned K&R format
double a, b;
{
return a > b ? a : b;
}
int main()
{
minimum(1, 2);
// correct usage minimum(1.0, 2.0);
// C++ will convert 1 to 1.0 and 2 to 2.0
minimum("hi", "there");
// non-sensical, C++ will complain
maximum(1, 2);
// call traditional C function
// no errors - wrong answer
maximum("hi", "there");
// again no complaints - strange results
}
Note that an ANSI C function declaration (where information about the parameters is
omitted) is interpreted by C++ as a declaration of a function that takes no parameters. For
example, the following declaration states that fred returns an int and can take any
number of parameters of any type in ANSI C, whilst in C++ it declares a function that
returns int and takes no parameters in C++.
int fred();

Explicit Type Conversion

Used to convert a value of one type to a value of another. Can be used as a replacement for
old style cast operators.

int main()
{
int i;
float f;
i = (float) f * 6;
// old style cast to float
// - does cast refer to (f * 6) or just to f?
i = float (f * 6);
// new style cast to float
// - clear what is being converted
return 0;
}

Type conversions of this form can only be used when the type has a simple single name, that
is

str = char * (ptr);

is not legal, but if a new type name is created with typedef, then the conversion will be
legal C++.

typedef char *string;
str = string(ptr);

constant in c

  • The keyword const(constant) can be used to freeze the value of an object. 
  • const objects will be initialized (as their value cannot otherwise be set!). 
  • const can also be used as a type qualifier on function parameters to prevent accidental modification of the parameter within the function.


void fred(const int x);
int main()
{
const int i = 15;
int j = 16;
i = 5; // illegal
fred(j);
return 0;
}
void fred(const int x)
{
x = 6; // illegal
}

When applying const to a pointer we can indicate that the pointer should be unmodified,
or that the data pointed to should remain constant. The alternatives are given below:

const char *ptr1 = "Hi"; // data pointed to is const
char *const ptr2 = "Hi"; // pointer is constant
const char *const ptr3 = "Hi"; // both pointer and data
// are constants
const objects can be used in array declarations, they cannot in C. The following is legal C++, but illegal C:
const int size = 10;
float vals[size];

Scope Qualifier

Scope Qualifier
#include <stdio.h>
int i = 0;
int main()
{
for (int i = 0; i < 10; i++)
printf("%5d%5d\n", i, ::i);
return 0;
}
The program produces the following output:
0 0
1 0
2 0
.
.
9 0
i refers to the local variable, ::i refers to the global variable.

Comment to End of Line

a += 6; // this is a comment
The new style comments are useful as it is possible to comment out code containing
comments, e.g.
// a += 6 // this is a comment
// b += 7;
With C style comments (which are still available in C++) problems occur:
/*
a += 6; /* this is a comment */
b += 7;
*/
The close comment symbol in the original comment ends the new comment, leaving code
uncommitted and a */ symbol which will cause the compiler distress.

Basic Input/Output in c++

Until now, the example programs of previous sections provided very little interaction with the user, if any at all.
Using the standard input and output library, we will be able to interact with the user by printing messages on the
screen and getting the user's input from the keyboard.
C++ uses a convenient abstraction called streams to perform input and output operations in sequential media such
as the screen or the keyboard. A stream is an object where a program can either insert or extract characters
to/from it. We do not really need to care about many specifications about the physical media associated with the
stream - we only need to know it will accept or provide characters sequentially.
The standard C++ library includes the header file iostream, where the standard input and output stream objects
are declared.
Standard Output (cout)
By default, the standard output of a program is the screen, and the C++ stream object defined to access it is cout.
cout is used in conjunction with the insertion operator, which is written as << (two "less than" signs).
cout << "Output sentence"; // prints Output sentence on screen
cout << 120; // prints number 120 on screen
cout << x; // prints the content of x on screen
The << operator inserts the data that follows it into the stream preceding it. In the examples above it inserted the
constant string Output sentence, the numerical constant 120 and variable x into the standard output stream cout.
Notice that the sentence in the first instruction is enclosed between double quotes (") because it is a constant
string of characters. Whenever we want to use constant strings of characters we must enclose them between
double quotes (") so that they can be clearly distinguished from variable names. For example, these two sentences
have very different results:
cout << "Hello"; // prints Hello
cout << Hello; // prints the content of Hello variable
The insertion operator (<<) may be used more than once in a single statement:
cout << "Hello, " << "I am " << "a C++ statement";
This last statement would print the message Hello, I am a C++ statement on the screen. The utility of repeating
the insertion operator (<<) is demonstrated when we want to print out a combination of variables and constants or
more than one variable:
cout << "Hello, I am " << age << " years old and my zipcode is " << zipcode;
If we assume the age variable to contain the value 24 and the zipcode variable to contain 90064 the output of the
previous statement would be:
Hello, I am 24 years old and my zipcode is 90064
It is important to notice that cout does not add a line break after its output unless we explicitly indicate it,
therefore, the following statements:
cout << "This is a sentence.";
cout << "This is another sentence.";
will be shown on the screen one following the other without any line break between them:
This is a sentence.This is another sentence.
even though we had written them in two different insertions into cout. In order to perform a line break on the
output we must explicitly insert a new-line character into cout. In C++ a new-line character can be specified as \n
(backslash, n):
cout << "First sentence.\n ";
cout << "Second sentence.\nThird sentence.";
This produces the following output:
First sentence.
Second sentence.
Third sentence.
Additionally, to add a new-line, you may also use the endl manipulator. For example:
cout << "First sentence." << endl;
cout << "Second sentence." << endl;
would print out:
First sentence.
Second sentence.
The endl manipulator produces a newline character, exactly as the insertion of '\n' does, but it also has an
additional behavior when it is used with buffered streams: the buffer is flushed. Anyway, cout will be an
unbuffered stream in most cases, so you can generally use both the \n escape character and the endl manipulator
in order to specify a new line without any difference in its behavior.
Standard Input (cin).
The standard input device is usually the keyboard. Handling the standard input in C++ is done by applying the
overloaded operator of extraction (>>) on the cin stream. The operator must be followed by the variable that will
store the data that is going to be extracted from the stream. For example:
int age;
cin >> age;
The first statement declares a variable of type int called age, and the second one waits for an input from cin (the
keyboard) in order to store it in this integer variable.
cin can only process the input from the keyboard once the RETURN key has been pressed. Therefore, even if you
request a single character, the extraction from cin will not process the input until the user presses RETURN after
the character has been introduced.
You must always consider the type of the variable that you are using as a container with cin extractions. If you
request an integer you will get an integer, if you request a character you will get a character and if you request a
string of characters you will get a string of characters.
// i/o example
#include <iostream>
using namespace std;
int main ()
{
int i;
cout << "Please enter an integer value: ";
cin >> i;
cout << "The value you entered is " << i;
cout << " and its double is " << i*2 << ".\n";
return 0;
}
Please enter an integer value: 702
The value you entered is 702 and its double is
1404.
The user of a program may be one of the factors that generate errors even in the simplest programs that use cin
(like the one we have just seen). Since if you request an integer value and the user introduces a name (which
generally is a string of characters), the result may cause your program to misoperate since it is not what we were
expecting from the user. So when you use the data input provided by cin extractions you will have to trust that
the user of your program will be cooperative and that he/she will not introduce his/her name or something similar
when an integer value is requested. A little ahead, when we see the stringstream class we will see a possible
solution for the errors that can be caused by this type of user input.
You can also use cin to request more than one datum input from the user:
cin >> a >> b;
is equivalent to:
cin >> a;
cin >> b;
In both cases the user must give two data, one for variable a and another one for variable b that may be separated
by any valid blank separator: a space, a tab character or a newline.
cin and strings
We can use cin to get strings with the extraction operator (>>) as we do with fundamental data type variables:
cin >> mystring;
However, as it has been said, cin extraction stops reading as soon as if finds any blank space character, so in this
case we will be able to get just one word for each extraction. This behavior may or may not be what we want; for
example if we want to get a sentence from the user, this extraction operation would not be useful.
In order to get entire lines, we can use the function getline, which is the more recommendable way to get user
input with cin:
// cin with strings
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string mystr;
cout << "What's your name? ";
getline (cin, mystr);
cout << "Hello " << mystr << ".\n";
cout << "What is your favorite team? ";
getline (cin, mystr);
cout << "I like " << mystr << " too!\n";
return 0;
}
What's your name? Juan SouliÃ‾¿½
Hello Juan SouliÃ‾¿½.
What is your favorite team? The Isotopes
I like The Isotopes too!
Notice how in both calls to getline we used the same string identifier (mystr). What the program does in the
second call is simply to replace the previous content by the new one that is introduced.
stringstream
The standard header file <sstream> defines a class called stringstream that allows a string-based object to be
treated as a stream. This way we can perform extraction or insertion operations from/to strings, which is especially
useful to convert strings to numerical values and vice versa. For example, if we want to extract an integer from a
string we can write:
string mystr ("1204");
int myint;
stringstream(mystr) >> myint;
This declares a string object with a value of "1204", and an int object. Then we use stringstream's constructor
to construct an object of this type from the string object. Because we can use stringstream objects as if they
were streams, we can extract an integer from it as we would have done on cin by applying the extractor operator
(>>) on it followed by a variable of type int.
After this piece of code, the variable myint will contain the numerical value 1204.
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price=0;
int quantity=0;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity <<
endl;
return 0;
}
Enter price: 22.25
Enter quantity: 7
Total price: 155.75
In this example, we acquire numeric values from the standard input indirectly. Instead of extracting numeric values
directly from the standard input, we get lines from the standard input (cin) into a string object (mystr), and then
we extract the integer values from this string into a variable of type int (quantity).
Using this method, instead of direct extractions of integer values, we have more control over what happens with
the input of numeric values from the user, since we are separating the process of obtaining input from the user (we
now simply ask for lines) with the interpretation of that input. Therefore, this method is usually preferred to get
numerical values from the user in all programs that are intensive in user input.

wellcome

#include<iostream.h>

#include<conio.h>

void main()

{

  clrscr();

  cout<<"WELLCOME";

}