Pages

Friday, April 22, 2016

C++ - Declaring Variables Constantly

C++ - Declaring Variables Constantly



In This Tutorial

• Declaring variables
• Declaring different types of variables 
• Using floating-point variables
• Declaring and using other variable types


The most fundamental of all concepts in C++ is the variable — a variable is like a small box. You can store things in the box for later use, particularly numbers. The concept of a variable is borrowed from mathematics. A statement such as.

x = 1

stores the value 1 in the variable x. From that point forward, the mathematician can use the variable x in place of the constant 1 — until she changes the value of x to something else. 

Variables work the same way in C++. You can make the assignment.

x = 1;

From that point forward in the program, until the value of x is changed, any references to x are the same as referencing 1. That is, the value of x is 1.

Unfortunately, C++ has a few more concerns about variables than the mathematician does. This chapter deals with the care and feeding of variables in C++.

Declaring Variables
C++ saves numeric values in small storage boxes known as variables. Mathematicians throw variables around with abandon. A mathematician might (for example) write down something like the following:

(x + 2) = y / 2
x + 4 = y
solve for x and y

Any reader who’s had algebra realizes right off that the mathematician has introduced the variables x and y. But C++ isn’t that smart (computers may be fast, but they’re stupid).

You have to announce each variable to C++ before you can use it. You have to say something soothing like this

int x;
x = 10;

int y;                                                            
y = 5;

These lines of code declare that a variable x exists, that it is of type int, and that a variable y of type int also exists. (The next section discusses variable types.) You can declare variables (almost) anywhere you want in your program — as long as you declare the variable before you use it.

Declaring Different Types of Variables
If you’re on friendly terms with math (hey, aren’t we all?), you probably think of a variable in mathematics as an amorphous box capable of holding whatever you might choose to store in it. You might easily write something like the following:

x = 1
x = 2.3
x = "this is a sentence"
x = Texas

Alas, C++ is not that flexible. (On the other hand, C++ can do things that people can’t do, such as add a billion numbers or so in a second, so let’s not get too uppity.) To C++, there are different types of variables just as there are different types of storage bins. Some storage bins are so small that they can only handle a single number. It takes a larger bin to handle a sentence. Of course, no bin is large enough to hold Texas (maybe Rhode Island or Delaware).

You have to tell C++ what size bin you need before you can use a C++ variable. In addition, different types of variables have different properties. So far, you have only seen the int type of variable in this chapter:

int x;
x = 1;

The variable type int is the C++ equivalent of an integer — a number that has no fractional part. (Integers are also known as counting numbers or whole numbers.)

Integers are great for most calculations. You can make it up through most (if not all) of elementary school with integers. It isn’t until you reach age 11 or so that they start mucking up the waters with fractions. The same is true in C++: More than 90 percent of all variables in C++ are declared to be of type int.

Unfortunately, int variables don’t always work properly in a program. If (for example) you worked through the temperature-conversion program in Chapter 1, the program has a potential problem — it can only handle integer temperatures — whole numbers that don’t have a fractional part. This limitation of using only integers doesn’t affect daily use because it isn’t likely that someone (other than a meteorologist) would get all excited about entering a fractional temperature (such as 10.5 degrees). The lurking problem is not at all obvious: The conversion program lops off the fractional portion of temperatures that it calculates, and just keeps going without complaint. This can result in a lapse of accuracy that can be serious — for example, you wouldn’t want to come up a half mile short of the runway on your next airplane trip due to a navigational round-off.

Reviewing the limitations of integers in C++ 
The int variable type is the C++ version of an integer. int variables suffer the same limitations as their counting-number integer equivalents in math do.

Integer round-off
Consider the problem of calculating the average of three numbers. Given three int variables — nValue1, nValue2, and nValue3 — an equation for calculating the average is

int nAverage;
int nValue1;
int nValue2;
int nValue3;
nAverage = (nValue1 + nValue2 + nValue3) / 3;

Because all three values are integers, the sum is assumed to be an integer. Given the values 1, 2, and 2, the sum is 5. Divide that by 3, and you get 12⁄3, or 1.666. Given that all three variables nValue1, nValue2, and nValue3 are integers, the sum is also assumed to be an integer. The result of the division is also an integer. The resulting value of nAverage is unreasonable but logical: 1.

Lopping off the fractional part of a number is called truncation, or rounding off. For many applications, truncation isn’t a big deal. Some folks might consider its results reasonable (not mathematicians or bookies, of course), but integer truncation can create math mayhem in computer programs. Consider the following equivalent formulation:

int nAverage;
int nValue1;
int nValue2;
int nValue3;
nAverage = nValue1/3 + nValue2/3 + nValue3/3;

