Chapter – 2

Fundamental Types, Constants, and Variables

This chapter introduces you to the basic types and objects used by C++ programs.

■ FUNDAMENTAL TYPES

Overview*

* without type void, which will be introduced later.

A program can use several data to solve a given problem, for example, characters, inte- gers, or floating-point numbers. Since a computer uses different methods for processing and saving data, the data type must be known. The type defines

  1. the internal representation of the data, and
  2. the amount of memory to allocate.

A number such as -1000 can be stored in either 2 or 4 bytes. When accessing the part of memory in which the number is stored, it is important to read the correct number of bytes. Moreover, the memory content, that is the bit sequence being read, must be interpreted correctly as a signed integer.

The C++ compiler recognizes the fundamental types, also referred to as built-in types, shown on the opposite page, on which all other types (vectors, pointers, classes, …) are based.

The Type bool

The result of a comparison or a logical association using AND or OR is a boolean value, which can be true or false. C++ uses the bool type to represent boolean values. An expression of the type bool can either be true or false, where the internal value for true will be represented as the numerical value 1 and false by a zero.

  • The char and wchar_t Types

These types are used for saving character codes. A character code is an integer associated with each character. The letter A is represented by code 65, for example. The character set defines which code represents a certain character. When displaying characters on screen, the applicable character codes are transmitted and the “receiver,” that is the screen, is responsible for correctly interpreting the codes.

The C++ language does not stipulate any particular characters set, although in gen- eral a character set that contains the ASCII code (American Standard Code for Informa- tion Interchange) is used. This 7-bit code contains definitions for 32 control characters (codes 0 – 31) and 96 printable characters (codes 32 – 127).

The char (character) type is used to store character codes in one byte (8 bits). This amount of storage is sufficient for extended character sets, for example, the ANSI char- acter set that contains the ASCII codes and additional characters such as German umlauts.

The wchar_t (wide character type) type comprises at least 2 bytes (16 bits) and is thus capable of storing modern Unicode characters. Unicode is a 16-bit code also used in Windows NT and containing codes for approximately 35,000 characters in 24 languages.

■ FUNDAMENTAL TYPES (CONTINUED)
                                        

Integral types:

TypeSizeRange of Values (decimal)
char unsigned char signed char1 byte 1 byte 1 byte—128 to +127 or 0 to 255 0 to 255 —128 to +127
int2 byte resp.—32768 to +32767 resp.
 4 byte—2147483648 to +2147483647
unsigned int2 byte resp.0 to 65535 resp.
 4 byte0 to 4294967295
short unsigned short2 byte 2 byte—32768 to +32767 0 to 65535
long4 byte—2147483648 to +2147483647
unsigned long4 byte0 to 4294967295

Sample program:

The types short, int, and long are available for operations with integers. These types are distinguished by their ranges of values. The table on the opposite page shows the integer types, which are also referred to as integral types, with their typical storage requirements and ranges of values.

The int (integer) type is tailor-made for computers and adapts to the length of a reg- ister on the computer. For 16-bit computers, int is thus equivalent to short, whereas for 32-bit computers int will be equivalent to long.

□   Integral Types

C++ treats character codes just like normal integers. This means you can perform cal- culations with variables belonging to the char or wchar_t types in exactly the same way as with int type variables. char is an integral type with a size of one byte. The range of values is thus –128 to +127 or from 0 to 255, depending on whether the com- piler interprets the char type as signed or unsigned. This can vary in C++.

The wchar_t type is a further integral type and is normally defined as unsigned short.

The signed and unsigned Modifiers

The short, int, and long types are normally interpreted as signed with the highest bit representing the sign. However, integral types can be preceded by the keyword unsigned. The amount of memory required remains unaltered but the range of values changes due to the highest bit no longer being required as a sign. The keyword unsigned can be used as an abbreviation for unsigned int.

In ANSI C++ the size of integer types is not preset. However, the following order applies:

                                char <= short <= int <= long

Moreover, the short type comprises at least 2 bytes and the long type at least 4 bytes.

The current value ranges are available in the climits header file. This file defines constants such as CHAR_MIN, CHAR_MAX, INT_MIN, and INT_MAX, which represent the smallest and greatest possible values. The program on the opposite page outputs the value of these constants for the int and unsigned int types.

 ■ FUNDAMENTAL TYPES (CONTINUED)

