DSA Assignment
DSA Assignment
In this tutorial you will learn about Objects, Classes, Inheritance, Data Abstraction, Data Encapsulation, Polymorphism, Overloading, and Reusability. Before starting to learn C++ it is essential to have a basic knowledge of the concepts of Object oriented programming. Some of the important object oriented features are namely:
Objects Classes Inheritance Data Abstraction Data Encapsulation Polymorphism Overloading Reusability
In order to understand the basic concepts in C++, a programmer must have a good knowledge of the basic terminology in object-oriented programming. Below is a brief outline of the concepts of object-oriented programming languages :
Objects:
Object is the basic unit of object-oriented programming. Objects are identified by its unique name. An object represents a particular instance of a class. There can be more than one instance of a class. Each instance of a class can hold its own relevant data.
An Object is a collection of data members and associated member functions also known as methods.
Classes:
Classes are data types based on which objects are created. Objects with similar properties and methods are grouped together to form a Class. Thus a Class represents a set of individual objects. Characteristics of an object are represented in a class as Properties. The actions that can be performed by objects become functions of the class and are referred to as Methods. For example consider we have a Class of Cars under which Santro Xing, Alto and WaganR represents individual Objects. In this context each Car Object will have its own, Model, Year of Manufacture, Color, Top Speed, Engine Power etc., which form Properties of the Car class and the associated actions i.e., object functions like Start, Move, and Stop form the Methods of Car Class. No memory is allocated when a class is created. Memory is allocated only when an object is created, i.e., when an instance of a class is created.
Inheritance:
Inheritance is the process of forming a new class from an existing class or base class. The base class is also known as parent class or super class. The new class that is formed is called derived class. Derived class is also known as a child class or sub class. Inheritance helps in reducing the overall code size of the program, which is an important concept in object-oriented programming.
Data Abstraction:
Data Abstraction increases the power of programming language by creating user defined data types. Data Abstraction also represents the needed information in the program without presenting the details.
Data Encapsulation:
Data Encapsulation combines data and functions into a single unit called Class. When using Data Encapsulation, data is not accessed directly; it is only accessible through the functions present inside the class. Data Encapsulation enables the important concept of data hiding possible.
Polymorphism:
Polymorphism allows routines to use variables of different types at different times. An operator or function can be given different meanings or functions. Polymorphism refers to a single function or multi-functioning operator performing in different ways.
Overloading:
Overloading is one type of Polymorphism. It allows an object to have different meanings, depending on its context. When an existing operator or function begins to operate on new data type, or class, it is understood to be overloaded.
Reusability:
This term refers to the ability for multiple programmers to use the same written and debugged existing class of data. This is a time saving device and adds code efficiency to the language. Additionally, the programmer can incorporate new features to the existing class, further developing the application and allowing users to achieve increased performance. This time saving feature optimizes code, helps in gaining secured applications and facilitates easier maintenance on the application. The implementation of each of the above object-oriented programming features for C++ will be highlighted in later sections.
// Creation of Object // the getvalue method is being called // the displayvalue method is being called
Copyright exforsys.com
Output:
C++ Comments
A comment is text that the compiler ignores but that is useful for programmers. Comments are normally used to explain code for future reference. The compiler treats them as white space. You can use comments in testing to make certain lines of code inactive; A C++ comment is written in one of the following ways:
The /* (slash, asterisk) characters, followed by any sequence of characters (including new lines), followed by the */ characters. This syntax is the same as ANSI C. The // (two slashes) characters, followed by any sequence of characters. A new line not immediately preceded by a backslash terminates this form of comment. Therefore, it is commonly called a "single-line comment."
The comment characters (/*, */, and //) have no special meaning within a character constant, string literal, or comment. Comments using the first syntax, therefore, cannot be nested.
Types of Comments
C++ comments come in two flavors: the double-slash (//) comment, and the slash-star (/*) comment. The double-slash comment, which will be referred to as a C++-style comment, tells the compiler to ignore everything that follows this comment, until the end of the line. The slash-star comment mark tells the compiler to ignore everything that follows until it finds a star-slash (*/) comment mark. These marks will be referred to as C-style comments. Every /* must be matched with a closing */.
Constants
Constants are expressions with a fixed value. Literals Literals are the most obvious kind of constants. They are used to express particular values within the source code of a program. We have already used these previously to give concrete values to variables or to express messages we wanted our programs to print out, for example, when we wrote:
a = 5;
the 5 in this piece of code was a literal constant. Literal constants can be divided in Integer Numerals, Floating-Point Numerals, Characters, Strings and Boolean Values. Integer Numerals
They are numerical constants that identify integer decimal values. Notice that to express a numerical constant we do not have to write quotes (") nor any special character. There is no doubt that it is a constant: whenever we write 1776 in a program, we will be referring to the value 1776. In addition to decimal numbers (those that all of us are used to using every day), C++ allows the use of octal numbers (base 8) and hexadecimal numbers (base 16) as literal constants. If we want to express an octal number we have to precede it with a 0 (a zero character). And in order to express a hexadecimal number we have to precede it with the characters 0x (zero, x). For example, the following literal constants are all equivalent to each other:
1 75 2 0113 3 0x4b // decimal // octal // hexadecimal
All of these represent the same number: 75 (seventy-five) expressed as a base-10 numeral, octal numeral and hexadecimal numeral, respectively. Literal constants, like variables, are considered to have a specific data type. By default, integer literals are of type int. However, we can force them to either be unsigned by appending the u character to it, or long by appending l:
1 2 3 4 75 75u 75l 75ul // // // // int unsigned int long unsigned long
In both cases, the suffix can be specified using either upper or lowercase letters. Floating Point Numbers They express numbers with decimals and/or exponents. They can include either a decimal point, an e character (that expresses "by ten at the Xth height", where X is an integer value that follows the e character), or both a decimal point and an e character:
1 2 3 4 3.14159 6.02e23 1.6e-19 3.0 // // // // 3.14159 6.02 x 10^23 1.6 x 10^-19 3.0
These are four valid numbers with decimals expressed in C++. The first number is PI, the second one is the number of Avogadro, the third is the electric charge of an electron (an extremely small number) all of them approximated- and the last one is the number three expressed as a floating-point numeric literal. The default type for floating point literals is double. If you explicitly want to express a float or a long double numerical literal, you can use the f or l suffixes respectively:
1 3.14159L 2 6.02e23f // long double // float
Any of the letters that can be part of a floating-point numerical constant (e, f, l) can be written using either lower or uppercase letters without any difference in their meanings. Character and string literals There also exist non-numerical constants, like:
1 2 3 4
The first two expressions represent single character constants, and the following two represent string literals composed of several characters. Notice that to represent a single character we enclose it between single quotes (') and to express a string (which generally consists of more than one character) we enclose it between double quotes ("). When writing both single character and string literals, it is necessary to put the quotation marks surrounding them to distinguish them from possible variable identifiers or reserved keywords. Notice the difference between these two expressions:
1x 2 'x'
x alone would refer to a variable whose identifier is x, whereas 'x' (enclosed within single quotation
marks) would refer to the character constant 'x'. Character and string literals have certain peculiarities, like the escape codes. These are special characters that are difficult or impossible to express otherwise in the source code of a program, like newline (\n) or tab (\t). All of them are preceded by a backslash (\). Here you have a list of some of such escape codes:
\n Newline \r carriage return \t Tab \v vertical tab \b Backspace \f form feed (page feed) \a alert (beep) \' single quote (')
For example:
1 2 3 4 '\n' '\t' "Left \t Right" "one\ntwo\nthree"
Additionally, you can express any character by its numerical ASCII code by writing a backslash character (\) followed by the ASCII code expressed as an octal (base-8) or hexadecimal (base-16) number. In the first case (octal) the digits must immediately follow the backslash (for example \23 or \40), in the second case (hexadecimal), an x character must be written before the digits themselves (for example \x20 or \x4A). String literals can extend to more than a single line of code by putting a backslash sign ( \) at the end of each unfinished line.
1 "string expressed in \ 2 two lines"
You can also concatenate several string constants separating them by one or several blank spaces, tabulators, newline or any other valid blank character:
"this forms" "a single" "string" "of characters"
Finally, if we want the string literal to be explicitly made of wide characters (wchar_t type), instead of narrow characters (char type), we can precede the constant with the L prefix:
L"This is a wide character string"
Wide characters are used mainly to represent non-English or exotic character sets.
Boolean literals There are only two valid Boolean values: true and false. These can be expressed in C++ as values of type bool by using the Boolean literals true and false.
Constant Values
The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it.
// constant_values1.cpp int main() { const int i = 5; i = 10; // C3892 i++; // C2105 }
In C++, you can use the const keyword instead of the #define preprocessor directive to define constant values. Values defined with const are subject to type checking, and can be used in place of constant expressions. In C++, you can specify the size of an array with a const variable as follows:
// constant_values2.cpp // compile with: /c const int maxarray = 255; char store_char[maxarray];
In C, constant values default to external linkage, so they can appear only in source files. In C++, constant values default to internal linkage, which allows them to appear in header files. The const keyword can also be used in pointer declarations.
// constant_values3.cpp int main() { char *mybuf = 0, *yourbuf; char *const aptr = mybuf; *aptr = 'a'; // OK aptr = yourbuf; // C3892 }
A pointer to a variable declared as const can be assigned only to a pointer that is also declared as const.
// constant_values4.cpp #include <stdio.h> int main() { const char *mybuf = "test"; char *yourbuf = "test2"; printf_s("%s\n", mybuf); const char *bptr = mybuf; printf_s("%s\n", bptr); // *bptr = 'a'; } // Error // Pointer to constant data
Output
test test
You can use pointers to constant data as function parameters to prevent the function from modifying a parameter passed through a pointer. For objects that are declared as const, you can only call constant member functions. This ensures that the constant object is never modified.
birthday.getMonth(); // Okay birthday.setMonth( 4 ); // Error
You can call either constant or nonconstant member functions for a nonconstant object. You can also overload a member function using the const keyword; this allows a different version of the function to be called for constant and nonconstant objects. You cannot declare constructors or destructors with the const keyword.
C and C++ const Differences
When you declare a variable as const in a C source code file, you do so as:
const int i = 2;
But to get the same behavior in C++, you must declare your const variable as:
extern const int i = 2;
If you wish to declare an extern variable in a C++ source code file for use in a C source code file, use:
extern "C" const int x=10;
Defined constants (#define) You can define your own names for constants that you use very often without having to resort to memory-consuming variables, simply by using the #define preprocessor directive. Its format is:
#define identifier value
For example:
1 #define PI 3.14159 2 #define NEWLINE '\n'
This defines two new constants: PI and NEWLINE. Once they are defined, you can use them in the rest of the code as if they were any other regular constant, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // defined constants: calculate circumference #include <iostream> using namespace std; #define PI 3.14159 #define NEWLINE '\n' int main () { double r=5.0; double circle; circle = 2 * PI * r; cout << circle; cout << NEWLINE; return 0; } 31.4159 // radius
In fact the only thing that the compiler preprocessor does when it encounters #define directives is to literally replace any occurrence of their identifier (in the previous example, these were PI and
NEWLINE) by the code to which they have been defined (3.14159 and '\n' respectively). The #define directive is not a C++ statement but a directive for the preprocessor; therefore it assumes the entire line as the directive and does not require a semicolon (;) at its end. If you append a semicolon character (;) at the end, it will also be appended in all occurrences of the identifier within the body of the program that the preprocessor replaces. Declared constants (const) With the const prefix you can declare constants with a specific type in the same way as you would do with a variable:
1 const int pathwidth = 100; 2 const char tabulator = '\t';
Here, pathwidth and tabulator are two typed constants. They are treated just like regular variables except that their values cannot be modified after their definition.
Dynamic Initialization
Dynamic Initialization refers to initializing a variable at runtime. If you give a C++ statement as shown below, it refers to static initialization, because you are assigning a constant to the variable which can be resolved at compile time. Int x = 5; Whereas, the following statement is called dynamic initialization, because it cannot be resolved at compile time. In x = a * b; Initializing x requires the value of a and b. So it can be resolved only during run time. Dynamic initialization is mostly used in case of initializing C++ objects. Dynamic initialization of objects in c++ The dynamic initialization means that the initial values may be provided during run time. Even class objects can be initialized dynamically. I.e. with the values provided at run time. The following example explains it. A Program to find the factorial of an integer using constructor. #include<iostream.h> #include<conio.h> Class factorial { Private: Int n; Public: Factorial (int number) { N=number; } Void display () { Int fact=1;
If (n==0) Cout<<\n factorial=1; Else For (int i=1; i<=n; i++) { Fact=fact *I; } Cout<<\n factorial=<<fact; } }; Void main () { Int x; Clrscr (); Cout<<\n enter the number to find its factorial ; Cin>>x; Obj.dispay (); getch (); }
C++ References
C++ references allow you to create a second name for the a variable that you can use to read or modify the original data stored in that variable. While this may not sound appealing at first, what this means is that when you declare a reference and assign it a variable, it will allow you to treat the reference exactly as though it were the original variable for the purpose of accessing and modifying the value of the original variable--even if the second name (the reference) is located within a different scope. This means, for instance, that if you make your function arguments references, and you will effectively have a way to change the original data passed into the function. This is quite different from how C++ normally works, where you have arguments to a function copied into new variables. It also allows you to dramatically reduce the amount of copying that takes place behind the scenes, both with functions and in other areas of C++, like catch clauses.
Basic Syntax
Declaring a variable as a reference rather than a normal variable simply entails appending an ampersand to the type name, such as this "reference to an int"
int& foo = ....;
Did you notice the "...."? (Probably, right? After all, it's 25% of the example.) When a reference is created, you must tell it which variable it will become an alias for. After you create the reference, whenever you use the variable, you can just treat it as though it were a regular integer variable. But when you create it, you must initialize it with another variable, whose address it will keep around behind the scenes to allow you to use it to modify that variable. In a way, this is similar to having a pointer that always points to the same thing. One key difference is that references do not require dereferencing in the same way that pointers do; you just treat them as normal variables. A second difference is that when you create a reference to a variable, you need not do anything special to get the memory address. The compiler figures this out for you:
int x; int& foo = x; // foo is now a reference to x so this sets x to 56 foo = 56; std::cout << x <<std::endl;
void swap (int& first, int& second) { int temp = first; first = second; second = temp; }
Both arguments are passed "by reference"--the caller of the function need not even be aware of it:
int a = 2; int b = 3; swap( a, b );
After the swap, a will be 3 and b will be 2. The fact that references require no extra work can lead to confusion at times when variables magically change after being passed into a function. Bjarne Stroustrup suggests that for arguments that the function is expected to change, using a pointer instead of a reference helps make this clear--pointers require that the caller explicitly pass in the memory address.
While doing programming in any programming language, you need to use various variables to store various information. Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in memory. You may like to store information of various data type like character, wide character, integer, floating point, double floating point, boolean etc. Based on the data type of a variable, the operating system allocates memory and decides what can be stored in the reserved memory.
Several of the basic types can be modified using one or more of these type modifiers:
signed
The following table shows the variable type, how much memory it takes to store the value memory, and what is maximum and minimum vaue which can be stored in such type of variables.
Type char unsigned char signed char int unsigned int signed int short int Typical Bit Width 1byte 1byte 1byte 4bytes 4bytes 4bytes 2bytes Typical Range -127 to 127 or 0 to 255 0 to 255 -127 to 127 -2147483648 to 2147483647 0 to 4294967295 -2147483648 to 2147483647 -32768 to 32767 0 to 65,535 -32768 to 32767 -2,147,483,647 to 2,147,483,647 same as long int 0 to 4,294,967,295 +/- 3.4e +/- 38 (~7 digits)
unsigned short int Range signed short int long int signed long int unsigned long int float Range 4bytes 4bytes 4bytes 4bytes
+/- 1.7e +/- 308 (~15 digits) +/- 1.7e +/- 308 (~15 digits) 1 wide character
The sizes of variables might be different from those shown in the above table, depending on the compiler and the computer you are using. Following is the example which will produce correct size of various data type on your cmputer.
#include <iostream> using namespace std; int main() { cout << "Size cout << "Size cout << "Size cout << "Size cout << "Size cout << "Size cout << "Size return 0; }
of of of of of of of
char : " << sizeof(char) << endl; int : " << sizeof(int) << endl; short int : " << sizeof(short int) << endl; long int : " << sizeof(long int) << endl; float : " << sizeof(float) << endl; double : " << sizeof(double) << endl; wchar_t : " << sizeof(wchar_t) << endl;
This example uses endl which inserts a new-line character after every line and << operator is being used to pass multiple values out to the screen. We are also using sizeof() function to get size of various data types. When the above code is compiled and executed, it produces following result which can vary from machine to machine:
Size Size Size Size Size Size Size of of of of of of of char : 1 int : 4 short int : 2 long int : 4 float : 4 double : 8 wchar_t : 4
typedef Declarations:
You can create a new name for an existing type using typedef. Following is the simple syntax to define a new type using typedef:
For example, the following tells the compiler that feet is another name for int:
typedef int feet;
Now, the following declaration is perfectly legal and creates an integer variable called distance:
feet distance;
You learned how to put data into variables using assignment statement .Now you will learn how to put data into variables using c++ input statement.
when the computer gets the data from the keyboard , the user is said to be acting interactively. Putting data into variables using cin and the operator >>.The syntax of cin together with >> is
cin>>variable;
cin>>variable1>>variable2;
This is called an input statement. In c++ , >> is called the stream extraction operator.
then input is
cin>>feet>>inches;
Output statements
In c++ output on standard output device is use cout and the operator << . The syntax for output statement is
cout<< expression;
This is called an output statement. In C++ , << is called the stream insertion operator.
This example surely help you in uderstanding the input and output statements.
#include <iostream> using namespace std; int main () { double radius,area_circle; cout <<"enter radius of circle:"<<endl; cin>>radius; area_circle= 3.14 * radius * radius; cout<<"area_circle:="<<area_circle<<endl; // output statement return 0; } // output statement // input statement
The C++ standard libraries provide an extensive set of input/output capabilities which we will see in subsequent chapters. This chapter will discuss very basic and most common I/O operations required for C++ programming. C++ I/O occurs in streams, which are sequences of bytes. If bytes flow from a device like a keyboard, a disk drive, or a network connection etc. to main memory, this is called input operation and if bytes flow from main memory to a device like a display screen, a printer, a disk drive, or a network connection, etc, this is called output operation.
<iostream>
<iomanip>
<fstream>
When the above code is compiled and executed, it produces following result:
Value of str is : Hello C++
The C++ compiler also determines the data type of variable to be output and selects the appropriate stream insertion operator to display the value. The << operator is overloaded to output data items of built-in types integer, float, double, strings and pointer values. The insertion operator << may be used more than once in a single statement as shown above and endl is used to add a new-line at the end of the line.
When the above code is compiled and executed, it will prompt you to enter a name. You enter a value and then hit the enter to see the result something as follows:
Please enter your name: cplusplus Your name is: cplusplus
The C++ compiler also determines the data type of the entered value and selects the appropriate stream extraction operator to extract the value and store it in the given variables. The stream extraction operator >> may be used more than once in a single statement. To request more than one datum you can use the following:
cin >> name >> age;
operators in C++
Advertisements
An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations. C++ is rich in built-in operators and provides following type of operators:
Arithmetic Operators Relational Operators Logical Operators Bitwise Operators Assignment Operators Misc Operators
This chapter will examine the arithmetic, relational, and logical, bitwise, assignment and other operators one by one.
Arithmetic Operators:
There are following arithmetic operators supported by C++ language: Assume variable A holds 10 and variable B holds 20 then: Show Examples
Operator + * / Description Adds two operands Subtracts second operand from the first Multiply both operands Divide numerator by de-numerator A + B will give 30 A - B will give -10 A * B will give 200 B / A will give 2 Example
Modulus Operator and remainder of after an B % A will give 0 integer division Increment operator, increases integer value by one A++ will give 11
++
--
Relational Operators:
There are following relational operators supported by C++ language Assume variable A holds 10 and variable B holds 20 then: Show Examples
Operator == Description Example
Checks if the value of two operands is equal or (A == B) is not true. not, if yes then condition becomes true. Checks if the value of two operands is equal or not, if values are not equal then condition (A != B) is true. becomes true. Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.
!=
>
<
Checks if the value of left operand is less than the value of right operand, if yes then (A < B) is true. condition becomes true. Checks if the value of left operand is greater than or equal to the value of right operand, if (A >= B) is not true. yes then condition becomes true. Checks if the value of left operand is less than or equal to the value of right operand, if yes (A <= B) is true. then condition becomes true.
>=
<=
Logical Operators:
There are following logical operators supported by C++ language Assume variable A holds 1 and variable B holds 0 then: Show Examples
Operator Description Called Logical AND operator. If both the operands are non zero then condition becomes true. Example
&&
(A && B) is false.
||
Called Logical OR Operator. If any of the two operands is non zero then condition becomes (A || B) is true. true. Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition !(A && B) is true. is true then Logical NOT operator will make false.
Bitwise Operators:
Bitwise operator works on bits and perform bit by bit operation. The truth tables for &, |, and ^ are as follows:
pqp&qp|qp^q 000 010 111 100 0 1 1 1 0 1 0 1
Assume if A = 60; and B = 13; Now in binary format they will be as follows: A = 0011 1100
B = 0000 1101 ----------------A&B = 0000 1100 A|B = 0011 1101 A^B = 0011 0001 ~A = 1100 0011 The Bitwise operators supported by C++ language are listed in the following table. Assume variable A holds 60 and variable B holds 13 then: Show Examples
Operator & Description Example
Binary AND Operator copies a bit to the result (A & B) will give 12 which is 0000 1100 if it exists in both operands. Binary OR Operator copies a bit if it exists in either operand. Binary XOR Operator copies the bit if it is set in one operand but not both. Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. (A | B) will give 61 which is 0011 1101
<<
>>
Binary Right Shift Operator. The left operands value is moved right by the number of bits A >> 2 will give 15 which is 0000 1111 specified by the right operand.
Assignment Operators:
There are following assignment operators supported by C++ language: Show Examples
Operator =
Description
Example
Simple assignment operator, Assigns values C = A + B will assign value of A + B into C from right side operands to left side operand Add AND assignment operator, It adds right operand to the left operand and assign the result to left operand
+=
C += A is equivalent to C = C + A
-=
Subtract AND assignment operator, It subtracts right operand from the left operand C -= A is equivalent to C = C - A and assign the result to left operand Multiply AND assignment operator, It multiplies right operand with the left operand C *= A is equivalent to C = C * A and assign the result to left operand Divide AND assignment operator, It divides left operand with the right operand and assign C /= A is equivalent to C = C / A the result to left operand Modulus AND assignment operator, It takes modulus using two operands and assign the result to left operand Left shift AND assignment operator Right shift AND assignment operator Bitwise AND assignment operator
*=
/=
%=
C %= A is equivalent to C = C % A
bitwise exclusive OR and assignment operator C ^= 2 is same as C = C ^ 2 bitwise inclusive OR and assignment operator C |= 2 is same as C = C | 2
Misc Operators
There are few other operators supported by C++ Language.
Operator sizeof Description sizeof operator returns the size of a variable. For example sizeof(a),
where a is integer, will return 4. Condition ? X : Y Conditional operator. If Condition is true ? then it returns value X : otherwise value Y Comma operator causes a sequence of operations to be performed. The value of the entire comma expression is the value of the last expression of the comma-separated list. Member operators are used to reference individual members of classes, structures, and unions. Casting operators convert one data type to another. For example, int(2.2000) would return 2. Pointer operator & returns the address of an variable. For example &a; will give actual address of the variable. Pointer operator * is pointer to a variable. For example *var; will pointer to a variable var.
Cast
&
Unary
& sizeof Multiplicative Additive Shift Relational Equality Bitwise AND Bitwise XOR Bitwise OR Logical AND Logical OR Conditional */% +<< >> Left to right Left to right Left to right
< <= > >= Left to right == != & ^ | && || ?: Left to right Left to right Left to right Left to right Left to right Left to right Right to left
Assignment
Comma
Control Structures
A program is usually not limited to a linear sequence of instructions. During its process it may bifurcate, repeat code or take decisions. For that purpose, C++ provides control structures that serve to specify what has to be done by our program, when and under which circumstances. With the introduction of control structures we are going to have to introduce a new concept: the compound-statement or block. A block is a group of statements which are separated by semicolons (;) like all C++ statements, but grouped together in a block enclosed in braces: { }:
{ statement1; statement2; statement3; }
Most of the control structures that we will see in this section require a generic statement as part of its syntax. A statement can be either a simple statement (a simple instruction ending with a semicolon) or a compound statement (several instructions grouped in a block), like the one just described. In the case that we want the statement to be a simple statement, we do not need to enclose it in braces ({}). But in the case that we want the statement to be a compound statement it must be enclosed between braces ({}), forming a block. Conditional structure: if and else The if keyword is used to execute a statement or block only if a condition is fulfilled. Its form is:
if (condition) statement
Where condition is the expression that is being evaluated. If this condition is true, statement is executed. If it is false, statement is ignored (not executed) and the program continues right after this conditional structure. For example, the following code fragment prints x is 100 only if the value stored in the x variable is indeed 100:
1 if (x == 100) 2 cout << "x is 100";
If we want more than a single statement to be executed in case that the condition is true we can specify a block using braces { }:
1 if (x == 100) 2{ 3 cout << "x is "; 4 cout << x; 5}
We can additionally specify what we want to happen if the condition is not fulfilled by using the keyword else. Its form used in conjunction with if is:
if (condition) statement1 else statement2
For example:
1 if (x == 100) 2 cout << "x is 100"; 3 else 4 cout << "x is not 100";
prints on the screen x is 100 if indeed x has a value of 100, but if it has not and only if not- it prints out x is not 100. The if + else structures can be concatenated with the intention of verifying a range of values. The following example shows its use telling if the value currently stored in x is positive, negative or none of them (i.e. zero):
1 if (x > 0) 2 cout << "x 3 else if (x < 4 cout << "x 5 else 6 cout << "x
Remember that in case that we want more than a single statement to be executed, we must group them in a block by enclosing them in braces { }. Iteration structures (loops) Loops have as purpose to repeat a statement a certain number of times or
and its functionality is simply to repeat statement while the condition set in expression is true. For example, we are going to make a program to countdown using a whileloop:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // custom countdown using while #include <iostream> using namespace std; int main () { int n; cout << "Enter the starting number > "; cin >> n; while (n>0) { cout << n << ", "; --n; } cout << "FIRE!\n"; return 0; }
When the program starts the user is prompted to insert a starting number for the countdown. Then the while loop begins, if the value entered by the user fulfills the condition n>0 (that n is greater than zero) the block that follows the condition will be executed and repeated while the condition (n>0) remains being true. The whole process of the previous program can be interpreted according to the following script (beginning in main): 1. User assigns a value to n 2. The while condition is checked (n>0). At this point there are two possibilities: * condition is true: statement is executed (to step 3) * condition is false: ignore statement and continue after it (to step 5)
3. Execute statement:
cout << n << ", "; --n; (prints the value of n on the screen and decreases n by 1)
4. End of block. Return automatically to step 2 5. Continue the program right after the block: print FIRE! and end program.
When creating a while-loop, we must always consider that it has to end at some point, therefore we must provide within the block some method to force the condition to become false at some point, otherwise the loop will continue looping forever. In this case we have included --n; that decreases the value of the variable that is being evaluated in the condition (n) by one - this will eventually make the condition (n>0) to become false after a certain number of loop iterations: to be more specific, when n becomes 0, that is where our while-loop and our countdown end. Of course this is such a simple action for our computer that the whole countdown is performed instantly without any practical delay between numbers. The do-while loop Its format is:
do statement while (condition);
Its functionality is exactly the same as the while loop, except that condition in the do-while loop is evaluated after the execution of statement instead of before, granting at least one execution of statement even if condition is never fulfilled. For example, the following example program echoes any number you enter until you enter 0.
1 2 3 4 5 6 7 8 9 10 11 12 // number echoer Enter number end): 12345 You entered: Enter number int main () end): 160277 { You entered: unsigned long n; Enter number do { end): 0 cout << "Enter number (0 to You entered: end): "; cin >> n; #include <iostream> using namespace std; (0 to 12345 (0 to 160277 (0 to 0
13 cout << "You entered: " << 14 n << "\n"; 15 } while (n != 0); return 0; }
The do-while loop is usually used when the condition that has to determine the end of the loop is determined within the loop statement itself, like in the previous case, where the user input within the block is what is used to determine if the loop has to end. In fact if you never enter the value 0 in the previous example you can be prompted for more numbers forever. The for loop Its format is:
for (initialization; condition; increase) statement;
and its main function is to repeat statement while condition remains true, like the while loop. But in addition, the for loop provides specific locations to contain an initialization statement and an increase statement. So this loop is specially designed to perform a repetitive action with a counter which is initialized and increased on each iteration. It works in the following way: 1. initialization is executed. Generally it is an initial value setting for a counter variable. This is executed only once. 2. condition is checked. If it is true the loop continues, otherwise the loop ends and statement is skipped (not executed). 3. statement is executed. As usual, it can be either a single statement or a block enclosed in braces { }. 4. finally, whatever is specified in the increase field is executed and the loop gets back to step 2.
The initialization and increase fields are optional. They can remain empty, but in all cases the semicolon signs between them must be written. For example we could write: for (;n<10;) if we wanted to specify no initialization and no increase; or for (;n<10;n++) if we wanted to include an increase field but no initialization (maybe because the variable was already initialized before). Optionally, using the comma operator (,) we can specify more than one expression in any of the fields included in a for loop, like in initialization, for example. The comma operator (,) is an expression separator, it serves to separate more than one expression where only one is generally expected. For example, suppose that we wanted to initialize more than one variable in our loop:
1 for ( n=0, i=100 ; n!=i ; n++, i-- ) 2{ 3 // whatever here... 4}
This loop will execute for 50 times if neither n or i are modified within the loop:
n starts with a value of 0, and i with 100, the condition is n!=i (that n is not
equal to i). Because n is increased by one and i decreased by one, the loop's condition will become false after the 50th loop, when both n and i will be equal to 50. Jump statements. The break statement
Using break we can leave a loop even if the condition for its end is not fulfilled. It can be used to end an infinite loop, or to force it to end before its natural end. For example, we are going to stop the count down before its natural end (maybe because of an engine check failure?):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // break loop example #include <iostream> using namespace std; int main () { int n; for (n=10; n>0; n--) { cout << n << ", "; if (n==3) { cout << "countdown aborted!"; break; } } return 0; }
The continue statement The continue statement causes the program to skip the rest of the loop in the current iteration as if the end of the statement block had been reached, causing it to jump to the start of the following iteration. For example, we are going to skip the number 5 in our countdown:
1 2 3 4 5 6 7 8 9 10 11 12 13 // continue loop example #include <iostream> using namespace std; int main () { for (int n=10; n>0; n-- 10, 9, 8, 7, 6, 4, 3, 2, 1, ) { FIRE! if (n==5) continue; cout << n << ", "; } cout << "FIRE!\n"; return 0; }
goto allows to make an absolute jump to another point in the program. You
should use this feature with caution since its execution causes an unconditional jump ignoring any type of nesting limitations. The destination point is identified by a label, which is then used as an argument for the goto statement. A label is made of a valid identifier followed by a colon (:). Generally speaking, this instruction has no concrete use in structured or object oriented programming aside from those that low-level programming fans may find for it. For example, here is our countdown loop using goto:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // goto loop example #include <iostream> using namespace std; int main () { int n=10; 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, loop: FIRE! cout << n << ", "; n--; if (n>0) goto loop; cout << "FIRE!\n"; return 0; }
The purpose of exit is to terminate the current program with a specific exit code. Its prototype is:
void exit (int exitcode);
The exitcode is used by some operating systems and may be used by calling programs. By convention, an exit code of 0 means that the program finished normally and any other value means that some error or unexpected results happened. The selective structure: switch. The syntax of the switch statement is a bit peculiar. Its objective is to check
several possible constant values for an expression. Something similar to what we did at the beginning of this section with the concatenation of several if and else if instructions. Its form is the following:
switch (expression) { case constant1: group of statements 1; break; case constant2: group of statements 2; break; . . . default: default group of statements }
It works in the following way: switch evaluates expression and checks if it is equivalent to constant1, if it is, it executes group of statements 1 until it finds the break statement. When it finds this break statement the program jumps to the end of the switch selective structure. If expression was not equal to constant1 it will be checked against constant2. If it is equal to this, it will execute group of statements 2 until a break keyword is found, and then will jump to the end of the switch selective structure. Finally, if the value of expression did not match any of the previously specified constants (you can include as many case labels as values you want to check), the program will execute the statements included after the default: label, if it exists (since it is optional). Both of the following code fragments have the same behavior: switch example
switch (x) { case 1: cout << "x is 1"; break; case 2: cout << "x is 2"; break; default: cout << "value of x unknown";
if-else equivalent
if (x == 1) { cout << "x is 1"; } else if (x == 2) { cout << "x is 2"; } else { cout << "value of x unknown"; }
The switch statement is a bit peculiar within the C++ language because it uses labels instead of blocks. This forces us to put break statements after the group of statements that we want to be executed for a specific condition. Otherwise the remainder statements -including those corresponding to other labels- will also be executed until the end of the switch selective block or a break statement is reached. For example, if we did not include a break statement after the first group for case one, the program will not automatically jump to the end of the switch selective block and it would continue executing the rest of statements until it reaches either a break instruction or the end of the switch selective block. This makes it unnecessary to include braces { } surrounding the statements for each of the cases, and it can also be useful to execute the same block of instructions for different possible values for the expression being evaluated. For example:
1 switch (x) { 2 case 1: 3 case 2: 4 case 3: 5 cout << "x is 1, 2 or 3"; 6 break; 7 default: 8 cout << "x is not 1, 2 nor 3"; 9 }
Notice that switch can only be used to compare an expression against constants. Therefore we cannot put variables as labels (for example case n: where n is a variable) or ranges (case (1..3):) because they are not valid C++ constants. If you need to check ranges or values that are not constants, use a concatenation of if and else if statements.
Parameter Passing
Parameter passing methods are the ways in which parameters are transfered between functions when one function calls another. C++ provides two parameter passing methods--pass-byvalue and pass-by-reference .
Pass By Value
Consider a pair of C++ functions defined in Program . The function One calls the function Two. In general, every function call includes a (possibly empty) list of arguments. The arguments specified in a function call are called actual parameters . In this case, there is only one actual parameter--y.
Program: Example of Pass-By-Value Parameter Passing The method by which the parameter is passed to a function is determined by the function definition. In this case, the function Two is defined as accepting a single argument of type int called x. The arguments which appear in a function definition are called formal parameters . If the type of a formal parameter is not a reference (see Section ), then the parameter passing method is pass-by-value. The semantics of pass-by-value work like this: The effect of the formal parameter definition is to create a local variable of the specified type in the given function. E.g., the function Two has a
local variable of type int called x. When the function is called, the values (r-values) of the actual parameters are used to initialize the formal parameters before the body of the function is executed. Since the formal parameters give rise to local variables, if a new value is assigned to a formal parameter, that value has no effect on the actual parameters. Therefore, the output obtained produced by the function One defined in Program is:
2 1
Pass By Reference
Consider the pair of C++ functions defined in Program . The only difference between this code and the code given in Program is the definition of the formal parameter of the function Two: In this case, the parameter x is declared to be a reference to an int. In general, if the type of a formal parameter is a reference, then the parameter passing method is pass-by-reference .
Program: Example of Pass-By-Reference Parameter Passing A reference formal parameter is not a variable. When a function is called that has a reference formal parameter, the effect of the call is to associate the reference with the corresponding actual parameter. I.e., the reference becomes an alternative name for the corresponding actual parameter. Consequently, this means that the actual parameter passed by reference must be variable. A reference formal parameter can be used in the called function everywhere that a variable can be used. In particular, if the reference formal parameter is used where a r-value is required, it is
the r-value of actual parameter that is obtained. Similarly, if the reference parameter is used where an l-value is required, it is the l-value of actual parameter that is obtained. Therefore, the output obtained produced by the function One defined in Program is:
2 2
Template (C++)
From Wikipedia, the free encyclopedia Jump to: navigation, search This article has multiple issues. Please help improve it or discuss these issues on the talk page. This article needs additional citations for verification. (January 2009) This article includes a list of references, but its sources remain unclear because it has insufficient inline citations. (May 2009) This article may require cleanup to meet Wikipedia's quality standards. (May 2009)
Templates are a feature of the C++ programming language that allow functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one. This is effectively a Turing-complete language. Templates are of great utility to programmers in C++, especially when combined with multiple inheritance and operator overloading. The C++ Standard Library provides many useful functions within a framework of connected templates. Major inspirations for C++ templates were the parametrized modules provided by CLU and the generics provided by Ada.[1]
Contents
1 Technical overview o 1.1 Function templates o 1.2 Class templates o 1.3 Explicit template specialization 2 Advantages and disadvantages 3 Generic programming features in other languages 4 See also 5 References 6 External links
Technical overview
There are two kinds of templates: function templates and class templates.
Function templates
A function template behaves like a function except that the template can have arguments of many different types (see example). In other words, a function template represents a family of functions. The format for declaring function templates with type parameters is
template <class identifier> function_declaration; template <typename identifier> function_declaration;
Both expressions have exactly the same meaning and behave exactly the same way. The latter form was introduced to avoid confusion because a type parameter does not need to be a class, it may also be a basic type like int or double. For example, the C++ Standard Library contains the function template max(x, y) which returns either x or y, whichever is larger. max() could be defined like this, using the following template:
template <typename Type> Type max(Type a, Type b) { return a > b ? a : b; }
This single function definition works with different kinds of data types. A function template does not occupy space in memory. The actual definitions of a function template are generated at compile-time, when the compiler has determined what types the function will be called for. The function template does not save memory.
#include <iostream> int main() {
// This will std::cout << // This will std::cout << // This type std::cout << return 0; }
call max <int> (by argument deduction) max(3, 7) << std::endl; call max<double> (by argument deduction) max(3.0, 7.0) << std::endl; is ambiguous, so explicitly instantiate max<double> max<double>(3, 7.0) << std::endl;
In the first two cases, the template argument T is automatically deduced by the compiler to be int and double, respectively. In the third case deduction fails because the type of the parameters must in general match the template arguments exactly. This function template can be instantiated with any copy-constructible type for which the expression (y < x) is valid. For user-defined types, this implies that the less-than operator must be overloaded.
Class templates
A class template provides a specification for generating classes based on parameters. Class templates are commonly used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments.[2] The C++ Standard Library contains many class templates, in particular the containers adapted from the Standard Template Library, such as vector.
Explicit template specialization
When a function or class is instantiated from a template, a specialization of that template is created by the compiler for the set of arguments used (and the specialization is referred to as being a generated specialization). However, the programmer may decide to implement a special version of a function (or class) for a given set of template arguments which is called an explicit specialization. If a class template is specialized by a subset of its parameters it is called partial template specialization. If all of the parameters are specialized it is a full specialization. Function templates cannot be partially specialized. Explicit specialization is used when the behavior of a function or class for particular choices of the template parameters must deviate from the generic behavior: that is, from the code generated by the main template, or templates. For example:
template <> bool max(bool a, bool b) { return a||b; }
Some uses of templates, such as the maximum() function, were previously fulfilled by functionlike preprocessor macros. For example, the following is a C++ maximum() macro:
#define maximum(a,b) ((a) < (b) ? (b) : (a))
Both macros and templates are expanded at compile time. Macros are always expanded inline, while templates are only expanded inline when the compiler deems it appropriate. When expanded inline, macro functions and template functions have no extraneous runtime overhead. Template functions with many lines of code will incur runtime overhead when they are not expanded inline, but the reduction in code size may help the code to load from disk more quickly or fit within RAM caches. Templates are considered type-safe; that is, they require type-checking at compile time. Hence, the compiler can determine at compile time whether the type associated with a template definition can perform all of the functions required by that template definition. By design, templates can be utilized in very complex problem spaces, whereas macros are substantially more limited. There are fundamental drawbacks to the use of templates:
1. Historically, some compilers exhibited poor support for templates. So, the use of templates could decrease code portability. 2. Many compilers lack clear instructions when they detect a template definition error. This can increase the effort of developing templates, and has prompted the development of Concepts for possible inclusion in a future C++ standard. 3. Since the compiler generates additional code for each template type, indiscriminate use of templates can lead to code bloat, resulting in larger executables. 4. Because a template by its nature exposes its implementation, injudicious use in large systems can lead to longer build times. 5. It can be difficult to debug code that is developed using templates. Since the compiler replaces the templates, it becomes difficult for the debugger to locate the code at runtime. 6. Templates of Templates (nesting) are not supported by all compilers, or might have a max nesting level. 7. Templates are in the headers, which require a complete rebuild of all project pieces when changes are made. 8. No information hiding. All code is exposed in the header file. No one library can solely contain the code.
Additionally, the use of the "less than" and "greater than" signs as delimiters is problematic for tools (such as text editors) which analyze source code syntactically. It is difficult, or sometimes impossible[citation needed], for such tools to determine whether a use of these tokens is as comparison operators or template delimiters. For example, this line of code:
foo (a < b, c > d) ;
may be a function call with two parameters, each the result of a comparison expression. Alternatively, it could be a declaration of a constructor for class foo taking a parameter d whose type is the parameterized a < b, c >.