THE BASIC DATA TYPES:
All variables in C++ must be declared prior to their
use. This is necessary
because the compiler must know what type of data a variable
contains before it can properly compile any
statement that uses the variable. In C++ there
are seven basic data types: character, wide character, integer,
floating point, double
floating point, Boolean, and somewhat surprisingly, valueless. The
keywords used to declare
variables of these types are char,
chart,
int,
float,
double,
bool,
and void,
respectively. Common sizes and ranges of each data type are shown
in Table 3-1. Remember, the sizes and ranges used
by your compiler may vary from those
listed here. The most common variance occurs between 16-bit and
32-bit environments. In
general, an integer in a 16-bit environment is 16 bits wide. In a
32-bit environment, an integer is usually 32 bits
wide Variables of type char
are used to hold 8-bit ASCII characters such
as A, B, or C, or any other
8-bit quantity. To specify a character, you must enclose it between
single quotes. The type
wchar_t is
designed to hold characters that are part of large character
sets. As you may know, many human languages, such
as Chinese, define a large number
of characters, more than will fit within the 8 bits provided by the
char type.
The wchar_t
type
was added to C++ to accommodate this situation. While we won’t be
making much use of wchar_t
in this
book, it is something that you will want to slook into if you are
tailoring programs for the international market. Variables of type
int
can
hold integer quantities that do not require fractional components.
Variables of this type are often used for controlling loops and
conditional statements. Variables of the types float
and
double
are
employed either when a fractional component is required or when your
application requires very large or small numbers. The difference
between a float
and a
double
variable
is the magnitude of the largest (and smallest) number that each one
can hold. As shown in Table 3-1, a double
in C++
can store a number approximately ten times larger than a float.
The
bool
type
stores
Boolean (i.e., true/false) values. C++ defines two Boolean constants:
true
and
false,
which are the only values that a bool
variable
may have. As you have seen, void
is used
to declare any function that does not return a value. Other purposes
of void
are
discussed later in this book.
Declaration of Variables
The general form of a
variable declaration statement is shown here:
type
variable_list;
Here, type
must be
a valid C++ data type, and variable_list
may
consist of one or more identifier names separated by commas. Some
declarations are shown here, for example:
int i, j, k;
char ch, chr;ss
float f, balance;
double d;
In C++, the name of a
variable has nothing to do with its type. Standard C++ states that at
least the first 1,024 characters of any identifier name (including
variable names) will be significant. This means that if two variable
names differ in at least one character within the first 1,024
characters, then the compiler will consider them to be different
names. There are three places where variables will be declared:
inside functions, in the definition of function parameters, and
outside of all functions. These variables are called local
variables,
formal parameters, and
global
variables, respectively.
Although we will examine the importance of these three different
types of variables in greater detail later in this book, let’s take
a brief look at them now.
Local Variables
Variables that are
declared inside a function are local variables. They can be used only
by statements that are
inside that function. Local variables are not known to functions
Outside their own.
Consider this example:
#include
<iostream>
using
namespace std;
void
func();
int
main()
{
int
x; // local to main()
x
= 10;
func();
cout
<< "\n";
cout
<< x; // displays 10
return
0;
}
void
func()
{
int
x; // local to func()
x
= -199;
cout
<< x; // displays -199
}
Here, the integer variable x
is declared twice, once in main(
) and once in func(
). The x
in main(
) has no bearing on, or relationship to, the
x in
func( ).
Specifically, changes to the x
inside func(
) will not affect the x
inside main(
). Therefore, this program will print –199
and 10 on the screen. In C++, local variables are created when the
function is called and are destroyed when the function is exited.
Correspondingly, the storage for these local variables is created and
destroyed in the same way. For these reasons, local variables do not
maintain\ their values between function calls. (That is, the value of
a local variable is lost each time its function returns.) In some C++
literature, a local variable is called a dynamic
variable or an automatic
variable. However,
this book will continue to use the term local
variable because it is the more common term.
Formal Parameters
As you saw in Chapter 2, if a function has arguments,
then those arguments must be declared. These are called the formal
parameters of the function. As shown in the
following fragment, this declaration occurs after the function name,
inside the parentheses:
int
func1(int first, int last, char ch)
{
.
.
.
}
The func1(
) function has three arguments, called first,
last,
and ch.
You must tell C++ what type of variables these are by declaring them,
as shown above. Once this has been done, these arguments receive
information passed to the function. They may also be used inside the
function as normal local variables. For example, you may make
assignments to a function’s formal parameters or use them in any
allowable C++ expression. Even though these variables perform the
special task of receiving the value of the arguments passed to the
function, they can be used like any other local variable. Like other
local variables, their value is lost once the function terminates.
Global Variables
You may be wondering how to make a variable and its data
stay in existence throughout the entire execution of your program.
You can do this in C++ by using a global variable. Unlike local
variables, global
variables will hold their value throughout
the lifetime of your program. You create global variables by
declaring them outside of all functions. A global variable can be
accessed by any function. That is, a global variable is available for
use throughout your entire program. In the following program, you can
see that the variable count
has been declared outside of all functions.
Its declaration is before the main(
) function. However, it could have been
placed anywhere, as long as it was not in a function. Remember,
though, that since you must declare a variable before you use it, it
is best to declare global variables at the top of the program.
#include
<iostream>
using
namespace std;
void
func1();
void
func2();
int
count; // this is a global variable
int
main()
{
int
i; // this is a local variable
for(i=0;
i<10; i++) {
count
= i * 2;
func1();
}
return 0;
}
void
func1()
{
cout
<< "count: " << count; // access global count
cout
<< '\n'; // output a newline
func2();
}
void
func2()
{
int
count; // this is a local variable
for(count=0;
count<3; count++) cout << '.';
}
Looking closely at this program, it should be clear that
although neither main(
) nor func1(
) has declared the variable count,
both may use it. In func2(
), however, a local variable called count
is declared. When func2(
) uses count,
it is referring to its local variable, not the global one. It is
important to remember that if a global variable and a local variable
have the same name, all references to that variable name inside the
function in which the local variable is declared will refer to the
local variable and not to the global variable.
Some Type Modifiers
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.
Table’s 3-2a and 3-2b show all the allowed combinations of the
basic types and the type modifiers for both 16- and 32-bit
environments. The tables also show the most common size and range for
each type. You should check your compiler’s documentation for the
actual range supported by your compiler. As you look at the tables,
pay special attention to the size of a short integer, an integer, and
a long integer. Notice that in most 16-bit environments, the size of
an integer is the same as a short integer. Also notice that in most
32-bit environments, the size of an integer is the same as a long
integer. The reason for this is found in C++’s definition of its
basic types. Standard C++ states that a long integer will be at least
as large as an integer, and that an integer will be at least as large
as a short integer. Further, the size of an integer should be based
upon the execution environment. This means that for 16-bit
environments, integers are 16 bits, and for 32-bit environments,
integers are 32 bits. However, the smallest allowable size for an
integer in any environment is 16 bits. Since C++ defines only the
relationship and a set of guidelines for the size of the integer
types, there is no requirement (or guarantee) that one type will be
larger than another. However, the sizes shown in both tables hold
true for many compilers.
Although it is allowed, the use of signed
on integers is redundant because the default
declaration assumes a signed value. Technically, whether char
is signed or unsigned by default is
implementation-defined. However, for most compilers, char
is signed. In these environments, the use of
signed on
char is
also redundant. For the rest of this book, it will be assumed that
chars
are signed entities. The difference between signed and unsigned
integers is in the way the high-order bit of the integer is
interpreted. If a signed integer is specified, then the C++ compiler
will generate code that assumes that the high-order bit of an integer
is to be used as a sign
flag. If the sign flag is 0, then the number
is positive; if it is 1, then the number is negative. Negative
numbers are almost always represented using the two’s
complement approach. In this method, all bits
in the number are reversed, and then 1 is added to this number.
Signed integers are important for a great many algorithms, but they
have only half the absolute magnitude of their unsigned relatives.
For example, assuming 16-bit integers, here is 32,767:
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
For a signed value, if the high-order bit were set to 1,
the number would then be interpreted as –1 (assuming the two’s
complement format). However, if you declared this to be an unsigned
int, then when the high-order bit was set to
1, the number would become 65,535. To understand the difference
between the way that signed and unsigned integers are interpreted by
C++, you should run this short program now:
#include <iostream>
using namespace std;
/* This program shows the difference betweens
signed and unsigned integers.
*/
int main()
{
short
int i; // a signed short integer
short
unsigned int j; // an unsigned short integer
j
= 60000;
i
= j;
cout
<< i << " " << j;
return
0;
}
When this program is run, the output is –5536
60000. This is because the bit pattern that
represents 60,000 as a short unsigned integer is interpreted as
–5,536 by a short signed integer. C++ allows a shorthand notation
for declaring unsigned,
short,
or long integers.
You can simply use the word unsigned,
short,
or long,
without the int.
The int is
implied. For example, the following two statements both declare
unsigned integer variables.
unsigned x;
unsigned int y;
Variables of type char can
be used to hold values other than just the ASCII character set. A
char variable can also
be used as a "small" integer with the range –128 through
127, and it can be used in place of an integer when the situation
does not require larger numbers. For example, the following program
uses a char variable
to control the loop that prints the alphabet on the screen:
// This program prints the alphabet in reverse order.
#include <iostream>
using namespace std;
int main()
{
char letter;
for(letter = 'Z'; letter >= 'A'; letter--)
cout << letter;
return 0;
}
If the for
loop
seems weird to you, keep in mind that the character A is represented
inside the computer as a number, and that the values from A to Z are
sequential, in ascending order.
Literals
In C++, literals
(also called constants)
refer to fixed values that cannot be altered by the program. For the
most part, literals and their usage are so intuitive that they have
been used in one form or another by all the preceding sample
programs. Now, the time has come to explain them formally.
C++ literals can be of any of the basic data types. The
way each literal is represented depends upon its type. Character
literals are enclosed between single quotes. For example, 'a' and '%'
are both character literals. As some of the examples thus far have
shown, if you want to assign a character to a variable of type char,
you will use a statement similar to this one:
ch
= 'Z';
To specify a wide character literal (i.e., one that is
of type wchar_t),
precede the character with an L.
For example,
wchar_t
wc;s
wc
= L'A';
Here, wc
is assigned the wide-character constant
equivalent of A. Integer literals are specified as numbers without
fractional components. For example, 10 and –100 are integer
literals. Floating-point literals require the use of the decimal
point, followed by the number’s fractional component. For example,
11.123 is a floating-point constant. C++ also allows you to use
scientific notation for floating-point numbers.
There are two floating-point types: float
and double.
There are also several flavors of the basic types that can be
generated with the type modifiers. The question is this: How does the
compiler determine the type of a literal? For example, is 123.23 a
float
or a double?
The answer to this question has two parts. First, the C++ compiler
automatically makes certain assumptions about literals; second, you
can explicitly specify the type of a literal, if you like. By
default, the C++ compiler fits an integer literal into the smallest
compatible data type that will hold it, beginning with int.
Therefore, assuming 16-bit integers, 10 is int
by default, but 103,000 is long.
Even though the
value 10 could be fit into a character, the compiler will not do
this, because it means crossing type boundaries.
An exception to the smallest-type rule is a
floating-point constant, which is assumed to be double.
For virtually all programs you will write as a beginner, the compiler
defaults are perfectly adequate. However, it is possible to specify
precisely the type of literal you want. In cases where the default
assumption that C++ makes about a numeric literal is not what you
want, C++ allows you to specify the exact type by using a suffix. For
floating point types, if you follow the number with an F, the number
is treated as a float.
If you follow it with an L, the number becomes a long
double. For integer types, the U suffix
stands for unsigned and
the L for long.
(Both the U and the L must be used to specify an unsigned
long.) Some examples are shown here:
Variable Initializations
You can assign a value to a variable at the same time
that it is declared by placing an equal sign and the value after the
variable name. The general form of initialization is:
type variable_name =
value;
Some examples are:
char ch = 'a';
int first = 0;
float balance = 123.23F;
Although variables are frequently initialized by
constants, you can initialize a variable by using any expression
valid at the time of the initialization. As you will see,
initialization plays an important role when you are working with
objects. Global variables are initialized only at the start of the
program. Local variables are initialized each time the function in
which they are declared is entered. All global variables are
initialized to zero if no other initializer is specified. Local
variables that are not initialized will have unknown values before
the first assignment is made to them. Here is a simple example of
variable initialization. This program uses the total
( ) function to compute the summation of the
value that it is passed. In other words, total
( ) sums the digits from 1 to the value. For
example, the summation of 3 is 1 + 2 + 3, or 6. In the process, total
( ) displays a running total. Notice the use
of the sum variable
in total ( ).
// An example that uses variable initialization.
#include <iostream>
using namespace std;
void total(int x);
int main()
{
cout << "Computing summation of 5.\n";
total(5);
cout << "\n Computing summation of 6.\n";
total(6);
return 0;
}
void total(int x)
{
int sum=0; // initialize sum
int i, count;
for(i=1; i<=x; i++) {
sum = sum + i;
for(count=0; count<10; count++) cout << '.';
cout << "The current sum is " <<
sum << '\n';
}
}
Here is the output produced by the program.
Computing summation of 5.
..........The current sum is 1
..........The current sum is 3
..........The current sum is 6
..........The current sum is 10
..........The current sum is 15
Computing summation of 6.
..........The current sum is 1
..........The current sum is 3
..........The current sum is 6
..........The current sum is 10
..........The
current sum is 15
..........The
current sum is 21
As you can see, each time
total(
) is
called, sum
is
initialized to zero.
No comments:
Post a Comment