Floating-pointtypes:

  Type  Size  Range of Values  Lowest Positive Value  Accuracy (decimal)
float  4 bytes  –3.4E+38  1.2E—38  6 digits
double  8 bytes  –1.7E+308  2.3E—308  15 digits
long double10 bytes–1.1E+49323.4E—493219 digits
IEEE format (IEEE = Institute of Electrical and Electronic Engineers) is normally used to represent floating-point types. The table above makes use of this representation.

Arithmetictypes

Arithmetic operators are defined for arithmetic types, i.e. you can perform calculations with variables of this type.

□   Floating-Point Types

Numbers with a fraction part are indicated by a decimal point in C++ and are referred to as floating-point numbers. In contrast to integers, floating-point numbers must be stored to a preset accuracy. The following three types are available for calculations involving floating-point numbers:

float          for simple accuracy

double         for double accuracy

long double    for high accuracy

The value range and accuracy of a type are derived from the amount of memory allocated and the internal representation of the type.

Accuracy is expressed in decimal places. This means that “six decimal places” allows a programmer to store two floating-point numbers that differ within the first six decimal places as separate numbers. In reverse, there is no guarantee that the figures 12.3456 and 12.34561 will be distinguished when working to a accuracy of six decimal places. And remember, it is not a question of the position of the decimal point, but merely of the numerical sequence.

If it is important for your program to display floating-point numbers with an accuracy supported by a particular machine, you should refer to the values defined in the cfloat header file.

Readers interested in additional material on this subject should refer to the Appendix, which contains a section on the representation of binary numbers on computers for both integers and floating-point numbers.

□ The size of Operator

The amount of memory needed to store an object of a certain type can be ascertained using the sizeof operator:

sizeof (name)

yields the size of an object in bytes, and the parameter name indicates the object type or the object itself. For example, sizeof (int)represents a value of 2 or 4 depending on the machine. In contrast, sizeof (float) will always equal 4.

□   Classification

The fundamental types in C++ are integer types, floating-point types, and the void type. The types used for integers and floating-point numbers are collectively referred to as arithmetic types, as arithmetic operators are defined for them.

The void type is used for expressions that do not represent a value. A function call can thus take a void type.

Examples for integral constants

DecimalOctalHexadecimalType
160200x10int
2550377OXffint
327670777770x7FFFint
32768U0100000U0x8000Uunsigned int
10000003032400x186A0int (32 bit-) long (16 bit- CPU)
10L012L0xALlong
27UL033UL0x1bULunsigned long
21474836480200000000000x80000000unsigned long
In each line of the above table, the same value is presented in a different way.

Sample program

// To display hexadecimal integer literals and
// decimal integer literals.
//
#include <iostream> 
using namespace std;

int main()
{
   // cout outputs integers as decimal integers:
   cout << "Value of 0xFF = " << 0xFF << " decimal"
      << endl;	                 // Output: 255 decimal
   // The manipulator hex changes output to hexadecimal
 // format (dec changes to decimal format):
   cout << "Value of 27 = " << hex << 27 <<" hexadecimal"
      << endl;	            // Output: 1b hexadecimal
      return 0;
}

The boolean keywords true and false, a number, a character, or a character sequence (string) are all constants, which are also referred to as a literals. Constants can thus be subdivided into

  • boolean constants
  • numerical constants
  • character constants
  • string constants.

Every constant represents a value and thus a type—as does every expression in C++. The type is defined by the way the constant is written.

□   Boolean Constants

A boolean expression can have two values that are identified by the keywords true and false. Both constants are of the bool type. They can be used, for example, to set flags representing just two states.

□   Integral Constants

Integral numerical constants can be represented as simple decimal numbers, octals, or hexadecimals:

  • A decimal constant (base 10) begins with a decimal number other than zero, such as 109 or 987650
  • Anoctal constant (base 8) begins with a leading 0, for example 077 or 01234567
  • A hexadecimal constant (base 16) begins with the character pair 0x or 0X, for example 0x2A0 or 0X4b1C. Hexadecimal numbers can be capitalized or non- capitalized.

Integral constants are normally of type int. If the value of the constant is too large for the int type, a type capable of representing larger values will be applied. The ranking for decimal constants is as follows:

int, long, unsigned long

You can designate the type of a constant by adding the letter L or l (for long), or U