Plugging in the same 1, 2, and 2 values, the resulting value of nAverage is (talk about logical-but-unreasonable) 0. To see how this can occur, consider that 13 truncates to 0, 23 truncates to 0, and 23 truncates to 0. The sum of 0, 0, and 0 is zero. (Sort of like that old song: “Nothing from nothing leaves nothing, ya gotta be something . . .”) You can see that integer truncation can be completely unacceptable.

Limited range
A second problem with the int variable type is its limited range. A normal int variable can store a maximum value of 2,147,483,647 and a minimum value of –2,147,483,648 — roughly from positive 2 billion to negative 2 billion, for a total range of about 4 billion.

Tip:
Two billion is a very large number: plenty big enough for most uses. But it’s not large enough for some applications — for example, computer technology. In fact, your computer probably executes faster than 2 gigahertz, depending upon how old your computer is. (Giga is the prefix meaning billion.) A single strand of communications fiber — the kind that’s been strung from one end of the country to the other — can handle way more than 2 billion bits per second.

C++ offers a little help by allowing you declare an integer to be unsigned, meaning that it cannot be negative. An unsigned int value type can represent a number from 0 to 4,294,967,295, should the need arise for some unimaginable reason.

Tip:
You can declare a variable simply unsigned. The int is implied.

Solving the truncation problem 
The limitations of int variables can be unacceptable in some applications. Fortunately, C++ understands decimal numbers. A decimal number can have a nonzero fractional part. (Mathematicians also call those real numbers.) Decimal numbers avoid many of the limitations of int type integers. Notice that a decimal number “can have” a nonzero fractional part. In C++, the number 1.0 is just as much a decimal number as 1.5. The equivalent integer is written simply as 1. Decimals numbers can also be negative, like –2.3.

When you declare variables in C++ that are decimal numbers, you identify them as double precision floating-point values. (Yes, there is such a critter as a “single precision floating-point variable,” but stick with me here.) The term floating-point means the decimal point is allowed to float back and forth, identifying as many “decimal places” as necessary to express the value. Floatingpoint variables are declared in the same way as int variables:

double dValue1;

From this point forward, the variable dValue1 is declared to be a double. Once declared, you cannot change the type of a variable. dValue1 is now a double and will be a double for the remainder of its natural instructions. To see how floating-point numbers fix the truncation problem inherent with integers, convert all the int variables to double. Here’s what you get:

double dValue;
dValue = 1.0/3.0 + 2.0/3.0 + 2.0/3.0;

is equivalent to 

dValue = 0.333... + 0.666... + 0.666...;

which results in the value 

dValue = 1.666...;

Warning:
I have written the value 1.6666 . . . as if the number of trailing 6s goes on forever. This is (not necessarily) the case. There’s a limit to the number of digits of accuracy of a double variable — but it’s a lot more than I can keep track of.

Looking at the limits of floating-point numbers
Although floating-point variables can solve many calculation problems such as truncation, they have some limitations themselves — in effect, the reverse of those associated with integer variables. double variables can’t be used as counting numbers, they’re more difficult for the computer to handle, and they also suffer from round-off error (though not nearly to the same degree as int variables).

Counting
You cannot use floating-point variables in applications where counting is important. This includes C++ constructs, which requires counting ability. C++ can’t verify which whole number value is meant by a given floating-point number.

For example, it’s clear that 1.0 is 1. But what about 0.9 or 1.1? Should these also be considered as 1? C++ simply avoids the problem by insisting on using int values when counting is involved.

Calculation speed 
Historically, a computer processor can process integer arithmetic quicker than it can floating-point arithmetic. Thus, while a processor can add 1 million integer numbers in a given amount of time, the same processor may be able to perform only 200,000 floating-point calculations during the same period. (Not surprisingly, I couldn’t even get around to reading the first value.)

Calculation speed is becoming less of a problem as microprocessors increase their capabilities. Most modern processors contain special calculation circuitry for performing floating-point calculations almost as fast as integer calculations.

Loss of accuracy 
Floating-point variables cannot solve all computational problems. Floatingpoint variables have a limited precision of about 6 digits — an extra-economy size, double-strength version of float can handle some 15 significant digits with room left over for lunch.

To evaluate the problem, consider that 13 is expressed as 0.333 . . . in a continuing sequence. The concept of an infinite series makes sense in math, but not to a computer. The computer has a finite accuracy. Average 1, 2, and 2 (for example), and you get 1.666667.

C++ can correct for many forms of round-off error. For example, in output, C++ can determine that instead of 0.999999, that the user really meant 1. In other cases, even C++ cannot correct for round-off error.

Not-so-limited range 
Although the double data type has a range much larger than that of an integer, it’s still limited. The maximum value for an int is a skosh more than 2 billion. The maximum value of a double variable is roughly 10 to the 38th power. That’s 1 followed by 38 zeroes; it eats 2 billion for breakfast. (It’s even more than the national debt, at least at the time of this writing.)

