These are some of the key words used in the language. This is not a comprehensive list.
Elementary Types of Variables
bool
This can have exactly 2 values, true and false. These are stored internally as 1 and 0. In practice, numeric values can also be interpreted as true (nonzero) or false (0), but bool is intended for the purpose.
char
This holds one character, normally stored as a signed 1-byte value by the ASCII encoding scheme. In theory, this may be stored as some other number of bits and may represent only the basic first 128 ASCII values.
A "char" variable may also be "signed" or "unsigned". A "char" variable can also be regarded as a 1-byte integer, which thus could be signed or unsigned.
wchar
This is like char (a "wide character") but is stored in 2 bytes, typically using Unicode.
int
This holds an integer value, normally stored as a 4-byte binary value, compiler-dependent. Some compilers may use other sizes.
An "int" variable may also be "signed" (the default) or "unsigned." In the latter case, it is stored as an unsigned binary value of the same size.
In general, sizeof(short int) <= sizeof(int) <= sizeof(long int).
long int
This holds an integer value with a range always at least as large as an "int" and perhaps using twice as many bytes. This is also known as just "long".
A "long int" variable may also be "signed" (the default) or "unsigned." In the latter case, it is stored as an unsigned binary value of the same size.
short int
This holds an integer value with a range no larger than an "int". This is also known as "short".
A "short int" variable may also be "signed" (the default) or "unsigned." In the latter case, it is stored as an unsigned binary value of the same size.
Note: An "int" may be the same size as a "short int" or the same size as a "long int" or the three sizes may be distinct.
float
This holds a floating-point value, stored typically as 4 bytes or 8 bytes, compiler-dependent.
double
This holds a floating-point value with a range always at least as large as a "float" and perhaps using twice as many bytes. The term "long float" has sometimes been used as a synonym for "double" but is out of favor.
long double
This holds a floating-point value with a range always at least as large as a "double" and perhaps using twice as many bytes.
Note: A "double" may be the same size as a "float" or the same size as a "long double" or the three sizes may be distinct.
In general, sizeof(float) <= sizeof(double) <= sizeof(long double).
signed
unsigned
These are modifiers that can be used with "int", "short int", and "long int". The default is "signed". An unsigned int cannot have negative values and has a double-size range of positive values.
* (pointer to)
When we have an asterisk between a variable's name and a type, the variable is not of that type but is rather a pointer to that type. That is, if we declare "char * S", S will be a pointer to something of type "char".
We can also have pointers of type "void *"; for instance, the "malloc" function returns this type. Its use is to be recast as some other type of pointer. Pointer arithmetic will probably not work with a pointer of type void *.
void
A function may be declared as of type "void" to indicate that it does not return any value.
A function that is not declared as being of any type is of type "int" by default. (This is a poor practice and may be rejected by the compiler.)
void *
This is a "pointer to void" and usually makes sense only if we are casting a void * pointer to be a pointer to some other type. This does happen and is useful; for instance, the "malloc" function returns this type.
Other terms used in declarations
auto
This is used only in declaring variables at the heads of blocks. The variables will have local (automatic) extent, i.e., its scope is that block. This is the default, so "auto" is rarely used.
const
This indicates that an identifier will be a constant. If we use "int const A = 3" or "const int A = 3", the value of A cannot easily be changed later. If the explicit type is omitted, as in "const A", the type is assumed to be "int". (This is a poor practice and may be rejected by the compiler.)
Normally a "const" declaration is accompanied by assigning an initial value. (Otherwise it is useless. The compiler may be smart enough to catch this error.)
It is also possible to have a "pointer to const", as in "const int * P", in which case the value of P can be changed, but the value of *P cannot be changed (at least not by referring to *P). This is different from a constant pointer, as in "int * const P", where P is a constant but *P can be changed (as in "*P = 2").
Reference arguments of functions can also be declared as const, in which case the function cannot change their values even though they are references.
If a data member of a class is defined as "static const", then we have a constant that belongs to the class. (The alternative would be a global #define.)
Also see the separate web page on the term "const".
static
This is used to indicate that storage for a variable should be allocated when a function's execution begins and should persist until the overall program terminates. Thus, for instance, a static variable in a function will retain its value from one call to the next. This is called "static extent".
If a global variable is declared as static, it can be used only within the file in which it is declared. We could legally have two variables of the same name, each a global static variable in its own file.
If a data member in a class is declared as static, then this data member exists just once for the whole class, rather than once for each instance. If a data member is static, we can access it using classname::membername.
If a method of a class is declared as static, then it can be invoked using classname::methodname() without referring to a specific instance of the class.
Also see the separate web page in the term "static".
extern
This is used to make an identifier (the name of a function or global variable) visible and hence usable outside the file in which it is defined. Thus, if Var1 is defined as an int in FileA and I want to use it in FileB, I need to include the line
extern int Var1;
in FileB.
Also see the separate web page on the term "extern".
register
This is essentially equivalent to "auto" but also indicates that the variable will be heavily used and hence should be managed accordingly by the compiler. (It is quite possible this will be ignored.)
Terms used in defining new types
enum
We can define a type of variable that has only a specific list of possible values, as in:
enum Suit { spades, hearts, diamonds, clubs } MySuit;
where MySuit is declared as a variable of type "Suit". We could define more variables of type "Suit":
enum Suit YourSuit;
An enumerated type is stored as an integer; in the above example, spades = 0, etc. We could specify our own values for the values, as in:
enum Suit { spades = 12, hearts = 8, diamonds = 4, clubs = 0 };
We could recover the integer value of "hearts", for instance, by recasting YourSuit as an int.
struct
We can define a multi-component record type with "struct", as in
struct Bag { int A; float B; } MyBag;
where MyBag is declared as a variable of type "Bag". We could define more variables of type "Bag":
struct Bag YourBag;
We can refer to the fields in MyBag as "MyBag.A" and "MyBag.B".
We can have arrays of Bag, pointers to Bag, etc.
union
With this, we can store several kinds of data in the same type. For instance:
union Item { long int A; char B; } MyItem;
where MyItem is declared as a variable of type "Item". We could define more variables of type "Item":
union Item YourItem;
Here MyItem has enough space to hold either a "long int" value or a "char" value, but not both; the size is exactly enough to hold the largest of the fields listed.
We can refer to the fields in MyItem as "MyItem.A" and "MyItem.B".
typedef
This is essentially an alias mechanism used to add a user-defined name for some type of variable defined with "enum" or "struct" or "union", etc. For example:
typedef unsigned long int BigInt; typedef enum { spades, hearts, diamonds, clubs } Suit; BigInt X; Suit MySuit;
where we do not now need "enum" before "Suit".
References
Reference Arguments
If we want to pass a variable as an argument to a function so the function will be able to change the variable's value, we can pass it as a "reference argument". To do so, prefix the name of the formal arguments in the list of formal arguments with '&', as in:
void AddOne(int & A) { A++; }
This can be combined with const to have constant reference arguments.
The advantage of reference arguments is that a copy need not be made at execution time, and thus execution may be faster and use less memory.
Many people prefer the use of reference arguments and make them constant when possible.
Reference Variables
A reference variable is an alternative name for a variable. To create a reference variable, prefix its name in the variable declaration with '&', and initialize it as = another variable. For instance:
int I = 3; int & J = I;
Now J and I are names associated with the same storage. If we change I, we are also changing J, and vice versa. Notice that we could not write:
int & K = 3;
as K is a variable; however
const int & K = 3;
will be accepted.
The identification of a reference variable with a non-reference value cannot be changed. In the above example, if we also have
int P = 5;
then neither of these will work:
J = P; K = 5;