or u (for unsigned). For example,

12Land12lcorrespond to the type long
12Uand12ucorrespond to the type unsigned int
12ULand12ulcorrespond to the type unsigned long

 

 ■ CONSTANTS (CONTINUED)

Examples for floating-point constants

  5.19  12.  0.75  0.00004
0.519E112.0.750.4e-4
0.0519e2.12E+27.5e-1.4E-4
519.OE-212e075E-24E-5

Examples for character constants

  Constant  Character  Constant Value (ASCII code decimal)
‘A’Capital A65
‘a’Lowercase a97
‘ ‘Blank32
‘.’Dot46
‘0’Digit 048
‘\0’Terminating null character0

Internal representation of a string literal

String literal:      “Hello!”

Stored byte sequence:

‘H’‘e’‘1’‘1’‘o’‘!’‘\0’

□   Floating-Point Constants

Floating-point numbers are always represented as decimals, a decimal point being used to distinguish the fraction part from the integer part. However, exponential notation is also permissible.

EXAMPLES:  27.1     1.8E–2     // Type: double

Here, 1.8E–2 represents a value of 1.8*10–2. E can also be written with a small lettere. A decimal point or E (e) must always be used to distinguish floating-point constants from integer constants.

Floating-point constants are of type double by default. However, you can add F or f to designate the float type, or add L or l for the long double type.

□   Character Constants

A character constant is a character enclosed in single quotes. Character constants take the type char.

EXAMPLE:  ‘A’    // Type: char

The numerical value is the character code representing the character. The constant ‘A’ thus has a value of 65 in ASCII code.

□   String Constants

You already know string constants, which were introduced for text output using the cout stream. A string constant consists of a sequence of characters enclosed in double quotes.

EXAMPLE:  Today is a beautiful day!

A string constant is stored internally without the quotes but terminated with a null char- acter, \0, represented by a byte with a numerical value of 0 — that is, all the bits in this byte are set to 0. Thus, a string occupies one byte more in memory than the number of characters it contains. An empty string, “”, therefore occupies a single byte.

The terminating null character \0 is not the same as the number zero and has a differ- ent character code than zero. Thus, the string

EXAMPLE:  0

Comprises two bytes, the first byte containing the code for the character zero 0 (ASCII code 48) and the second byte the value 0.

The terminating null character \0 is an example of an escape sequence. Escape sequences are described in the following section.

 ■ ESCAPE SEQUENCES

Overview

  Single character  Meaning  ASCII code (decimal)
\aalert (BEL)7
\bbackspace (BS)8
\thorizontal tab (HT)9
\nline feed (LF)10
\vvertical tab (VT)11
\fform feed (FF)12
\rcarriage return (CR)13
\”” (double quote)34
\’‘ (single quote)39
\?? (question mark)63
\\\ (backslash)92
\0string terminating character0
\ooo (up to 3 octal digits)numerical value of a characterooo (octal!)
\xhh (hexadecimal digits)numerical value of a characterhh (hexadecimal!)

Sample program:

#include <iostream> 
using namespace std;
int main()
{
  cout << "\nThis is\t a string\n\t\t"
          " with \"many\" escape sequences!\n";
  return 0;
}

Programoutput:

This is         a string

with "many" escape sequences!

□   Using Control and Special Characters

Nongraphic characters can be expressed by means of escape sequences, for example \t, which represents a tab.

The effect of an escape sequence will depend on the device concerned. The sequence \t, for example, depends on the setting for the tab width, which defaults to eight blanks but can be any value.

An escape sequence always begins with a \ (backslash) and represents a single charac- ter. The table on the opposite page shows the standard escape sequences, their decimal values, and effects.

You can use octal and hexadecimal escape sequences to create any character code. Thus, the letter A (decimal 65) in ASCII code can also be expressed as \101 (three octals) or \x41 (two hexadecimals). Traditionally, escape sequences are used only to represent non-printable characters and special characters. The control sequences for screen and printer drivers are, for example, initiated by the ESC character (decimal 27), which can be represented as \33 or \x1b.

Escape sequences are used in character and string constants.

EXAMPLES:  '\t'  "\tHello\n\tMike!"

The characters ‘, “, and \ have no special significance when preceded by a backslash, i.e. they can be represented as \’, \”, and \\ respectively.