Warning:
Only the first 13 digits or so have any meaning; the remaining 25 digits suffer from floating-point round-off error.

Declaring Variable Types
So far this chapter has been trumpeting that variables must be declared and that they must be assigned a type. Fortunately (ta-dah!), C++ provides a number of different variable types. See Table 2-1 for a list of variables, their advantages, and limitations.

C++ Variables 


It may seem odd that the standard floating length variable is called double while the “off size” is float. In days gone by, memory was an expensive asset — you could reap significant space savings by using a float variable. This is no longer the case. That, combined with the fact that modern processors perform double precision calculations at the same speed as float, makes the double the default. Bigger is better, after all.

The following statement declares a variable lVariable as type long and sets it equal to the value 1, while dVariable is a double set to the value 1.0:

// declare a variable and set it to 1
long lVariable;
lVariable = 1;

// declare a variable of type double and set it to 1.0
double dVariable;
dVariable = 1.0;

Tip:
You can declare a variable and initialize it in the same statement:

int nVariable = 1;     // declare a variable and
                       // initialize it to 1

Although such declarations are common, the only benefit to initializing a variable in the declaration is that it saves typing.

A char variable can hold a single character; a string (which isn’t really a variable but works like one for most purposes) holds a string of characters. Thus, ‘C’ is a char that contains the character C, whereas “C” is a string with one character in it. A rough analogy is that a ‘C’ corresponds to a nail in your hand, whereas “C” corresponds to a nail gun with one nail left in the magazine. (Chapter 9 describes strings in detail.)

Warning:
If an application requires a string, you’ve gotta provide one, even if the string contains only a single character. Providing nothing but the character just won’t do the job.

Types of constants
A constant is an explicit number or character (such as 1, 0.5, or ‘c’) that doesn’t change. As with variables, every constant has a type. In an expression such as n = 1; (for example), the constant 1 is an int. To make 1 a long integer, write the statement as n = 1L;. The analogy is as follows: 1 represents a single ball in the bed of a pickup truck, whereas 1L is a single ball in the bed of a dump truck. The ball is the same, but the capacity of its container is much larger.

Following the int to long comparison, 1.0 represents the value 1, but in a floating-point container. Notice, however, that the default for floating-point constants is double. Thus, 1.0 is a double number and not a float.

Warning:
true is a constant of type bool. However, “true” (note the quotation marks) is a string of characters that spell out the word true. In addition, in keeping with C++’s attention to case, true is a constant, but TRUE has no meaning.

Special characters
You can store any printable character you want in a char or string variable. You can also store a set of non-printable characters that is used as character constants. See Table 2-2 for a description of these important nonprintable characters.


You have already seen the newline character at the end of strings. This character breaks a string and puts the parts on separate lines. A newline character may appear anywhere within a string. For example,

"This is line 1\nThis is line 2"                                    

appears on the output as

This is line 1                                                      
This is line 2                                                      

Similarly, the \t tab character moves output to the next tab position. (This position can vary, depending on the type of computer you’re using to run the program.) Because the backslash character is used to signify special characters, a character pair for the backslash itself is required. The character pair \\ represents the backslash.



Are These Calculations Really Logical?
C++ provides a logical variable called bool. The type bool comes from Boolean, the last name of the inventor of the logical calculus. There are two values for a boolean variable: true and false.

Tip:
There are actually calculations that result in the value bool. For example, “x is equal to y” is either true or false.

Mixed Mode Expressions
C++ allows you to mix variable types in a single expression. That is, you are allowed to add an integer with a double precision floating-point value. In the following expression, for example, nValue1 is allowed to be an int:

// in the following expression the value of nValue1
// is converted into a double before performing the
// assignment int
nValue1 = 1;
nValue1 + 1.0;

An expression in which the two operands are not the same type is called a mixed-mode expression. Mixed-mode expressions generate a value whose type is equal to the more capable of the two operands. In this case, nValue1 is converted to a double before the calculation proceeds. Similarly, an expression of one type may be assigned to a variable of a different type, as in the following statement:

// in the following assignment, the whole
// number part of fVariable is stored into nVariable
double dVariable = 1.0;
int nVariable;
nVariable = dVariable;

Warning:
You can lose precision or range if the variable on the left side of the assignment is smaller. In the previous example, C++ truncates the value of before storing it in nVariable.

Converting a larger value type into a smaller value type is called demotion, whereas converting values in the opposite direction is known as promotion. Programmers say that the value of int variable nVariable1 is promoted to a double as expressions such as the following:

int nVariable1 = 1;
double dVariable = nVariable1;


Tip:
Mixed-mode expressions are not a good idea. Avoid forcing C++ to do your conversions for you. 

0 comments:

Post a Comment