Module 2 C
Module 2 C
Module-2
Functions in C++
Introduction
Tokens
As we know, the smallest individual units in a program are known as tokens. C++
has the following tokens:
• Keywords
• Identifiers
• Constants
• Strings
• Operators
A C++ program is written using these tokens, white spaces, and the syntax of the
language. Most of the C++ tokens are basically similar to the C tokens with the exception
of some additions and minor modifications.
Keywords
The keywords implement specific C++ language features. They are explicitly reserved
identifiers and cannot be used as names for the program variables or other user-defined
program elements.
Below Table gives the complete set of C++ keywords. Many of them are common to both
C and C++.
The ANSI C keywords are shown in boldface. Additional keywords have been added to
the ANSI C keywords in order to enhance its features and make it an object-oriented
language. ANSI C++ standards committee has added some more keywords to make the
language more versatile. These are shown separately.
Identifiers refer to the names of variables, functions, arrays, classes, etc., created
by the programmer.
They are the fundamental requirement of any language.
Each language has its own rules for naming these identifiers.
The following rules are common to both C and C++:
Only alphabetic characters, digits and underscores are permitted.
The name cannot start with a digit.
Uppercase and lowercase letters are distinct.
A declared keyword cannot be used as a variable name.
A major difference between C and C++ is the limit on the length of a name.
While ANSI C recognizes only the first 32 characters in a name, ANSI C++ places
no limit on its length and, therefore, all the characters in a name are significant.
Care should be exercised while naming a variable which is being shared by more
than one file containing C and C++ programs.
Constants refer to fixed values that do not change during the execution of a
program.
Like C, C++ supports several kinds of literal constants. They include integers,
characters, floating point numbers and strings.
Literal constant do not have memory locations.
Examples:
123 // decimal integer
12.34 // floating point integer
037 // octal integer
0X2 // hexadecimal integer
“C++” // string constant
‘A’ // character constant
L‘ab’ // wide-character constant
Data types in C++ can be classified under various categories as shown in Fig. 3.1.
Both C and C++ compilers support all the built-in (also known as basic or fundamental)
data types. With the exception of void, the basic data types may have several modifiers
preceding them to serve the needs of various situations. The modifiers signed,
unsigned, long, and short may be applied to character and integer basic data types.
However, the modifier long may also be applied to double. Data type representation is
machine specific in C++.
Below Table lists all combinations of the basic data types and modifiers along with their
size and range for a 16-bit word machine.
Reference Variables
total is a float type variable that has already been declared; sum is the alternative name
declared to represent the variable total. Both the variables refer to the same data object
in the memory.
Now, the statements
cout << total;
and
cout << sum;
both print the value 100. The statement
total = total + 10;
will change the value of both total and sum to 110. Likewise, the assignment
sum = 0;
will change the value of both the variables to zero.
Operators in C++
C++ has a rich set of operators. All C operators are valid in C++ also.
In addition, C++ introduces some new operators.
We have already seen two such operators, namely, the insertion operator <<, and
the extraction operator >>.
Other new operators are;
:: Scope resolution operator
::* Pointer-to-member declarator
->* Pointer-to-member operator
.* Pointer-to-member operator
delete Memory release operator
endl Line feed operator
new Memory allocation operator
setw Field width operator
In addition, C++ also allows us to provide new definitions to some of the built-in
operators. That is, we can give several meanings to an operator, depending upon the
types of arguments used. This process is known as operator overloading.
Constant Expressions
Constant expressions consist of only constant values.
Examples:
15
20 + 5 / 2.0
‘x’
Integral Expressions
Integral expressions are those which produce integer results after implementing all the
automatic and explicit type conversions.
Examples:
m
m*n-5
m * ‘x’
5 + int(2.0)
where m and n are integer variables.
Float Expressions
Float expressions are those which, after all conversions, produce floating-point results.
Examples:
x+y
x * y / 10
5 + float(10)
10.75
where x and y are floating-point variables.
Pointer Expressions
Pointer expressions produce address values.
Examples:
&m
ptr
ptr + 1
“xyz”
where m is a variable and ptr is a pointer.
Relational Expressions
Relational expressions yield results of type bool which takes a value true or false.
Examples:
x <= y
a+b == c+d
m+n > 100
When arithmetic expressions are used on either side of a relational operator, they will
be evaluated first and then the results compared.
Relational expressions are also known as Boolean expressions.
Logical Expressions
Logical expressions combine two or more relational expressions and produces bool
type results.
Examples:
a>b && x==10
x==10 || y==5
Bitwise Expressions
Bitwise expressions are used to manipulate data at bit level. They are basically used
for testing or shifting bits.
Examples:
x << 3 // Shift three bit position to left
y >> 1 // Shift one bit position to right
Shift operators are often used for multiplication and division by powers of two.
Embedded Assignment
x = (y = 50) + 10;
(y = 50) is an assignment expression known as embedded assignment. Here, the value
50 is assigned to y and then the result 50+10 = 60 is assigned to x.
This statement is identical to
y = 50;
x = y + 10;
Compound Assignment
Like C, C++ supports a compound assignment operator which is a combination of the
assignment operator with a binary arithmetic operator.
For example, the simple assignment statement
x = x +10;
may be written as
x +=10;
The operator += is known as compound assignment operator
or short-hand assignment operator.
The general form of the compound assignment operator is
variable1 op= variable2;
where op is a binary arithmetic operator. This means that
variable1 = variable1 op variable2;
Function Prototyping
The argument-list contains the types and names of arguments that must be passed to
the function.
Example:
float volume(int x, float y, float z);
Note that each argument variable must be declared independently inside the
parentheses. That is, a combined declaration like
float volume(int x, float y, z); is illegal.
In a function declaration, the names of the arguments are dummy variables and
therefore , they are optional. That is, the form
float volume(int, float, float);
is acceptable at the place of declaration. At this stage, the compiler only checks for the
type of arguments when the function is called.
In general, we can either include or exclude the variable names in the argument list of
prototypes.
The variable names in the prototype just act as placeholders and, therefore, if names are
used, they don’t have to match the names used in the function call or function
definition.
In the function definition, names are required because the arguments must be
referenced inside the function.
Example:
float volume(int a, float b, float c)
{
float v = a*b*c;
.....
.....
}
The function volume() can be invoked in a program as follows:
float cube1 = volume(b1,w1,h1); // Function call
The variable b1, w1, and h1 are known as the actual parameters which specify
the dimensions of cube1.
Their types (which have been declared earlier) should match with the types
declared in the prototype. Remember, the calling statement should not include
type names in the argument list.
We can also declare a function with an empty argument list, as in the following example:
void display( );
In C++, this means that the function does not pass any parameters. It is identical to the
statement
void display(void);
void do_something(...);
Call By Reference
Now, if m and n are two integer variables, then the function call
swap(m, n);
will exchange the values of m and n using their aliases (reference variables)
a and b.
In traditional C, this is accomplished using pointers and indirection as follows:
Program:
#include <iostream.h>
#include<conio.h>
// function declaration
void swap(int &x, int &y);
void main ()
{
// local variable declaration:
int a = 100;
int b = 200;
clrscr();
cout << "Before swap, value of a :" << a << endl;
cout << "Before swap, value of b :" << b << endl;
/* calling a function to swap the values using variable reference.*/
swap(a, b);
cout << "\nAfter swap, value of a :" << a << endl;
cout << "After swap, value of b :" << b << endl;
getch();
}
Output:
Return by Reference
A function can also return a reference. Consider the following function:
Since the return type of max() is int &, the function returns reference to x or y (and not
the values). Then a function call such as max(a, b) will yield a reference to either a or b
depending on their values. This means that this function call can appear on the left-hand
side of an assignment statement.
That is, the statement.
max(a,b) = -1;
Inline Functions
One of the objectives of using functions in a program is to save some
memory space, which becomes appreciable when a function is likely to be
called many times.
However, every time a function is called, it takes a lot of extra time in
executing a series of instructions for tasks such as jumping to the function,
saving registers, pushing arguments into the stack, and returning to the
calling function.
When a function is small, a substantial percentage of execution time may
be spent in such overheads.
One solution to this problem is to use macro definitions, popularly known as
macros. Preprocessor macros are popular in C.
The major drawback with macros is that they are not really functions and
therefore, the usual error checking does not occur during compilation.
C++ has a different solution to this problem. To eliminate the cost of calls to
small functions, C++ proposes a new feature called inline function.
An inline function is a function that is expanded in line when it is invoked.
That is, the compiler replaces the function call with the corresponding
function code .
inline function-header
{
function body
}
Example:
Example:
Program:
#include <iostream.h>
#include<conio.h>
inline float mul(float x, float y)
{
return(x*y);
}
inline double div(double p, double q)
{
return(p/q);
}
int main()
{
float a = 12.345;
float b = 9.82;
cout << mul(a,b) << “\n”;
cout << div(a,b) << “\n”;
return 0;
}
Output:
121.228
1.25713
Default Arguments
C++ allows us to call a function without specifying all its arguments. In such
cases, the function assigns a default value to the parameter which does not have
a matching argument in the function call.
Default values are specified when the function is declared. The compiler looks at
the prototype to see how many arguments a function uses and alerts the
program for possible default values.
Here is an example of a prototype (i.e., function declaration) with default values:
#include<iostream.h>
Program:
#include<conio.h>
void main()
{
float amount;
float value(float p, int n, float r=0.15); //prototype
void printline(char ch='*',int len=10); //prototype
printline(); //use default values for arguments
amount = value (5000.00,5); //default for 3rd argument
cout<<“\n Final Value = ”<<amount<<“\n\n”;
amount = value (10000.00,5,0.30); //pass all arguments explicitly
cout<<“\n Final Value = ”<<amount<<“\n\n”;
printline(‘=’); //use default value for second argument
getch();
}
float value (float p, int n, float r)
{
int year = 1;
float sum = p;
while(year<=n)
{
sum = sum*(1+r);
year = year+1;
}
return(sum);
}
void printline(char ch, int len)
{
for(int i=1;i<=len;i++)
cout<<ch<<”\t”;
}
**********
Output: Final Value = 10056.8
Final Value = 37129.3
==========
Function Overloading
As stated earlier, overloading refers to the use of the same thing for
different purposes. C++ also permits overloading of functions.
This means that we can use the same function name to create
functions that perform a variety of different tasks. This is known as
function polymorphism in OOP.
Using the concept of function overloading; we can design a family of
functions with one function name but with different argument lists.
The function would perform different operations depending on the
argument list in the function call.
The correct function to be invoked is determined by checking the number
and type of the arguments but not on the function type.
For example, an overloaded add() function handles different types of data as
shown as follows:
// Declarations
int add(int a, int b); // prototype 1
int add(int a, int b, int c); // prototype 2
double add(double x, double y); // prototype 3
double add(int p, double q); // prototype 4
double add(double p, int q); // prototype 5
// Function calls
cout << add(5, 10); // uses prototype 1
cout << add(15, 10.0); // uses prototype 4
cout << add(12.5, 7.5); // uses prototype 3
cout << add(5, 10, 15); // uses prototype 2
cout << add(0.75, 5); // uses prototype 5
A function call first matches the prototype having the same number and
type of arguments and then calls the appropriate function for execution. A
best match must be unique.
to find a match.
3. When either of them fails, the compiler tries to use the built-in
conversions (the implicit assignment conversions) to the actual
arguments and then uses the function whose match is unique. If the
conversion is possible to have multiple matches, then the compiler will
generate an error message. Suppose we use the following two functions:
long square(long n)
double square(double x)
square(10)
will cause an error because int argument can be converted to either long
or double, thereby creating an ambiguous situation as to which version of
square() should be used.
4. If all of the steps fail, then the compiler will try the user-defined conversions
in combination with integral promotions and built-in conversions to find a
unique match. User-defined conversions are often used in handling class
objects.
Output:
Calling the area() function for computing the area of a square (side = 5) : 25
Calling the area() function for computing the area of a rectangle (length = 5, breadth = 10) : 50
Calling the area() function for computing the area of a circle (radius = 5.5) : 94.99