When using octal numbers for escape sequences in strings, be sure to use three digits, for example, \033 and not \33. This helps to avoid any subsequent numbers being eval- uated as part of the escape sequence. There is no maximum number of digits in a hexa- decimal escape sequence. The sequence of hex numbers automatically terminates with the first character that is not a valid hex number.

The sample program on the opposite page demonstrates the use of escape sequences in strings. The fact that a string can occupy two lines is another new feature. String constants separated only by white spaces will be concatenated to form a single string.

To continue a string in the next line you can also use a backslash \ as the last character in a line, and then press the Enter key to begin a new line, where you can continue typing the string.

EXAMPLE:  "I am a very, very \

long string"

Please note, however, that the leading spaces in the second line will be evaluated as part of the string. It is thus generally preferable to use the first method, that is, to terminate the string with ” and reopen it with “.

 ■ NAMES

Keywords in C++

    asm    do    inline    short    typeid
autodoubleintsignedtypename
booldynamic_castlongsizeofunion
breakelsemutablestaticunsigned
caseenumnamespacestatic_castusing
catchexplicitnewstructvirtual
charexternoperatorswitchvoid
classfalseprivatetemplatevolatile
constfloatprotectedthiswchar_t
const_castforpublicthrowwhile
continuefriendregistertrue 
defaultgotoreinterpret_casttry 
deleteifreturntypedef 

Examples for names

□ Valid Names

Within a program names are used to designate variables and functions. The following rules apply when creating names, which are also known as identifiers:

■ a name contains a series of letters, numbers, or underscore characters ( _ ). Ger- man umlauts and accented letters are invalid. C++ is case sensitive; that is, upper- and lowercase letters are different.
■ the first character must be a letter or underscore
■ there are no restrictions on the length of a name and all the characters in the name are significant
■ C++ keywords are reserved and cannot be used as names.

The opposite page shows C++ keywords and some examples of valid and invalid names. The C++ compiler uses internal names that begin with one or two underscores followed by a capital letter. To avoid confusion with these names, avoid use of the under- score at the beginning of a name.
Under normal circumstances the linker only evaluates a set number of characters, for example, the first 8 characters of a name. For this reason names of global objects, such as functions, should be chosen so that the first eight characters are significant.

□   Conventions

In C++ it is standard practice to use small letters for the names of variables and func- tions. The names of some variables tend to be associated with a specific use.

EXAMPLES:

c, ch	for characters
i, j, k, l, m, n	for integers, in particular indices
x, y, z	for floating-point numbers

To improve the readability of your programs you should choose longer and more self- explanatory names, such as start_index or startIndex for the first index in a range of index values.
In the case of software projects, naming conventions will normally apply. For exam- ple, prefixes that indicate the type of the variable may be assigned when naming vari- ables.

 ■ VARIABLES

Sample program

HINT:
Both strings and all other values of fundamental types can be output with cout. Integers are printed in decimal format by default

Screen output

Value of gVar1: 0

Value of gVar2: 2

Character in ch: A

Value of sum:  8

Data such as numbers, characters, or even complete records are stored in variables to enable their processing by a program. Variables are also referred to as objects, particularly if they belong to a class.

□   Defining Variables

A variable must be defined before you can use it in a program. When you define a vari- able the type is specified and an appropriate amount of memory reserved. This memory space is addressed by reference to the name of the variable. A simple definition has the following syntax:

SYNTAX: typ name1 [name2 … ];

This defines the names of the variables in the list name1 [, name2 …] as variables of the type type. The parentheses [ … ] in the syntax description indicate that this part is optional and can be omitted. Thus, one or more variables can be stated within a single definition.

EXAMPLES:

char c;
int i, counter;
double x, y, size;

In a program, variables can be defined either within the program’s functions or out- side of them. This has the following effect:

  • a variable defined outside of each function is global, i.e. it can be used by all func- tions
  • a variable defined within a function is local, i.e. it can be used only in that func- tion.

Local variables are normally defined immediately after the first brace—for example at the beginning of a function. However, they can be defined wherever a statement is per- mitted. This means that variables can be defined immediately before they are used by the program.

□   Initialization

A variable can be initialized, i.e. a value can be assigned to the variable, during its defini- tion. Initialization is achieved by placing the following immediately after the name of the variable:

  • an equals sign ( = ) and an initial value for the variable or
  • round brackets containing the value of the variable.

EXAMPLES:

