C++

More on Handling Basic Data Types

Have you ever wanted to learn how basic types of C++ variables interact in complex situations? Ivor Horton explains this, and also describes some interesting features of C++. This article is from chapter 3 of Ivor Horton's Beginning ANSC C++ The Complete Language (Apress, 2004; ISBN 1590592271).

You saw in Chapter 1 that programs can consist of several source files and most programs of any size will generally do so. If you have a program that consists of more than one source file, you may need to access a global variable from one source file that is declared in another. The extern keyword allows you to do this. Suppose you have one program file that contains the following:

// File1.cppint shared_value = 100;// Other program code …

If you have code in another file that needs to access the shared_value variable, you can arrange for this as follows:

The first statement in File2.cpp declares shared_value to be external, so this is only a declaration, not a definition. The reference to shared_value in main() is then to the variable defined in the first file, File1.cpp.

You must not use an initializing value when declaring an external variable. If in the second file you wrote

extern int shared_value = 0; // Wrong! Not an external declaration.

the variable would be defined locally, and the extern declaration would be ignored.

Precedence and Associativity

You have accumulated quite a number of new operators in this chapter. Table 3-4 summarizes the precedence and associativity of the operators you’ve seen so far.

Table 3-4. Operator Precedence and Associativity

Operator

Associativity

static_cast<>()

right

Postfix ++

Postfix -

Unary +

right

Unary

Prefix ++

Prefix -

~

* / %

left

Binary +

left

Binary

<< >>

left

&

left

^

left

|

left

= op=

right

The operators in Table 3-4 appear in sequence from highest precedence to lowest, and each group in the table contains operators that have the same precedence. The sequence of execution of operators with the same precedence in an expression is determined from their associativity. As I mentioned previously, a table showing the precedence of all the C++ operators appears in Appendix D.

Summary

In this chapter, you learned some of the more complicated aspects of computation in C++. You also learned a little about how you can define data types of your own, although what you’ve seen here has nothing to do with the ability to define completely general types that I discuss in Chapter 11. The essentials of what you’ve learned in this chapter are as follows:

You can mix different types of variables and constants in an expression. The compiler will arrange for variables to be automatically converted to an appropriate type where necessary.

Automatic conversion of the type of the right side of an assignment to that of the left side will also be made where these are different. This can cause loss of information when the left-side type isn’t able to contain the same information as the right-side type—double converted to int, for example, or long converted to short.

You can explicitly convert a value of one basic type to another by using static_cast<>().

By default, a variable declared within a block is automatic, which means that it only exists from the point at which it is declared to the end of the block in which its declaration appears, as indicated by the closing brace of the block that encloses its declaration.

A variable may be declared as static, in which case it continues to exist for the life of the program. However, it can only be accessed within the scope in which it was defined. If you don’t initialize a static variable explicitly, it will be initialized to 0 by default.

Variables can be declared outside of all the blocks within a program, in which case they have global namespace scope and static storage duration by default. Variables with global scope are accessible from anywhere within the program file that contains them, following the point at which they’re declared, except where a local variable exists with the same name as the global variable. Even then, they can still be reached by using the scope resolution operator (::).

The keyword typedef allows you to define synonyms for other types.

The extern keyword allows you to reference a global variable defined in another file.

Exercises

The following exercises enable you to try out what you’ve learned in this chapter. If you get stuck, look back over the chapter for help. If you’re still stuck, you can download the solutions from the Downloads area of the Apress website (http://www.apress.com), but that really should be a last resort.

Exercise 3-1. Write a program that calculates the reciprocal of a nonzero integer entered by the user. (The reciprocal of an integer, n, is 1/n.) The program should store the result of the calculation in a variable of type double and then output it.

Exercise 3-2. Create a program that prompts the user to input an integer in decimal form. Then, invert the last bit of its binary representation. That is, if the last bit is 1, then change it to 0, and vice versa. The result should then be displayed as a decimal number. How does the adjustment affect the resulting integer value? (Hint: Use a bitwise operator.)

Exercise 3-3. Write a program to calculate how many square boxes can be contained in a single layer on a rectangular shelf, with no overhang. Use variables of type double for the length and depth of the shelf (in feet) and for the length of one side of a single box (in inches) and read values for these from the keyboard. You’ll need to declare and initialize a constant to convert from feet to inches. Use a single statement to calculate the number of boxes that the shelf can hold in a single layer, assigning the answer to a variable of type long.

Exercise 3-4. Without running it, can you work out what the following code snippet will produce?

Exercise 3-5. Write a program to read four characters from the keyboard and pack them into a single 4-byte integer variable. Display the value of this variable as hexadecimal. Unpack the 4 bytes of the variable and output them in reverse order, with the low-order byte first.

This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN 1590592271). Check it out at your favorite bookstore today. Buy this book now.

DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.