As you learned in the lesson on basic addressing, memory on modern machines is typically organized into byte-sized pieces, with each piece having a unique address. Up to this point, it has been useful to think of memory as a bunch of cubbyholes or mailboxes where we can put and retrieve information, and variables as names for accessing those cubbyholes or mailboxes.
However, this analogy is not quite correct in one regard — most variables actually take up more than 1 byte of memory. Consequently, a single variable may use 2, 4, or even 8 consecutive memory addresses. The amount of memory that a variable uses is based on it’s data type. Fortunately, because we typically access memory through variable names and not memory addresses, the compiler is largely able to hide the details of working with different sized variables from us.
There are several reasons it is useful to know how much memory a variable takes up.
First, the more memory a variable takes up, the more information it can hold. Because each bit can only hold a 0 or a 1, we say that bit can store 2 values. 2 bits can store 4 different values:
|bit 0||bit 1|
3 bits can store 8 values. n bits can store 2^n values. Because a byte is 8 bits, a byte can store 2^8 (256) values.
The size of the variable puts a limit on the amount of information it can store — variables that are bigger can hold larger numbers. We will address this issue further when we get into the different types of variables.
Second, computers have a finite amount of free memory. Every time we declare a variable, a small portion of that free memory is used as long as the variable is in existence. Because modern computers have a lot of memory, this often isn’t a problem, especially if only declaring a few variables. However, for programs that need a large amount of variables (eg. 100,000), the difference between using 1 byte and 8 byte variables can be significant.
The obvious next question is “how much memory do variables of different data types take?”. The size of a given data type is dependent on the compiler and/or the computer architecture. On most 32-bit machines (as of this writing), a char is 1 byte, a bool is 1 byte, a short is 2 bytes, an int is 4 bytes, a long is 4 bytes, a float is 4 bytes, and a double is 8 bytes.
In order to determine the size of data types on a particular machine, C++ provides an operator named sizeof. The sizeof operator is a unary operator that takes either a type or a variable, and returns its size in bytes. You can compile and run the following program to find out how large your data types are:
using namespace std;
cout << "bool:\t\t" << sizeof(bool) << " bytes" << endl;
cout << "char:\t\t" << sizeof(char) << " bytes" << endl;
cout << "wchar_t:\t" << sizeof(wchar_t) << " bytes" << endl;
cout << "short:\t\t" << sizeof(short) << " bytes" << endl;
cout << "int:\t\t" << sizeof(int) << " bytes" << endl;
cout << "long:\t\t" << sizeof(long) << " bytes" << endl;
cout << "float:\t\t" << sizeof(float) << " bytes" << endl;
cout << "double:\t\t" << sizeof(double) << " bytes" << endl;
cout << "long double:\t" << sizeof(long double) << " bytes" << endl;
Here is the output from the author’s Pentium 4 machine, using Visual Studio 2005 Express:
bool: 1 bytes char: 1 bytes wchar_t: 2 bytes short: 2 bytes int: 4 bytes long: 4 bytes float: 4 bytes double: 8 bytes long double: 8 bytes
Your results may vary if you are using a different type of machine, or a different compiler.
If you’re wondering what t is in the above program, it’s a special symbol that inserts a tab. We will cover t and other special symbols when we talk about the char data type.
Interestingly, the sizeof operator is one of only three operators in C++ that is a word instead of a symbol. The other two are new and delete.
You can also use the sizeof operator on a variable name:
cout << "x is " << sizeof(x) << " bytes"<<endl;
x is 4 bytes
Now you know enough about variables that we can start discussing the different data types!
|2.4 — Integers|
|2.2 — Keywords and naming identifiers|