Sample Chapter
Sample Chapter
3.1 INTRODUCTION
A region of memory allocated for holding a single piece of data (for now a single number), is called a
variable. C++ allows you to create a variable, i.e. allocate the memory, and give it a name. The name
is to be used to refer to the variable in the rest of the program. A variable can be created by writing the
following in your program.
data-type variable-name;
In this, data-type must be a data-type selected from the first column of Table 3.1, and
variable-name a name chosen as per Section 3.1.1. This statement creates a variable of the name
variable-name, having the specified data-type. The data-type of a variable determines
how much space the variable uses (given in column 3 of Table 3.1), and the type of values expected to
be stored in the variable (column 4 of Table 3.1).
You have already seen some examples, e.g. in Section 1.3.1, we wrote
int nsides;
30 An Introduction to Programming through C++
We said then that this would create a variable capable of storing integers. From Table 3.1, you now also
know that typically the variable will use 4 bytes of memory, and will store positive and negative num-
bers. As discussed in Section 2.4.2, such numbers are typically represented in the two’s complement
representation, and if so the numbers in the range −2147483648 to 2147483647 can be stored.
C++ provides the types signed char, short int, long int, and long long
int for storing (positive or negative) integers. Variables of these respective types will use amount
of memory as given in Table 3.1 and will be able to store values in correspondingly larger or smaller
range. In all such cases, very likely the two’s complement representation of Section 2.4.2 is used.
Variables and Data Types 31
If you know that you will only store non-negative integers in a certain variable, you may choose one
of the unsigned types. For example, you may write:
unsigned int telephoneNumber;
This will create a variable called telephoneNumber, using 4 bytes, and the values will be
stored using the binary representation, as discussed in Section 2.4.1. The types unsigned
char, unsigned short, unsigned long and unsigned long long are also used for
storing non-negative integers. These will respectively use different amount of memory and allow
correspondingly smaller or larger ranges.
The following will create a variable called temperature for storing real numbers.
double temperature;
The created variable will be 8 bytes long. It will typically use the IEEE Floating Point Standard as
discussed in Section 2.4.3. The type name double is short for “double precision”, in comparison to
the type float which uses 4 bytes and is considered “single precision”.
The first 9 types in Table 3.1 are said to be integral types, and the last 3, floating types.
It should be noted that the size shown for each data type is only indicative. The C++ language
standard only requires that the sizes of char, short, int, long, long long to be in non-
decreasing order. Likewise, the sizes of float, double, long double are also expected to be
non-decreasing. The exact sizes are may vary from one compiler to another but can be determined as
discussed in Section 3.1.6.
The char types are most commonly used for storing text, as we will see later. In such uses it is
customary to omit the qualifiers signed or unsigned and write:
char firstLetterOfName;
This will create a 1 byte variable, of type either unsigned char or signed char. One of these
types will be chosen by the compiler. Note that if you are using char to store text, the exact choice
does not matter because the ASCII code is uses only the range 0 to 127 which is present in either the
signed or the unsigned version. If you use the char type to store integers (that happen to lie in a small
range) then it is best to specify whether you want the signed or the unsigned type.
The type bool is primarily used to store logical values, as will be seen in Section 6.7.
The phrase value of a variable is used to refer to the value stored in the variable. So the stored
telephone number (after it is stored, and we will say how to do this) will be the value of the variable
telephone_number.
We finally note that you can define several variables in a single statement if they have the same type,
by writing:
data-type variable-name1, variable-name2, ... variable-namek;
3.1.1 Identifiers
The technical term for a name in C++ is identifier. Identifiers can be used for naming variables, but
also other entities as we will see later.
An identifier can consist of letters, digits and the underscore character “_”. Identifiers cannot start
with a digit, hence you cannot have an identifier such as 3rdcousin. It is also not considered good
practice to use identifiers starting with an underscore for naming ordinary variables. Finally, some
32 An Introduction to Programming through C++
words are reserved by C++ for its own use, and these cannot be used as variable names. For example,
int is a reserved word; it is not allowed to be used as a variable name because it will be confusing.
The complete list of reserved words is given in Appendix B.
It is customary to name a variable to indicate the intended purpose of the variable. For example, if
we want to store a velocity in a variable, then we should give the name velocity to the variable.
An important point is that case is important in names; so mathmarks is considered to be a different
name from MathMarks. Notice that the latter is easier to read. This way of forming names, in which
several words are strung together, and in which the first letter of each word is capitalized, is said to be
utilizing camel case, or CamelCase. As you might guess, the capital letters resemble the humps on the
back of a camel. There are two kinds of CamelCase: UpperCamelCase in which the first letters of all
the words are capitalized, and lowerCamelCase, in which the first letters of all but the first word are
capitalized. For ordinary variables, it is more customary to use lowerCamelCase; thus it is suggested
that you use mathMarks rather than MathMarks.
If a variable is important in your program, you should give it a descriptive name, which expresses
its use. It is usually best to use complete words, unabbreviated. Thus if you have a variable which
contains the temperature, it is better to give it the name temperature rather than t, or temp or
tmprtre. Sometimes the description that you want to associate with a variable name is very long. Or
there is a clarification that the reader should be be aware of. In such cases, it is good to add a comment
explaining what you want immediately following the definition, e.g.
double temperature; // in degrees centigrade.
To initialize floating variables, we need a way to specify real number literals. We can specify real
number literals either by writing them out as decimal fractions, or using an analogue of “scientific
notation”. We simply write an E or e between the significand and the exponent, without leaving any
spaces. Thus, we would write Avogadro’s number1 , 6.022 × 1023, as 6.022E23. The significand as
well as the exponent could be specified with a minus sign, if needed, of course. For example the mass
of an electron, 9.10938188 × 10−31 kg, would be written as 9.10938188E-31. Thus we may write:
float w, y=1.5, avogadro = 6.022E23, eMass = 9.10938188E-31;
This statement defines 4 variables, the second, third and fourth are respectively initialized to 1.5,
6.022 × 1023 and 9.10938188 × 10−31. The variable w is not initialized.
Literals also have a type associated with them. An integer literal like 35 is considered to be of
type int, and a floating literal like 100.0 is by default considered to be of type double. You can
specify literals of specific types by attaching the suffixes L,F,U which respectively stand for long, float,
unsigned. Thus, if you write 100LU, it will be interpreted as a literal of type long unsigned,
having the value 100.
1 The number of molecules in a mole of any substance, e.g. number of carbon atoms in 12 gm of carbon.
34 An Introduction to Programming through C++
typing the value that you wanted. Let us consider an example. Suppose pqr has type int, then if you
execute the above statement, and type
123 56
the spaces that you type at the beginning will be ignored, the value 123 will be stored into pqr. This
is because the space following 123 will serve as a delimiter. The 56 will be used for a subsequent read
statement, if any. Note further that the value you type will not be received by your program unless you
type a newline after typing the value. Thus to place 123 into pqr in response to the statement above,
you must type a newline either immediately following 123 or following 56.
If pqr was of any of the floating types, then a literal of that type would be expected. Thus we could
have typed in 6.022e23 or 1.5. If pqr was of type bool you may only type 0 or 1.
3.1.5 Printing
If you print a variable rst of type bool, short, int or long, writing
cout << rst << endl;
its value will be printed. A minus sign will be printed if the value is negative. The final endl will
cause a newline to follow.
If you print a floating type variable, then C++ will print it in what it considers to be the best looking
form: as a decimal fraction or in the scientific format.
This will cause that character whose ASCII value is in xyz to be printed. Thus, in this case, the letter
a will be printed. Following that a newline will be printed, because of the endl at the end of the
statement.
operators, i.e. the so called right-associative operators, the operation on the right will get done first
(Section 3.2.6). Of course, we can use brackets to enforce the order we want, e.g. write 5 − (3 + 9)
if we want this expression to evaluate to −7. If we had C++ variables x,y,p,q, then the expression
corresponding to the algebraic expression above would have to be written as x*y+p*q. Note that
when you use a variable in an expression, it is your responsibility to ensure that the variable has been
assigned a value earlier.
An expression causes a sequence of arithmetic operations to be performed, and a value to be
computed. However, the computed value is lost unless we do something with it. One possibility is
to store the computed value in some variable. This can be done using an assignment statement. The
general form of an assignment is
variable = expression;
where variable is the name of a variable, and expression is an expression as described above.
Here is an example.
int x=2,y=3,p=4,q=5,r;
r = x*y + p*q;
This will cause r to get the value of the specified expression. Using the values given for the other
variables, the expression is simply 2 * 3 + 4 * 5, i.e. 26. Thus r will get the value 26.
We could also print out the value of the expression by writing
cout << x*y+p*q << endl;
Note that when you use a variable in an expression, you must have assigned it a value already, say
by initializing it at the time of defining it, or by reading a value into it from the keyboard, or in a
previous assignment statement. If this is not done, the variable will still contain some value, only you
don’t know what value. If an unknown value is used in a computation, the result will of course be
unpredictable in general.
Note that the operator = is used somewhat differently in C++ than in mathematics. In mathematics
a statement r = x*y + p*q; asserts that the left-hand side and right-hand side are equal. In C++
however, it is a command to evaluate the expression on the right and put the resulting value into the
variable named on the left.
Note also that we cannot write x*y + p*q = r; because we require the left hand side to be a
variable, into which the value of the expression on the right hand side must be stored.
The rule described above makes it perfectly natural to write a statement such as
p = p + 1;
This is meaningless in mathematics; in C++, however, it just says: evaluate the expression on the right
hand side and put the resulting value into the variable named on the left. Assuming p has the value 4
as in the code fragment given earlier, its value is 4, the statement would cause the addition 4 + 1 = 5 to
be performed. The result, 5, would be put in p.
3.2.2 Subtleties
The assignment statement is somewhat tricky. The first point concerns the floating point
representations. Both float and double are imprecise representations, where the significand is
correct only to a fixed number of bits. So if an arithmetic operation affects less significant bits, then the
operation will have no effect. As an example, consider the following code.
float w, y=1.5, avogadro=6.022E23 ;
w = avogadro + y;
What is the value of w? Suppose for a moment that we precisely calculate the sum avogadro + y.
The sum will be
602200000000000000000001.5
We will have a problem when we try to store this into a float type variable. This is because a float
type variable can only stores significands of 24 bits, or about 7 digits. So in order to store, we would
treat everything beyond the most significant 7 digits as 0. If so we would get
602200000000000000000000
This loss of digits is called round-off error. After the round off, this can now fit in a float, because
it can be written exactly as 6.022E23. Net effect of the addition: nothing! The variable w gets the
value avogadro even though you assigned it the value avogadro + 1.5. This example shows the
inherent problem in adding a very small float value to a very large float value.
38 An Introduction to Programming through C++
Some subtleties arise when we perform an arithmetic operation in which the operands have different
types, or even simply if you store one type of number into a variable of another type. C++ allows such
operations, and could be said to perform such actions reasonably well. However, it is worth knowing
what exactly happens.
Suppose we assign an int expression to a float variable, C++ will first convert the expression
into the floating point format. An int variable will have 31 bits of precision excluding the sign,
whereas a float variable only has 24 bits or so. So essentially some precision could be lost. There
could be loss of precision also if we assign a float expression to an int variable. Consider
float y = 6.6;
int x = y;
The value 6.6 is not integral, so C++ tries to do the best it can: it keeps the integer part. At the end, x
will equal 6. Basically, when a floating value is to be stored into an integer, C++ uses truncation, i.e.
the fractional part is dropped. You might want the assigned value to be the closest integer. This you
can obtain for yourself by adding 0.5 before the assignment. Thus, if you write x=y+0.5;, then x
would become 7, the integer closest to y. Note that some precision could be lost when you store a value
from a double (53 bits of precision) into a float (24 bits of precision). Overflow is also possible, as
discussed later.
When we perform an arithmetic operation on operands of the same type the result is also computed
to be of the same type. If your program asks to perform arithmetic operations on operands of different
types, then the operands are first converted by C++ so that they have the same type. The rules for this
are fairly natural. C++ always converts less expressive types to more expressive ones, where unsigned
integral types are deemed less expressive than signed integral types, which in turn are deemed less
expressive than the floating types. If the two types differ in size, then the smaller is converted to have a
larger size. As an example, suppose we have an arithmetic expression var1 op var2, where var1 is
int and var2 is float. Then var1 will be converted to float, and the result will also be float.
If var1, var2 are long, int, then var2 will be converted to long. If the operands are of type
float, long long then both will be converted to double, and so on. After the expression is
evaluated, it may either itself form an operand in a bigger expression, or it might have to be stored into
a variable. In both cases, there may have to be a further type conversion.
It is important to be careful with division.
int x=100, w;
float y,z;
y = 360/x;
z = 360.0/x;
w = 360.0/x;
As per the rules stated, 360/x will be evaluated to have an integer value since both operands are
integer. Thus the exact quotient 3.6 will be truncated to give 3. This value will be stored (after
conversion to the floating point format) into y. In the next statement, 360.0, the first operand is
double, hence the result will be evaluated as a double, i.e. 3.6. This value will be stored in z. In
the final statement, the value of the expression will indeed be 3.6, however because w is of type int,
there will have to be a type conversion, and as a result the value stored in w will be just 3.
Variables and Data Types 39
Note finally that if the dividend and the divisor are of integral types, and the divisor is 0, then an
error will be reported when such an operation happens during execution, and the program will stop
with a message. Something different happens for floating types, as discussed in Section 3.2.4.
3.2.3 Overflow
For each numerical data type, we have mentioned a certain largest possible and smallest possible value
that can be represented. While performing calculations, the results can go outside this allowed range.
In this case, what exactly happens is handled differently for different types.
For the unsigned data types, the rule is that arithmetic is performed modulo 2n , where n is the
number of bits used. So for example if you add up two short numbers, both 65535, then the result
will be (65535 + 65535) mod 65536 = 65534, where you may note that 216 = 65536.
For signed integer types, the language does not specify what must happen. In other words, you as a
programmer must be careful to ensure that the numbers stay within range.
int x,y,z;
x = y = z = 1;
This will end up assigning 1 to all the variables. This has a systematic explanation as follows.
Any assignment, say z = 1, is also an expression in C++. Not only is the assignment made, but
the expression stands for the value that got assigned. Further, the associativity of = is right-to-left, i.e.
given an expression x = y = z = 1, the rightmost assignment operator is evaluated first. This is
different from the other operators you have seen so far, such as the arithmetic operators, in which the
evaluation order is left to right. Thus, the our statement x = y = z = 1; is really to be read as
x = (y = (z = 1));
Now the expression inside the innermost parentheses, z = 1 is required to be evaluated first. This not
only puts the value 1 into z, but itself evaluates to 1. Now the statement effectively becomes
x = (y = 1);
The execution continues by setting y to 1, and then x to 1.
3.3 EXAMPLES
We consider some simple examples of using the data-types and assignment statements. These do not
include the bool type which is considered in Section 6.7.
Here is a program that reads in the temperature in Centigrade and prints out the equivalent
temperature in Fahrenheit.
main_program{
double centigrade, fahrenheit;