A reference variable is an alias, that is, another name for an already existing variable. Once a reference is initialized with a variable, either the variable name or the reference name may be used to refer to the variable.
References vs Pointers
References are often confused with pointers but three major differences between references and pointers are −
You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
Once a reference is initialized to an object, it cannot be changed to refer to another object. Pointers can be pointed to another object at any time.
A reference must be initialized when it is created. Pointers can be initialized at any time.
Creating References in C++
Think of a variable name as a label attached to the variable’s location in memory. You can then think of a reference as a second label attached to that memory location. Therefore, you can access the contents of the variable through either the original variable name or the reference. For example, suppose we have the following example −
int i =17;
We can declare reference variables for i as follows.
int& r = i;
Read the & in these declarations as reference. Thus, read the first declaration as “r is an integer reference initialized to i” and read the second declaration as “s is a double reference initialized to d.”. Following example makes use of references on int and double −
#include <iostream>usingnamespace std;intmain(){// declare simple variablesint i;double d;// declare reference variablesint& r = i;double& s = d;
i =5;
cout <<"Value of i : "<< i << endl;
cout <<"Value of i reference : "<< r << endl;
d =11.7;
cout <<"Value of d : "<< d << endl;
cout <<"Value of d reference : "<< s << endl;return0;}
When the above code is compiled together and executed, it produces the following result −
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
References are usually used for function argument lists and function return values. So following are two important subjects related to C++ references which should be clear to a C++ programmer −
Sr.No
Concept & Description
1
References as ParametersC++ supports passing references as function parameter more safely than parameters.
An enumeration, or enum in C++, is a user-defined data type formed by a set of named integral constants. However, enum types from tradition have the disadvantage of potential name clashes and the absence of type safety.
To solve this problem, C++ introduced the concept of enum class, which is also referred to as scoped enumerations.
Declaring an enum Class
This is the following syntax of declaring an enum class, which is done by using scoped enumeration (enum class).
enumclassEnumName{
Value1,
Value2,
Value3,// ... other enumerator values.};
Here, EnumName is the name of the enumeration class.
Value1, Value2.. is the named value(constants) inside the enum class.
Accessing Values from an enum Class
You can access the values of an enum class by using the Scope Resolution Operator (::) with the enum class name. Consider the following syntax:
EnumName::Value
Here, EnumName is the name of the enum class. Value is one of the enumerators defined in the class.
Example of Enum Class
Here is the following example for the enum class in C++.
#include <iostream>usingnamespace std;// Declare an enum class for days of the weekenumclassDay{
Monday,// 0
Tuesday,// 1
Wednesday,// 2
Thursday,// 3
Friday,// 4
Saturday,// 5
Sunday // 6};intmain(){
Day today = Day::Friday;if(today == Day::Friday){
cout <<"Today is Friday!"<< endl;}return0;}
Output
Today is Friday!
Explanation
First, we declared an enum class named Day with their values.
And then set the variable today to Day::Friday, and then we compared it to Day::Friday to print a message.
Underlying Type of an Enum Class
The enum class uses an integer as its default underlying type but many more underlying types are possible: unsigned int, char, uint8_t, int16_t, etc.
Default Underlying Type of enum class
When you declare the enum class without specifying any underlying type, then by default it is set to int. This means that each enumerator’s value will be stored as an int (4 bytes).
As we already see in the above following example.
Specifying a Custom Underlying Type for an enum class
Here, you can explicitly specify the underlying type of an enum class by adding a colon (:) after the enum class name. This will allow for control of the storage size and range of values.
Here, UnderlyingType could be any integral type (like unsigned int, char, uint8_t, etc.).
Example of Underlying Type of an Enum Class
Here is the following example using unsigned int as Underlying Type.
#include <iostream>usingnamespace std;enumclassStatus:unsigned int{
Ok =0,// 0
Error =1,// 1
Warning =2// 2};intmain(){
Status s = Status::Error;// Print the integer value of the enum
cout <<"The integer value of Error is: "<<static_cast<unsigned int>(s)<< endl;return0;}
In C++, an enumeration (or, enum) is a user-defined data type, where it consists of a set of named integral constants.
Creating (Declaring) Enumeration Type
To create an enumeration (enum), use the enum keyword followed by the name of the enumeration and a list of the named values further enclosed within curly braces.
Syntax
The following is the syntax to create an enumeration −
enumenumName{
Enumerator_value1,
Enumerator_value2,
Enumerator_value3,// So on};
Here,
enum is the keyword to declare enumeration type.
enumName is the name of the enumeration.
Enumerator_Value1, Enumerator_Value1, Enumerator_Value1, and so on are the integral constants.
Accessing Enumeration
You can access enumeration (enum) by declaring it with a variable name inside the int main() body and calling it as per requirement.
Syntax
Here’s a syntax for accessing or calling an enum:
enumenumName{
Enumerator_value1,
Enumerator_value2,
Enumerator_value3,// So on};// Creating variable and assigning value
enumName enam_var = value;
Here,
enumName is the declared variable name of an enum.
variableName is the variable name of enumerators (values defined within an enum).
Example of C++ Enumeration
In the following example, we are declaring an enumeration type, declaring an enum’s variable/object, and accessing enum constants. Consider the following example −
#include <iostream>usingnamespace std;// Define an enumeration called Day, for a days of weekenumDay{
Sunday,// 0
Monday,// 1
Tuesday,// 2
Wednesday,// 3
Thursday,// 4
Friday =45,// 45
Saturday // 46};intmain(){// Declaring a variable for a day
Day get1 = Wednesday;
cout<<get1<<endl;
cout<<Saturday<<endl;return0;}
Output
3
46
Explanation
In above code, by default explicitly, each day of the week value has been assigned a unique integer value ranging from 0 to 6 to all days of a week, However if we explicitly assign the value 45 to Friday, the enumeration property will cause the sequence to continue from that particular point, therefore the value for remaining Friday and Saturday will become 45 and 46 respectively completing series further on.
Types of C++ Enumeration
There are generally two type of enums in C++ −
1. Unscoped Enums
Unscoped enums are the traditional form of enumeration in C++. They are defined using the enum keyword with enumerator names declared within the enclosing scope. Since the enumerator names are added to the surrounding scope, which can lead to name collisions if not managed carefully, It can be used directly in the code, which is like a set of labels which represent specific numbers.
It automatically assigns integer values starting from zero, unless explicitly assigned, and implicitly convertible to integers.
Example
#include <iostream>usingnamespace std;enumRGB{
Red,// 0
Green,// 1
Blue // 2};voidprintColor(RGB color){switch(color){case Red: cout <<"Color is Red";break;case Green: cout <<"Color is Green";break;case Blue: cout <<"Color is Blue";break;}}intmain(){
RGB myColor = Red;// Here, no need to specify enum nameint value = myColor;// Implicit conversion to int
cout <<"Integer value: "<< value << endl;// Outputs: 0printColor(myColor);// Outputs: Color is Redreturn0;}
Output
Integer value: 0
Color is Red
2. Scoped Enums (enum class)
Scoped enums, introduced in C++11, are defined using the enum class. They provide better type safety and are more organized, where their enumerator names are scoped within the enum. Which means keeping their labels within a specific group, so you need to mention the group name when you use them. This helps avoid confusion if you have similar labels in different groups.
Enumerator names are scoped within the enum type, meaning you must use the enum name to access them. No implicit conversion to integers which helps enhance type safety.
Example
#include <iostream>usingnamespace std;enumclassColor{
Red,// Implicitly 0
Green,// Implicitly 1
Blue // Implicitly 2};// Usageintmain(){
Color myColor = Color::Red;// Must use enum name// int value = myColor; // Error: no implicit conversion// Explicit conversion to int if neededint value =static_cast<int>(myColor);// value = 0
cout <<"Integer value: "<< value << endl;// Outputs: 0return0;}
Output
Integer value: 0
Scoped Vs. Unscoped Enums
Features
Unscoped Enums
Scoped Enums (enum class)
Scope of Enumerators
Global scope
Scoped within the enum type
Name Conflicts
Possible
Avoided
Implicit Conversion
Yes
No
Type Safety
Less
More
Underlying Type
Default is int
Custom type can be specified
Comparing Enum Values
Enum values can be compared just like integer comparison. Consider the following example −
Example
#include <iostream>usingnamespace std;enumclassColor{
Red,
Green,
Blue
};intmain(){
Color myColor = Color::Green;if(myColor == Color::Green){
cout <<"The color is green!"<< endl;}else{
cout <<"The color is not green."<< endl;}return0;}
Output
The color is green!
Enum as Function Parameters
You can pass enums as parameters to functions. To pass enum as parameter in function, you need to specify the enum name along its instance.
Example
In the following example, we are passing enum as parameter −
#include <iostream>usingnamespace std;enumclassColor{
Red,
Green,
Blue
};// Function that takes an enum as a parametervoidprintColor(Color color){switch(color){case Color::Red:
cout <<"Red"<< endl;break;case Color::Green:
cout <<"Green"<< endl;break;case Color::Blue:
cout <<"Blue"<< endl;break;}}intmain(){
Color myColor = Color::Blue;printColor(myColor);return0;}
Output
Blue
Common Use Cases of Enum
The following are some of the common use cases of enum −
Improved Readability and Maintenance − Enums provide meaningful names for values which makes the code clearer and easier to understand and maintain.
Type Safety and Namespace Management − Enums in C++ restrict the assigned values, especially with scoped enums, which reduces errors and avoids name conflicts.
Organized Code Structure − Enums helps in enhancing organization by grouping related constants which improve code readability, enforce type safety, create cleaner function interfaces, and facilitate easier refactoring
Enhanced Functionality − Enums work smoothly with switch statements and allow explicit control over underlying types with assigned values.
Limitations of Enums
Despite of having benefits, it still have few limitations given below −
Type Safety Issues − Unscoped enums can cause name conflicts and allow implicit conversion to integers which will increase the risk of errors.
Limited Functionality − Enums have a fixed set of values and lack of member functions which cannot be extended at runtime.
Debugging Difficulties − Debuggers may display enum values as integers which makes it harder to interpret their meaning.
Normally, when we work with Numbers, we use primitive data types such as int, short, long, float and double, etc. The number data types, their possible values and number ranges have been explained while discussing C++ Data Types.
Defining Numbers in C++
You have already defined numbers in various examples given in previous chapters. Here is another consolidated example to define various types of numbers in C++ −
#include <iostream>usingnamespace std;intmain(){// number definition:short s;int i;long l;float f;double d;// number assignments;
s =10;
i =1000;
l =1000000;
f =230.47;
d =30949.374;// number printing;
cout <<"short s :"<< s << endl;
cout <<"int i :"<< i << endl;
cout <<"long l :"<< l << endl;
cout <<"float f :"<< f << endl;
cout <<"double d :"<< d << endl;return0;}
When the above code is compiled and executed, it produces the following result −
short s :10
int i :1000
long l :1000000
float f :230.47
double d :30949.4
Math Operations in C++
In addition to the various functions you can create, C++ also includes some useful functions you can use. These functions are available in standard C and C++ libraries and called built-in functions. These are functions that can be included in your program and then use.
C++ has a rich set of mathematical operations, which can be performed on various numbers. Following table lists down some useful built-in mathematical functions available in C++.
To utilize these functions you need to include the math header file <cmath>.
Sr.No
Function & Purpose
1
double cos(double);This function takes an angle (as a double) and returns the cosine.
2
double sin(double);This function takes an angle (as a double) and returns the sine.
3
double tan(double);This function takes an angle (as a double) and returns the tangent.
4
double log(double);This function takes a number and returns the natural log of that number.
5
double pow(double, double);The first is a number you wish to raise and the second is the power you wish to raise it t
6
double hypot(double, double);If you pass this function the length of two sides of a right triangle, it will return you the length of the hypotenuse.
7
double sqrt(double);You pass this function a number and it gives you the square root.
8
int abs(int);This function returns the absolute value of an integer that is passed to it.
9
double fabs(double);This function returns the absolute value of any decimal number passed to it.
10
double floor(double);Finds the integer which is less than or equal to the argument passed to it.
Following is a simple example to show few of the mathematical operations −
#include <iostream>#include <cmath>usingnamespace std;intmain(){// number definition:short s =10;int i =-1000;long l =100000;float f =230.47;double d =200.374;// mathematical operations;
cout <<"sin(d) :"<<sin(d)<< endl;
cout <<"abs(i) :"<<abs(i)<< endl;
cout <<"floor(d) :"<<floor(d)<< endl;
cout <<"sqrt(f) :"<<sqrt(f)<< endl;
cout <<"pow( d, 2) :"<<pow(d,2)<< endl;return0;}
When the above code is compiled and executed, it produces the following result −
There are many cases where you will wish to generate a random number. There are actually two functions you will need to know about random number generation. The first is rand(), this function will only return a pseudo random number. The way to fix this is to first call the srand() function.
Following is a simple example to generate few random numbers. This example makes use of time() function to get the number of seconds on your system time, to randomly seed the rand() function −
#include <iostream>#include <ctime>#include <cstdlib>usingnamespace std;intmain(){int i,j;// set the seedsrand((unsigned)time(NULL));/* generate 10 random numbers. */for( i =0; i <10; i++){// generate actual random number
j =rand();
cout <<" Random Number : "<< j << endl;}return0;}
When the above code is compiled and executed, it produces the following result −
Random Number : 1748144778
Random Number : 630873888
Random Number : 2134540646
Random Number : 219404170
Random Number : 902129458
Random Number : 920445370
Random Number : 1319072661
Random Number : 257938873
Random Number : 1256201101
Random Number : 580322989
The constexpr specifier was introduced in C++11. It calculates the value of a variable or the return value of a function at compile time. Calculating the values during compilation time improves the performance of the code. It helps in faster execution of programs; since the value is already known during compilation, the runtime overhead is reduced.
Here is a simple practical example that shows how you can calculate the sum of two numbers using constexpr specifier −
#include <iostream>usingnamespace std;constexprintsum(int a,int b){return a + b;}intmain(){constexprint x =sum(10,2);
cout <<"10 + 2 = "<< x << endl;return0;}
The output of the above code is as follows −
10 + 2 = 12
The above example was a simple implementation of constexpr specifier. In this chapter, we will discuss following topics in detail −
The constexpr is needed in C++ because of the following reasons −
Performance optimization − All the overhead of calculating mathematical expressions has now shifted from runtime to compile time. This helps in faster execution of program, as no computation is needed at runtime.
Better compile-time constants − Features such as array size, switch case labels, and template parameters require value during compilation which can be provided using constexpr specifier, but there is no guarantee with the const keyword.
Declaring Variables with constexpr
You can use a constexpr specifier to declare a variable. The rule for declaring a variable with constexpr is that it should be initialized with a constant expression.
The valid and invalid syntax for a constexpr variable is given below −
// -----Valid declarations-----(1)constexprint y =4;(2)constexprint z =7;constexprint x = z;// -----Invalid declarations-----(1)constexprint a;// constexpr variable must be initialized(2)constexprint b = x +2;// x is not a constant expression(3)int z =7;constexprint x = z;// z is not a constant expression
Example: Valid Declaration
Below is an example to demonstrate the use of constexpr variable −
#include <iostream>usingnamespace std;intmain(){constexprint z =7;constexprint x = z;
cout <<"value of z: "<< z << endl;
cout <<"value of x: "<< x << endl;return0;}
The output of the above code is given below −
value of z: 7
value of x: 7
Example: Invalid Declaration
Here is an example of an invalid declaration of constexpr variable −
#include <iostream>usingnamespace std;intmain(){int z =7;constexprint x = z;
cout <<"value of z: "<< z << endl;
cout <<"value of x: "<< x << endl;return0;}
The output of the above code is given below. Here, we can see the error as int z is not a constant.
main.cpp: In function 'int main()':
main.cpp:6:23: error: the value of 'z' is not usable in a constant expression
6 | constexpr int x = z;
| ^
main.cpp:5:9: note: 'int z' is not const
5 | int z = 7;
| ^
Functions with Constexpr Specifier
You can use constexpr specifier to define a function. Given below are the rules that you should follow while using constexpr to define a function:
The parameter and return type of function should be of literal type. For example: int, double, char, and bool are valid, whereas string and vector are invalid return types.
The function should have only one return statement till C++11. From C++14 onwards, it can have multiple return statements.
The function cannot have any side effects. For example: the function can not have input/output (cin/cout) operations, can not modify global and static variables.
A constexpr function can only call other constexpr functions, not simple functions.
Factorial Calculation with Constexpr
Here is an example to implement a function with constexpr specifier to calculate the factorial of 5 at compile-time −
#include <iostream>usingnamespace std;constexprlonglongfactorial(int n){return(n <=1)?1: n *factorial(n -1);}intmain(){// Computed at compile-timeconstexprlonglong fact =factorial(5);
cout <<"Factorial of 5 = "<< fact << endl;return0;}
The output of the above code is given below −
Factorial of 5 = 120
Fibonacci Calculation with Constexpr
Below is an example to find the fibonacci number. In this example, multiple return statements are used which was not valid before C++14.
#include <iostream>usingnamespace std;// Fibonacci using iterationconstexprlonglongfibonacci(int n){if(n <=1)return n;longlong prev =0, curr =1;for(int i =2; i <= n;++i){longlong next = prev + curr;
prev = curr;
curr = next;}return curr;}intmain(){// Computed at compile-timeconstexprlonglong fib =fibonacci(10);
cout <<"Fibonacci of 10 = "<< fib << endl;return0;}
The output of the above code is given below −
Fibonacci of 10 = 55
Constructors with Constexpr Specifier
The constexpr specifier can be used to create classes, objects, and declare a constructor. To declare a constructor, we must follow rules given below −
You can only use literal type parameters in a constructor.
Only other constexpr constructors and functions can be called.
Classes with constexpr constructors cannot have mutable data members.
A constructor with constexpr cannot have try/catch blocks or throw expressions.
The example below demonstrates how to use constexpr specifier with a constructor for converting a temperature given in celsius to fahrenheit −
#include <iostream>usingnamespace std;classTemperature{double celsius;public:// constexpr constructorconstexprTemperature(double c):celsius(c){}// convert to FahrenheitconstexprdoubletoFahrenheit()const{return(celsius *9.0/5.0)+32.0;}// get CelsiusconstexprdoublegetCelsius()const{return celsius;}};intmain(){// Compile-time constant objectconstexpr Temperature t1(25.0);
cout <<"Compile time temperature conversions:"<< endl;// computed at compile-timeconstexprdouble f1 = t1.toFahrenheit();
cout << t1.getCelsius()<<"°C = "<< f1 <<"°F"<< endl;// Runtime objectdouble input =100.0;
Temperature t2(input);// runtime
cout <<"\nRuntime temperature conversions:"<< endl;
cout << t2.getCelsius()<<"°C = "<< t2.toFahrenheit()<<"°F"<< endl;return0;}
The output of the above code is as follows −
Compile time temperature conversions:
25°C = 77°F
Runtime temperature conversions:
100°C = 212°F
Use Cases of Constexpr Specifier
There are multiple practical use cases of constexpr specifier in various scenarios. Here are some of the uses mentioned below −
Array Sizes at Compile-time
In this example, constexpr provides the array size to print the numbers at compile-time using bufferSize() function.
#include <iostream>usingnamespace std;constexprintbufferSize(){return10;}intmain(){// valid as the buffer size is // known at compile-timeint arr[bufferSize()];for(int i =0; i <bufferSize(); i++){
arr[i]= i;}
cout <<"Array elements: ";for(int i =0; i <bufferSize(); i++){
cout << arr[i]<<" ";}
cout << endl;return0;}
The output of the above code is given below −
Array elements: 0 1 2 3 4 5 6 7 8 9
Mathematical Computations
The following example calculates the 10th power of 2. The power is calculated at compile-time rather than run-time. This reduces the run-time overhead of the program.
#include <iostream>usingnamespace std;constexprlonglongpower(int base,int exp){longlong result =1;for(int i =0; i < exp;++i){
result *= base;}return result;}intmain(){constexprlonglong n =power(2,10);// Calculated at compile time
cout <<"2^10 = "<< n << endl;return0;}
The output of the above code is given below −
2^10 = 1024
Using Constexpr in Switch Case Labels
Here is an example to pre-define the label of switch case using constexpr specifier. If we remove constexpr, it will give an error.
#include <iostream>usingnamespace std;constexprintchoice(){return3;// value known at compile-time}intmain(){switch(3){casechoice():
cout <<"Matched case 3"<< endl;break;default:
cout <<"Default case"<< endl;}return0;}
The output of the above code is given below −
Matched case 3
Difference between Const and Constexpr
The following table lists the differences between const keyword and constexpr specifier −
const
constexpr
Values can be evaluated at compile-time or run-time.
Values must be evaluated at compile time.
The variables can be initialized with compile time or run time values.
We initialize variables with compile-time constant expressions only.
There may be runtime overhead.
There is zero runtime overhead as evaluation occurs at compile-time.
Limitations of Constexpr Specifier
There are various advantages of using a constexpr specifier such as reducing the runtime overhead and increasing the performance but there are some limitations too that are mentioned below:
The input and output operations (cin/cout) cannot be used in the functions declared with constexpr specifier.
Function parameters or return type can only be of literal type.
Conclusion
In this chapter, we explained the use of constexpr specifier in detail. It calculates the value at compile-time, reducing the run-time overhead. We discussed the rules to use constexpr with variables, functions, and constructors with code examples. It offers the advantage of increasing the performance, but it also has some limitations that we highlighted at the end of the chapter.
A storage class defines the scope (visibility) and life-time of variables and/or functions within a C++ Program. These specifiers precede the type that they modify. There are following storage classes, which can be used in a C++ Program
auto
register
static
extern
mutable
The auto Storage Class
The auto storage class is the default storage class for all local variables.
Example
Below is the example of auto storage class −
{int mount;autoint month;}
The example above defines two variables with the same storage class, auto can only be used within functions, i.e., local variables.
The register Storage Class
The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can’t have the unary ‘&’ operator applied to it (as it does not have a memory location).
Example
Below is the example of register storage class −
{registerint miles;}
The register should only be used for variables that require quick access such as counters. It should also be noted that defining ‘register’ does not mean that the variable will be stored in a register. It means that it MIGHT be stored in a register depending on hardware and implementation restrictions.
The static Storage Class
The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.
The static modifier may also be applied to global variables. When this is done, it causes that variable’s scope to be restricted to the file in which it is declared.
In C++, when static is used on a class data member, it causes only one copy of that member to be shared by all objects of its class.
Example
Below is the example of static storage class −
#include <iostream>// Function declarationvoidfunc(void);staticint count =10;/* Global variable */main(){while(count--){func();}return0;}// Function definitionvoidfunc(void){staticint i =5;// local static variable
i++;
std::cout <<"i is "<< i ;
std::cout <<" and count is "<< count << std::endl;}
When the above code is compiled and executed, it produces the following result −
i is 6 and count is 9
i is 7 and count is 8
i is 8 and count is 7
i is 9 and count is 6
i is 10 and count is 5
i is 11 and count is 4
i is 12 and count is 3
i is 13 and count is 2
i is 14 and count is 1
i is 15 and count is 0
The extern Storage Class
The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. When you use ‘extern’ the variable cannot be initialized as all it does is point the variable name at a storage location that has been previously defined.
When you have multiple files and you define a global variable or function, which will be used in other files also, then extern will be used in another file to give reference of defined variable or function. Just for understanding extern is used to declare a global variable or function in another file.
The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions as explained below.
#include <iostream>externint count;voidwrite_extern(void){
std::cout <<"Count is "<< count << std::endl;}
Here, extern keyword is being used to declare count in another file. Now compile these two files as follows −
$g++ main.cpp support.cpp -o write
This will produce write executable program, try to execute write and check the result as follows −
$./write
5
The mutable Storage Class
The mutable specifier applies only to class objects, which are discussed later in this tutorial. It allows a member of an object to override const member function. That is, a mutable member can be modified by a const member function.
C++ allows the char, int, and double data types to have modifiers preceding them. A modifier is used to alter the meaning of the base type so that it more precisely fits the needs of various situations.
The data type modifiers are listed here −
signed
unsigned
long
short
The modifiers signed, unsigned, long, and short can be applied to integer base types. In addition, signed and unsigned can be applied to char, and long can be applied to double.
The modifiers signed and unsigned can also be used as prefix to long or short modifiers. For example, unsigned long int.
C++ allows a shorthand notation for declaring unsigned, short, or long integers. You can simply use the word unsigned, short, or long, without int. It automatically implies int. For example, the following two statements both declare unsigned integer variables.
unsigned x;unsignedint y;
To understand the difference between the way signed and unsigned integer modifiers are interpreted by C++, you should run the following short program −
#include <iostream>usingnamespace std;/* This program shows the difference between
* signed and unsigned integers.
*/intmain(){shortint i;// a signed short integershortunsignedint j;// an unsigned short integer
j =50000;
i = j;
cout << i <<" "<< j;return0;}
When this program is run, following is the output −
-15536 50000
The above result is because the bit pattern that represents 50,000 as a short unsigned integer is interpreted as -15,536 by a short.
Type Qualifiers in C++
The type qualifiers provide additional information about the variables they precede.
Sr.No
Qualifier & Meaning
1
constObjects of type const cannot be changed by your program during execution.
2
volatileThe modifier volatile tells the compiler that a variable’s value may be changed in ways not explicitly specified by the program.
3
restrictA pointer qualified by restrict is initially the only means by which the object it points to can be accessed. Only C99 adds a new type qualifier called restrict.
Manipulators in C++ are special functions or objects that are used with insertion (<<) and extraction (>>) operators (cin/cout) to control the input and output streams. You can change the format to display the output or how to read an input. The manipulators are declared in <iostream> and <iomanip> headers.
Types of Manipulators in C++
The manipulators can be classified into following categories −
The output stream manipulators are used to control display properties such as field width, fill characters, and numeric display options. The below lists all the output stream manipulators −
Manipulators
Definition
Syntax
endl
It inserts a newline and flushes the output buffer.
cout << “Tutorials” << endl;
setw(n)
It sets the field width for the next output operation.
cout << setw(5) << 57;
setfill()
It sets the fill character.
cout << setfill(‘*’) << setw(5) << 42;
showpoint
It displays decimal point for floating point numbers.
cout << showpoint << 7.0;
noshowpoint
It hides the decimal point.
cout << noshowpoint << 7.0;
showpos
It is used for displaying ‘+’ sign for positive numbers.
cout << showpos << 57;
noshowpos
It hides ‘+’ sign for positive numbers.
cout << noshowpos << 57;
flush
It flushes the output stream without newline.
cout << “Data” << flush;
ends
It is used for inserting a null character and then flushes.
cout << “String” << ends;
Here is an example illustrating the use of some of the output stream manipulators in C++ −
#include <iostream>#include <iomanip>usingnamespace std;intmain(){
cout <<"C++ Output Manipulators Examples:"<< endl;
cout <<"\nThis is the first line"<< endl;
cout <<"This is the second line using endl"<< endl;
cout << endl;
cout <<setw(5)<<57<<" (Field width 5) using setw()"<< endl;
cout <<setw(10)<<40<<" (Field width 10) using setw()"<< endl;
cout <<"\n";
cout <<setfill('*')<<setw(8)<<42<<" Filled with * using setfill()"<< endl;
cout <<setfill('-')<<setw(8)<<123<<" Filled with - using setfill()"<< endl;
cout <<setfill(' ');// Reset to space
cout <<"\nDecimal Point Display:"<< endl;
cout <<"With showpoint: "<< showpoint <<7.0<<", "<<3.0<< endl;
cout <<"With noshowpoint: "<< noshowpoint <<7.0<<", "<<3.0<< endl;return0;}
The output of the above code is as follows −
C++ Output Manipulators Examples:
This is the first line
This is the second line using endl
57 (Field width 5) using setw()
40 (Field width 10) using setw()
******42 Filled with * using setfill()
-----123 Filled with - using setfill()
Decimal Point Display:
With showpoint: 7.00000, 3.00000
With noshowpoint: 7, 3
Input Stream Manipulators
The input manipulators control whitespaces and also handles input stream during read operations.
Manipulators
Definition
Syntax
ws
It removes the whitespace character.
cin >> ws >> str;
noskipws
It avoids skipping whitespaces.
cin >> noskipws >> ch;
The following example shows the application of input stream manipulators ws and noskipws −
#include <iostream>#include <sstream> usingnamespace std;intmain(){
string text =" A B";
cout <<"Original Text: "<< text << endl;
istringstream iss(text);char ch;
iss >> ws >> ch;
cout <<"Using ws: '"<< ch <<"'"<< endl;// Reset stream
iss.clear();
iss.seekg(0);
iss >> noskipws >> ch;
cout <<"Using noskipws: '"<< ch <<"'"<< endl;return0;}
The output of the above code is as follows. Here ws skips all the white spaces while noskipws prints the white space without skipping it.
Original Text: A B
Using ws: 'A'
Using noskipws: ' '
Alignment Manipulators
Alignment manipulators are used to control alignment of output within its field width.
Manipulators
Definition
Syntax
left
It left aligns the output within field width.
cout << left << setw(10) << “Hi”;
right
It right aligns the output within field width.
cout << right << setw(10) << “Hi”;
internal
It is used to insert padding between sign and value.
cout << internal << setw(6) << -57;
In this example, we have used left and right manipulators that aligns the number to left and right respectively while internal sets the alignment between ‘-‘ and number.
#include <iostream>#include <iomanip>usingnamespace std;intmain(){int num =123;int negNum =-123;
cout <<"Left aligned : '"<< left <<setw(5)<< num <<"'"<< endl;
cout <<"Right aligned : '"<< right <<setw(5)<< num <<"'"<< endl;
cout <<"Internal align : '"<< internal <<setw(5)<< negNum <<"'"<< endl;return0;}
The output of the above code is as follows:
Left aligned : '123 '
Right aligned : ' 123'
Internal align : '- 123'
Floating Point Manipulators
Floating point manipulators are used to control the decimal precision and set the notation to represent the decimal numbers.
Manipulators
Definition
Syntax
setprecision(n)
It sets the precision for decimal output. It specifies upto how many decimal points, we want the output.
cout << setprecision(2) << 1.41421356;
fixed
It represents the given number in fixed-point notation.
cout << fixed << 1.41421356;
scientific
It represents the given number in scientific notation.
cout << scientific << 1234.5;
The following example sets the precision of given number using setprecision(). The fixed and scientific gives result upto 6 decimal places if setprecision() manipulator is not used.
#include <iostream>#include <iomanip>usingnamespace std;intmain(){double num =1.41421356;
cout <<"Original number:"<< num << endl;
cout <<"Default: "<<setprecision(5)<< num
<< endl;
cout <<"Fixed: "<< fixed <<setprecision(3)<< num << endl;
cout <<"Scientific: "<< scientific <<setprecision(3)<< num << endl;return0;}
The output of the above code is as follows:
Original number:1.41421
Default: 1.4142
Fixed: 1.414
Scientific: 1.414e+00
Numeric Base and Case Manipulators
The numeric base manipulators are used to convert and set the base of the given number. Case manipulators specifies whether you want your hex and scientific output in uppercase or lowercase.
Manipulators
Definition
Syntax
dec
It sets the given value as decimal output.
cout << dec << 57;
oct
It sets the given value as octal output.
cout << oct << 57;
hex
It sets the given value as hexadecimal output.
cout << hex << 57;
setbase
It is used for setting the numeric base as decimal, octal, or hexadecimal in the output.
cout << setbase(16) << 42;
showbase
It is used to display the base prefix in the output.
cout << showbase << hex << 42;
noshowbase
It hides base prefix in the output.
cout << noshowbase << hex << 42;
uppercase
It represents hex and scientific in uppercase letters.
cout << uppercase << hex << 255;
nouppercase
It represents hex and scientific in lowercase letters.
cout << nouppercase << hex << 255;
The following example demonstrates the use of base and case manipulators where numeric base manipulators sets or converts the base of the given number into decimal, hex or oct. The case manipulator converts the given value into lower case and upper case.
#include <iostream>#include <iomanip>usingnamespace std;intmain(){int number =255;
cout <<"Original number:"<< number << endl;
cout <<"Decimal: "<< dec << number <<", "<<"Octal: "<< oct << number <<", "<<"Hex: "<< hex << number << endl;// Reset to decimal
cout << dec;
cout <<"\nSetting base using setbase():"<< endl;
cout <<"Base 10: "<<setbase(10)<< number <<", "<<"Base 8: "<<setbase(8)<< number <<", "<<"Base 16: "<<setbase(16)<< number << endl;
cout <<"\nHiding base prefix using noshowbase:"<< endl;
cout << noshowbase;
cout <<"Decimal: "<< dec << number <<", "<<"Octal: "<< oct << number <<", "<<"Hex: "<< hex << number << endl;
cout <<"\nDisplaying base prefix using showbase:"<< endl;
cout << showbase;
cout <<"Decimal: "<< dec << number <<", "<<"Octal: "<< oct << number <<", "<<"Hex: "<< hex << number << endl;
cout <<"\nLowercase hex using nouppercase: "<< nouppercase
<< hex << showbase <<255<<", "<<171<< endl;
cout <<"Uppercase hex uppercase: "<< uppercase << hex
<< showbase <<255<<", "<<171<< endl;return0;}
The output of the above code is as follows:
Original number:255
Decimal: 255, Octal: 377, Hex: ff
Setting base using setbase():
Base 10: 255, Base 8: 377, Base 16: ff
Hiding base prefix using noshowbase:
Decimal: 255, Octal: 377, Hex: ff
Displaying base prefix using showbase:
Decimal: 255, Octal: 0377, Hex: 0xff
Lowercase hex using nouppercase: 0xff, 0xab
Uppercase hex uppercase: 0XFF, 0XAB
Boolean Manipulators
Boolean manipulators are used to represent the boolean values as either true/false or 0/1.
Manipulators
Definition
Syntax
boolalpha
It displays booleans as true/false.
cout << boolalpha << true;
noboolalpha
It displays booleans as 1/0.
cout << noboolalpha << true;
Here is an example demonstrating the use of boolean manipulators where boolalpha and noboolalpha display boolean values as true/false and 1/0, respectively.
#include <iostream>#include <iomanip>usingnamespace std;intmain(){
cout <<"Using boolalpha for comparison"<< endl;int a =10, b =20, c =10;
cout << boolalpha;
cout <<"a = "<< a <<", b = "<< b <<", c = "<< c << endl;
cout <<"a == b: "<<(a == b)<<", "<<"a == c: "<<(a == c)<<", "<<"a < b: "<<(a < b)<<", "<<"b > c: "<<(b > c)<< endl;
cout <<"\nUsing noboolalpha for comparison"<< endl;
cout << noboolalpha;
cout <<"a = "<< a <<", b = "<< b <<", c = "<< c << endl;
cout <<"a == b: "<<(a == b)<<", "<<"a == c: "<<(a == c)<<", "<<"a < b: "<<(a < b)<<", "<<"b > c: "<<(b > c)<< endl;return0;}
The output of the above code is as follows:
Using boolalpha for comparison
a = 10, b = 20, c = 10
a == b: false, a == c: true, a < b: true, b > c: true
Using noboolalpha for comparison
a = 10, b = 20, c = 10
a == b: 0, a == c: 1, a < b: 1, b > c: 1
Time and Date Manipulators
You can format the time in the given format or parse the formatted time and date using time and date manipulators.
Manipulators
Definition
Syntax
put_time
It is used to format and output time in the specified format.
cout << put_time(&tm, “%Y-%m-%d”);
get_time
It is used for parsing the formatted time input.
cin >> get_time(&tm, “%Y-%m-%d”);
The following example demonstrates time and date manipulators to format and parse the date and time using put_time and get_time respectively:
#include <iostream>#include <iomanip>#include <sstream>#include <ctime>usingnamespace std;intmain(){
time_t now =time(0);
tm *ltm =localtime(&now);
cout <<"Current date and time using put_time: "<<"\n";
cout <<put_time(ltm,"%Y-%m-%d %H:%M:%S")<< endl;
string dateStr ="2025-09-08 14:30:00";
tm t ={};
istringstream ss(dateStr);
cout <<"Custom date and time using get_time: "<<"\n"<< dateStr << endl;
ss >>get_time(&t,"%Y-%m-%d %H:%M:%S");return0;}
The output of the above code is as follows:
Current date and time using put_time:
2025-09-08 07:19:03
Custom date and time using get_time:
2025-09-08 14:30:00
Conclusion
Manipulators in C++ are special functions that are used with input and output streams (cin and cout) to change the output format and how to read an input. Manipulators in C++ can be further categorized into the following types: output stream manipulators, input stream manipulators, alignment manipulators, floating point manipulators, numeric base and case manipulators, boolean manipulators, time and date manipulators.
The predefined object cout is an instance of ostream class that displays the output to the user. The cout object is said to be attached to the standard output device, which usually is the screen. The cout object is used in conjunction with the stream insertion operator (<<) that inserts the data into the output stream and displays the data on the screen.
The syntax for using cout object with a single variable and multiple variables is given below −
In this example, we are checking the state of the output stream. For successful operations, it prints success message and for failed operations, it prints a message of output stream error.
#include <iostream>usingnamespace std;intmain(){int num =345;
cout <<"Displaying number: "<< num << endl;if(cout.good()){
cout <<"Output stream is in good state"<< endl;}else{
cout <<"Output stream has errors"<< endl;}return0;}
The output of the above code is as follows −
Displaying number: 345
Output stream is in good state
Conclusion
In this chapter, we understood the cout object and its usage along with its member functions and their respective example codes.
The predefined object cin is an instance of istream class that accepts the user input. The cin object is said to be attached to the standard input device, which usually is the keyboard. The cin object is used in conjunction with the stream extraction operator (>>) that extracts the data from the input stream and stores the extracted data in a variable.
The syntax for using the cin object with a single variable and multiple variables is given below −
// For single variable
cin >> variable_name;or// For multiple variables
cin >> variable1 >> variable2 >>...>> variableN;
where,>> is the extraction operator.
variable_name, variable1, variable2,..., variableN are
the variable names where we store the input values.
Read this chapter to get a good understanding of how the cin object works. We have used plenty of examples to explain all of its features in detail.
Taking User Input with cin
The following example demonstrates how to take a single integer and multiple integers as input using cin to calculate the sum of the numbers −
The output of the above code is given below. Here we have used the get() function twice. The first time it return the character ‘a’ and second time it returns a blank space.
Enter any character: a b c
Entered character: 'a'
Entered character: ' '
In this example, we are validating the user input for an integer. For integer input, it prints the integer and for non-integer inputs, it prints a message of invalid input.
#include <iostream>usingnamespace std;intmain(){int num;
cout <<"Enter an integer: ";
cin >> num;if(cin.good()){
cout <<"Valid input. Given number: "<< num << endl;}else{
cout <<"Invalid input. Input number is not an integer"<< endl;}return0;}
The output of the above code is as follows −
Enter an integer: 345
Valid input. Given number: 345
Enter an integer: abcd
Invalid input. Input number is not an integer