3.3
Predefined Functions
3.3
Parameters, Arguments and Return Values
Many predefined functions need data to work with — this data is called parameters or arguments, supplied inside the parentheses of the function name. Some functions hand back a result after performing their task, known as the function's return-value; others simply carry out a task without returning anything. The header file relevant to a group of functions must always be included before those functions are used.
3.3.1
Console Functions for Character I/O
C++ also offers functions purely for single-character input/output, declared in the header file cstdio (stdio.h in Turbo C++).
getchar() returns the character typed at the keyboard, which can be stored in a variable:
char ch = getchar();
putchar() displays the character passed as its argument on the monitor. The argument may be a character constant, a variable, or even an integer treated as an ASCII value:
char ch = 'B'; //assigns 'B' to the variable ch
putchar(ch); //displays 'B' on the screen
putchar('c'); //displays 'c' on the screen
putchar(97); //displays 'a' on the screen
Program 3.1 uses both functions together to search for a character within a string and count its occurrences.
// Program 3.1: To search for a character in a string using console functions
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char str[20], ch;
int i, num=0;
puts("Enter a string:"); //To print '\n' after the string
gets(str);//To accept a string with white spaces
cout<<"\nEnter the character to be searched: ";
ch=getchar();//To input the character to be searched
/* A loop to search for the character and count its
occurrences in the string. Search will be
terminated when null character is found */
for(i=0; str[i]!='\0'; i++)
if (str[i]==ch)
num++;
cout<<"\nThe number of occurences of the character ";
putchar(ch);
cout<<" is : "<<num;
return 0;
}
Sample run — input string examination, searched character a → output: The number of occurences of the character a is : 2
3.3.2
Stream Functions for I/O Operations
C++ also provides stream functions, available through the header iostream, that let a stream of bytes flow between memory and objects such as the keyboard (cin) and the monitor (cout).
A. Input functions — get() and getline(), invoked as cin.get() and cin.getline() using the dot operator.
cin.get(ch) → reads one character into chcin.get(str, 10) → reads a string of up to 10 characters
char ch, str[10];
ch=cin.get(ch); //accepts a character and stores in ch
cin.get(ch); //equivalent to the above statement
cin.get(str,10); //accepts a string of maximum 10 characters
getline() accepts a string until Enter, a character count, or a specified delimiter character, whichever comes first — it can be called with two or three arguments:
char ch, str[10];
int len;
cin.getline(str,len); // With 2 arguments
cin.getline(str,len,ch); // With 3 arguments
With two arguments, up to len-1 characters are stored (a byte is reserved for the string terminator). With three arguments, an extra delimiting character can be supplied — whichever limit is hit first (character count or delimiter) stops the read.
B. Output functions — put() and write(), invoked with cout.
char ch='c';
cout.put(ch); //character 'c' is displayed
cout.put('B'); //character 'B' is printed
cout.put(65); //character 'A' is printed
write() displays a string, printing exactly as many characters as its second argument specifies (padding with spaces if the string is shorter):
char str[10]="hello";
cout.write(str,10); // displays "hello" followed by 5 spaces
Program 3.2 demonstrates all four stream functions together.
// Program 3.2: To illustrate the working of stream input/output functions
#include <iostream>
#include <cstring> //To use strlen() function
using namespace std;
int main()
{
char ch, str[20];
cout<<"Enter a character: ";
cin.get(ch); //To input a character to the variable ch
cout<<"Enter a string: ";
cin.getline(str,10,'.'); //To input the string
cout<<"Entered character is:\t";
cout.put(ch); //To display the character
cout.write("\nEntered string is:",20);
cout.write(str,strlen(str));
return 0;
}
With input p then hello world, the output shows only hello wo — the string was capped at 9 stored characters, and the leftover Enter key from the earlier get() is consumed as the first character. With input hello.world, only hello is stored, since getline() stops at the delimiting dot.
3.3.3
String Functions
String-manipulation functions live in the header cstring (string.h in Turbo C++).
strlen(string) returns the number of characters in a string:
char str[] = "Welcome";
int n;
n = strlen(str); // n becomes 7
n = strlen("Computer"); // n becomes 8; a string constant works too
strcpy(string1, string2) copies string2 into string1:
char s1[10], s2[10] = "Welcome";
strcpy(s1,s2); // s1 now holds "Welcome"
strcpy(str,"Welcome"); // second argument can be a string constant
Note that str = "Welcome"; is invalid — a character array can only be assigned a string literal directly at the point of declaration, e.g. char str[10] = "Welcome";
strcat(string1, string2) appends string2 onto the end of string1 — the first argument must be large enough to hold both strings combined:
char s1[20] = "Welcome", s2[10] = " to C++";
strcat(s1,s2);
cout << s1; // displays "Welcome to C++"
strcmp(string1, string2) compares two strings by alphabetical order and returns:
- 0 if the two strings are identical
- a negative value if
string1 is alphabetically lower than string2
- a positive value if
string1 is alphabetically higher than string2
char s1[]="Deepthi", s2[]="Divya";
int n;
n = strcmp(s1,s2); // n is negative, so "s1 < s2"
strcmpi(string1, string2) works exactly like strcmp() but ignores case, treating uppercase and lowercase letters as equal:
char s1[]="SANIL", s2[]="sanil";
int n = strcmpi(s1,s2); // n is 0 → "strings are same"
Program 3.3 compares two strings and, if different, concatenates and measures them.
// Program 3.3: To combine two strings if they are different and find its length
#include <iostream>
#include <cstring> // header file essential for string functions
using namespace std;
int main()
{
char s1[15], s2[15], s3[30];
cout<<"Enter two strings: ";
cin>>s1>>s2;
int n;
n=strcmp(s1,s2);
if (n==0)
cout<<"\nThe input strings are same";
else
{
cout<<"\nThe input strings are not same";
strcpy(s3,s1);//Copies the string in s1 into s3
strcat(s3,s2);//Appends the string in s2 to that in s3
cout<<"String after concatenation is: "<<s3;
cout<<"\nLength of the new string is: "
<<strlen(s3);
}
return 0;
}
Sample run — input india and kerala → not same; concatenation gives indiakerala, length 11.
3.3.4
Mathematical Functions
Common mathematical functions are declared in the header cmath (math.h in Turbo C++).
abs(int) returns the absolute value of an integer (positive or negative). For floating-point numbers, use fabs() instead, which returns a floating-point result.
int n = -25;
cout << abs(n); // displays 25
sqrt(double) returns the non-negative square root of its argument (which may be int, float or double):
int n = 25;
float b = sqrt(n);
cout << b; // displays 5
pow(double, double) returns xy for arguments x and y:
int x = 5, y = 4, z;
z = pow(x, y);
cout << z; // displays 625, since 5⁴ = 5×5×5×5
Program 3.4 uses sqrt() (via Heron's formula) and pow() to find the area of a triangle and a circle.
// Program 3.4: To find the area of a triangle and a circle using mathematical functions
#include <iostream>
#include <cmath> // header file essential for mathematical functions
using namespace std;
int main()
{
const float pi=22.0/7;
int a,b,c, radius;
float s, area1, area2;
cout<<"Enter the three sides of the triangle: ";
cin>>a>>b>>c;
s = (a+b+c)/2.0;
area1 = sqrt(s*(s-a)*(s-b)*(s-c));
cout<<"The Area of the Triangle is: "<<area1;
cout<<"\nEnter the radius of the circle: ";
cin>>radius;
area2 = pi*pow(radius,2);
cout<<"Area of the Circle is: "<<area2;
return 0;
}
Sample run — sides 5, 7, 9 → triangle area 17.4123; radius 2.5 → circle area 12.5714
3.3.5
Character Functions
Character-testing and conversion functions are declared in the header cctype (ctype.h in Turbo C++). Each testing function returns 1 if the condition holds and 0 otherwise.
| Function | Syntax | Checks whether the character is… |
| isupper() | int isupper(char c) | an uppercase letter |
| islower() | int islower(char c) | a lowercase letter |
| isalpha() | int isalpha(char c) | any alphabet (upper or lower) |
| isdigit() | int isdigit(char c) | a digit (0–9) |
| isalnum() | int isalnum(char c) | alphanumeric (a letter or a digit) |
toupper(char c) and tolower(char c) convert a character to its uppercase or lowercase form respectively, returning the character unchanged if it is already in that case (or is not a letter at all):
char c = toupper('a'); // c becomes 'A'
cout << (char)toupper('A'); // still 'A' — (char) cast avoids printing the ASCII code
char x = 'a';
char d = tolower(x); // d stays 'a'
Program 3.5 scans a whole line of text and separately counts uppercase letters, lowercase letters and digits, then prints the string entirely in uppercase and entirely in lowercase.
// Program 3.5: To count different types of characters in the given string
#include <iostream>
#include <cstdio>
#include <cctype>
using namespace std;
int main()
{
char text[80];
int Ucase=0, Lcase=0, Digit=0;
cout << "Enter a line of text: ";
gets(text);
for(int i=0; text[i]!='\0'; i++) // loop stops at the null character
if (isupper(text[i]))
Ucase++;
else if (islower(text[i]))
Lcase++;
else if (isdigit(text[i]))
Digit++;
cout << "\nNo. of uppercase letters = " << Ucase;
cout << "\nNo. of lowercase letters = " << Lcase;
cout << "\nNo. of digits = " << Digit;
cout << "\nThe string in uppercase form is\n";
i=0;
while (text[i]!='\0')
{
putchar(toupper(text[i]));
i++;
}
cout << "\nThe string in lowercase form is\n";
i=0;
do
{
putchar(tolower(text[i])); // using cout<< instead of putchar() here would print ASCII codes
i++;
}while(text[i]!='\0');
return 0;
}
Sample run — input The vehicle ID is KL01 AB101 → 7 uppercase letters, 11 lowercase letters, 5 digits.
3.4
User-defined Functions
3.4
Anatomy of a Function Definition
Every program we have written so far contains main() — itself a function. Its header, int main(), is called the function's header (or heading), and the statements inside the following pair of braces form its body. The general syntax of a function definition is:
data_type function_name(argument_list)
{
statements in the body;
}
data_type is any valid C++ type; function_name is a programmer-chosen identifier; and the optional argument_list is a comma-separated list of parameters, each preceded by its data type. Designing a function means answering a few questions: which data type should head the function, how many arguments it needs and of what type, what its body should do, and what (if anything) it should return.
3.4.1
Creating User-defined Functions
A minimal function that simply displays a message, with no arguments and no return value:
void saywelcome()
{
cout<<"Welcome to the world of functions";
}
Its return type is void and it takes no arguments. Consider four different ways of writing a function that finds the sum of two numbers — they differ in how they take input and whether they return a value.
Function 1
void sum1()
{
int a, b, s;
cout<<"Enter 2 numbers: ";
cin>>a>>b;
s=a+b;
cout<<"Sum="<<s;
}
Function 2
int sum2()
{
int a, b, s;
cout<<"Enter 2 numbers: ";
cin>>a>>b;
s=a+b;
return s;
}
Function 3
void sum3(int a, int b)
{
int s;
s=a+b;
cout<<"Sum="<<s;
}
Function 4
int sum4(int a, int b)
{
int s;
s=a+b;
return s;
}
The task performed is identical in each, but the number of parameters and the return type differ:
| Name | Arguments | Return value |
| sum1() | No arguments | Does not return any value |
| sum2() | No arguments | Returns an integer value |
| sum3() | Two integer arguments | Does not return any value |
| sum4() | Two integer arguments | Returns an integer value |
Table 3.1: Analysis of functions
A function with a return type other than void must return a value of that type using a return statement — which also immediately hands control back to the calling function, so any statements written after return within that function never execute. Functions of type void may omit return entirely, or use a bare return; with no value attached.
No function besides main() runs automatically — every sub-function, predefined or user-defined, executes only when it is called from main() or from another function. Here is a complete program calling all four:
int main()
{
int x, y, z=5, result;
cout << "\nCalling the first function\n";
sum1();
cout << "\nCalling the second function\n";
result = sum2();
cout << "Sum given by function 2 is " << result;
cout << "\nEnter values for x and y : ";
cin >> x >> y;
cout << "\nCalling the third function\n";
sum3(x,y);
cout << "\nCalling the fourth function\n";
result = sum4(z,12);
cout << "Sum given by function 4 is " << result;
cout << "\nEnd of main function";
return 0;
}
Since it returns exactly one usable result instead of printing internally, sum4()-style functions (parameters in, a value returned) are generally the most flexible and reusable design.
3.4.2
Prototype of Functions
A C++ program may define its functions in any order — main() first and the rest after, or the other way round.
Function before main()
int product(int a, int b)
{
int p;
p = a * b;
return p;
}
//Definition above main()
int main()
{
int ans, num1,num2;
cout<<"Enter 2 Numbers:";
cin>>num1>>num2;
ans = product(num1,num2);
cout<<"Product = "<<ans;
return 0;
}
Function after main()
int main()
{
int ans, num1,num2;
cout<<"Enter 2 Numbers:";
cin>>num1>>num2;
ans = product(num1,num2);
cout<<"Product = "<<ans;
return 0;
}
//Definition below main()
int product(int a, int b)
{
int p;
p = a * b;
return p;
}
The first version compiles cleanly. The second, however, fails with 'product' was not declared in this scope': while compiling main(), the compiler reaches the call to product() before it has seen the function at all, so it cannot verify the call is correct.
The fix is a function prototype — a declaration that tells the compiler the function's name, return type, and the number and type of its arguments (its accessibility too), without needing the full body. It takes the form of the function header alone, followed by a semicolon, placed before the call:
data_type function_name(argument_list);
Argument names are optional in a prototype — only the count and types must match. So the earlier error is resolved by adding this line before product() is called:
int product(int, int);
A function must be declared before it is used, exactly like a variable. If a function is fully defined before its first use, no separate prototype is required.
3.4.3
Arguments of Functions
Consider a function that computes simple interest:
float SimpleInterest(int P, int N, float R)
{
float amt;
amt = P * N * R / 100;
return amt;
}
cout << SimpleInterest(1000,3,2);//Function call 1
int x, y; float z=3.5, a;
cin >> x >> y;
a = SimpleInterest(x, y, z); //Function call 2
In the first call, the values 1000, 3 and 2 are passed to P, N and R; in the second, the values of x, y and z are passed instead. The variables x, y, z supplying the data at the calling place are called actual (original) arguments; the variables P, N, R that receive the data in the function header are the formal arguments. If a prototype uses variable names purely for documentation, those are called dummy arguments.
Program 3.8 uses a helper function fact() that returns a factorial, called twice within the same expression to compute nCr using the formula n!/(r!(n−r)!).
// Program 3.8: To find the value of nCr
#include<iostream>
using namespace std;
int fact(int); //Function prototype
int main()
{
int n,r, ncr;
cout<<"Enter the values of n and r : ";
cin>>n>>r;
ncr=fact(n)/(fact(r)*fact(n-r)); // actual arguments; function calls per the nCr formula
cout<<n<<"C"<<r<<" = "<<ncr;
return 0;
}
int fact(int N) //Function header; N is a formal argument
{
int f;
for(f=1; N>0; N--)
f=f*N;
return f; // factorial is returned
}
Sample run — n=5, r=2 → 5C2 = 10
3.4.4
Functions With Default Arguments
A function converting hours, minutes and seconds into total seconds can be written so that the minutes and seconds default to zero if the caller omits them:
int TimeSec(int H, int M=0, int S=0)
{
int sec = H * 3600 + M * 60 + S;
return sec;
}
This lets the function be invoked in several equally valid ways:
long s1 = TimeSec(2,10,40); // H=2, M=10, S=40 → 7840
long s2 = TimeSec(1,30); // H=1, M=30, S uses default 0 → 5400
long s3 = TimeSec(3); // H=3, M and S use default 0 → 10800
Default arguments must be placed from the right end of the argument list towards the left, since actual arguments are matched to formal ones from left to right during a call — a default value can only be "skipped" if every argument after it also has one.
3.4.5
Methods of Calling Functions
Suppose a teacher asks you to prepare invitation letters using a class name list. She could hand you a photocopy of the list — any marks you make don't affect her original — or she could hand you the original list itself, where any change you make sticks. C++ offers exactly this choice when passing arguments to a function.
a. Call by Value (Pass by value) method — a copy of the actual argument's value is passed to the formal argument. Changing the formal argument inside the function has no effect on the actual argument back at the calling place.
void change(int n)
{
n = n + 1;
cout << "n = " << n << '\n';
}
void main()
{
int x = 20;
change(x);
cout << "x = " << x;
}
Output: n = 21 then x = 20 — x is untouched because n has its own separate memory location.
| Before function call | After function call | After function execution |
| x = 20 (in main), n not yet allocated | x = 20, n = 20 (copy passed) | x = 20 (unchanged), n = 21 |
Table 3.2: Call by value procedure — formal argument n has its own memory, separate from x
b. Call by Reference (Pass by reference) method — the reference (memory address) of the actual argument is passed, so the formal argument shares the very same memory location as the actual argument. A reference variable — an alias for another variable, declared using & between the data type and the parameter name — is used as the formal parameter, and it is allocated no memory of its own.
void change(int & n)
{
n = n + 1;
cout << "n = " << n << '\n';
}
void main()
{
int x=20;
change(x);
cout << "x = " << x;
}
Output: n = 21 then x = 21 — because n and x refer to the very same storage location, changing one changes the other.
| Before function call | After function call | After function execution |
| x = 20 (in main), n not yet linked | x = 20, n shares x's memory | x = 21, n = 21 (same memory) |
Table 3.3: Call by reference procedure — n and x share one memory location
| Call by Value Method | Call by Reference Method |
| Ordinary variables are used as formal parameters. | Reference variables are used as formal parameters. |
| Actual parameters may be constants, variables or expressions. | Actual parameters will be variables only. |
| Changes made in the formal arguments do not reflect in actual arguments. | Changes made in the formal arguments do reflect in actual arguments. |
| Exclusive memory allocation is required for the formal arguments. | Memory of actual arguments is shared by formal arguments. |
Table 3.4: Call by value v/s Call by reference
Program 3.9 uses call by reference to exchange (“swap”) the values of two variables — something call by value could never achieve, since the caller's variables must actually change.
// Program 3.9: To swap the values of two variables
#include <iostream>
using namespace std;
void swap(int & x, int & y)
{
int t = x;
x = y;
y = t;
}
int main()
{
int m, n;
m = 10;
n = 20;
cout<<"Before swapping m= "<< m <<" and n= "<<n;
swap(m, n);
cout<<"\nAfter swapping m= "<< m <<" and n= "<<n;
return 0;
}
Output: Before swapping m= 10 and n= 20, then After swapping m= 20 and n= 10 — because x and y inside swap() share memory with m and n, so the exchange happens in main() too.