char c = 'a';
float x(1.875);

Any global variables not explicitly initialized default to zero. In contrast, the initial value for any local variables that you fail to initialize will have an undefined initial value.

■ THE KEYWORDS const AND volatile

Sample program

NOTE:
By default cout outputs a floating-point number with a maximum of 6 decimal places without trailing zeros.

Screenoutput

To Evaluate a Circle

Radius:	1.5
Circumference:	9.42478
Area:	7.06858

A type can be modified using the const and volatile keywords.

□   Constant Objects

The const keyword is used to create a “read only” object. As an object of this type is constant, it cannot be modified at a later stage and must be initialized during its defini- tion.

EXAMPLE:  const double pi = 3.1415947;

Thus the value of pi cannot be modified by the program. Even a statement such as the following will merely result in an error message:

pi = pi + 2.0;              // invalid

□   Volatile Objects

The keyword volatile, which is rarely used, creates variables that can be modified not only by the program but also by other programs and external events. Events can be initi- ated by interrupts or by a hardware clock, for example.

EXAMPLE:  volatile unsigned long clock_ticks;

Even if the program itself does not modify the variable, the compiler must assume that the value of the variable has changed since it was last accessed. The compiler therefore creates machine code to read the value of the variable whenever it is accessed instead of repeatedly using a value that has been read at a prior stage.

It is also possible to combine the keywords const and volatile when declaring a variable.

EXAMPLE:  volatile const unsigned time_to_live;

Based on this declaration, the variable time_to_live cannot be modified by the pro- gram but by external events.

EXERCISES

For exercise 3

Defining and initializing variables:
int a(2.5);	        const long large;
int b = '?';	        char c('\'');
char z(500);	        unsigned char ch = '\201';
int big = 40000;	unsigned size(40000);
double he's(1.2E+5);	float val = 12345.12345;
Exercise 1

The sizeof operator can be used to determine the number of bytes occupied in memory by a variable of a certain type. For example, sizeof(short) is equivalent to 2.
Write a C++ program that displays the memory space required by each fundamental type on screen.

Exercise 2

Write a C++ program to generate the screen output shown on the opposite page.

Exercise 3

Which of the variable definitions shown on the opposite page is invalid or does not make sense?

Exercise 4

Write a C++ program that two defines variables for floating-point numbers and initializes them with the values
123.456 and 76.543
Then display the sum and the difference of these two numbers on screen.

SOLUTIONS

Exercise 1

#include <iostream> 
using namespace std;

int main()
{
  cout << "\nSize of Fundamental Types\n"
       << " Type	Number of Bytes\n"
       << "----------------------------------" << endl;
  cout << " char:	" << sizeof(char) << endl; 
  cout << " short:    " << sizeof(short)<< endl; 
  cout << " int:	" << sizeof(int) << endl;
  cout << " long:	" << sizeof(long) << endl; 
  cout << " float:    " << sizeof(float)<< endl; 
  cout << " double:   " << sizeof(double)<<endl; 
  cout << " long double:  " << sizeof(long double)
       << endl;
  return 0;
}
Exercise 2

// Usage of escape sequences


#include <iostream> 
using namespace std;

int main()
{
      cout << "\n\n\t I"	        // Instead of tabs 
              "\n\n\t\t \"RUSH\""	// you can send the 
              "\n\n\t\t\t \\TO\\"	// suited number 
              "\n\n\t\t AND"	        // of blanks to 
              "\n\n\t /FRO/" << endl;	// the output.
      return 0;
}
Exercise 3

Incorrect:

int a(2.5);	          // 2.5 is not an integer value 
const long large;	  // Without initialization
char z(500);	          // The value 500 is too large
                          // to fit in a byte
int big = 40000;	  // Attention! On 16-bit systems
                          // int values are <= 32767 
double he's(1.2E+5);	  // The character ' is not
                          // allowed in names 
float val = 12345.12345;  // The accuracy of float
                          // is only 6 digits
Exercise 4

// Defining and initializing variables

#include <iostream> 
using namespace std;

int main()
{
     float x = 123.456F,	// or double 
           y = 76.543F,
           sum;
     sum = x + y;
 cout << "Total:	"
      << x << " + " << y << " = " << sum << endl;

 cout << "Difference: "
      << x << " — " << y << " = " << (x — y) << endl;

 return 0;
}