C++ Variables and Types: int, double, char, string, bool

Variables in C++

A C++ variable provides us with a named storage capability. It allows the programmer to manipulate data as per the need. Every variable has a type in C++. The variable type helps to determine the size and layout of the variable’s memory map, the range of values that can be stored within that memory, and the set of operations that can be applied to it.

In this C++ tutorial, you will learn:

Basic types of Variables in C++

Here are the basic types of C++ variables:

Int:

An integer is a numeric literal (associated with numbers) without any fractional or exponential part. Example. 120, -90, etc.

Double:

It is a double-precision floating point value. Example: 11.22, 2.345

Char:

A character literal is created by enclosing a single character inside single quotation marks. For example: ‘a’, ‘m’, ‘F’, ‘P’, ‘}’ etc.

Float:

A floating-point literal is a numeric literal that has either a fractional form or an exponent form. For example: 1.3, 2.6

String Literals:

A string literal is a sequence of characters enclosed in double-quote marks. For example: “How are you?”

Bool:

It holds Boolean value true or false.

Rules of Declaring Variables in C++

Here are some common rules for naming a variable:

  • A C++ variable name can only have alphabets, numbers, and underscore.
  • A C++ variable name cannot begin with a number.
  • Variable names should not begin with an uppercase character.
  • A variable name used in C++ cannot be a keyword. For example, int is a keyword that is used to denote integers.
  • A C++ variable name can start with an underscore. However, it is not considered a good practice.

C++ Variable Data Types

C++ defines a whole set of primitive types

The void type has no associated values with it and can be used in only a few circumstances. It is most commonly as the return type of functions that do not return a value.

The arithmetic types include characters, integers, Boolean values, and floating-point numbers. Arithmetic type if further divided into 2 categories

  1. Floating-point types. The float (or floating type) represent decimal numbers. The IEEE standard specifies a minimum number of significant digits. Most compilers usually provide more precision than the specified minimum. Typically, floats are represented in by 32bits, doubles in 64 bits, and long doubles in either 96 or 128 bits.
  2. Integral types (which include character, integers, and Boolean types). The Boolean type has only two types of values: True or False. There are several char types, most of which exist to support internationalization. The most basic character type is char. A char is the same size as a single machine byte meaning a single byte.

The Integral types may be signed or unsigned.

Signed Type: They represent negative or positive numbers (including zero). In a signed type, the range must be evenly divided between +ve and -ve values. Thus, an 8-bit signed char will hold values from –127 through 127.

Unsigned Type: In an unsigned type, all values are >= 0. An 8-bit unsigned char can contain 0 through 255 (both inclusive).

Variable Name or Identifiers

Identifiers can be composed of some letters, digits, and the underscore character or some combination of them. No limit is imposed on name length.

Identifiers must

  • begin with either a letter or an underscore (‘_’).
  • And are case-sensitive; upper and lowercase letters are distinct:

// defines four different int variables

int guru99, gurU99, GuRu99, GURU99;

The C++ language has reserved some names for its use.

There are many accepted conventions for naming variables in different programming languages. Following these conventions can improve the readability of the program.

  • An identifier should give at least some indication of its meaning.
  • Variable names are usually lowercase—guru99, not Guru99 or GURU99.
  • The classes we define usually begin with an uppercase letter.
  • Identifiers that contain multiple words should visually distinguish every word. For example, guru99_website not guru99website.

C++ Variable Declaration and Definition

A declaration of a variable makes a name known to the program in the scope in which it is defined. Example:

int a=5;
int b;
char c='A'; 
int a,b;
a=b=1000;
List initialization
int a(5);
int b{5};

Const Qualifier in C++

Suppose there is a variable buffsize which states the number of inputs to be taken from the user. Here, we don’t want to change the value of buffsize throughout the program. We want to define a variable whose value we know should not change.

In such case, use the keyword const

const int bufSize = 512;    // input buffer size

This defines bufSize as a constant. Any attempt to assign to or change bufSize gives an error.

Here, we can’t change the value of a const object after we create it, it has to be mandatory be declared and initialized. Otherwise compiler throws an error.

const int i = get_size();  // ok: initialized at run time
const int j = 42;          // ok: initialized at compile time
const int k;               // error: k is uninitialized const
int i = 42;
const int ci = i;    	   // ok: the value in i is copied into ci 

Scope of Variables in C++

A scope is a span of a program where a variable has a meaning. Mostly the same name can be used to refer to different entities within different scopes. Variables are visible from the point where they are declared until the end of the scope in which their declaration appears.

#include <iostream>	
int main()	
{	
    int sum = 0;	
    // sum values from 1 through 10 inclusive	
    for (int val = 1; val <= 10; ++val)	
        sum += val;  // equivalent to sum = sum + val	
    cout << "Sum of 1 to 10 inclusive is "<< sum <<endl;	
    return 0;	
}	 

This program defines 3 names, viz, main, sum, and val. It uses the namespace name std, along with two other names from that namespace—cout and endl.

  • The function name “main” is defined outside the curly braces. The function name main—like most other names defined outside a function—has a global scope. Which means that once declared, names which are at the global scope are accessible throughout the program.
  • The variable sum is defined within the scope of the block which is the body of the main function. It can be accessed from its point of declaration and throughout the rest of the main function’s body. However,not outside of it. This means that variable sum has block scope.
  • The variable val is defined in the scope of “for statement”. It can easily be used in that statement but not elsewhere in the main function. It has local scope.

Nested Scope

The scope can contain other scopes. The contained (or nested) scope is referred to as an inner scope. The containing scope is the outer scope.

#include <iostream>	
using namespace std;	
// Program for illustration purposes only: It is bad style for a function	
// to use a global variable and also define a local variable with the same name	
int reused = 42;  // reused has global scope	
int main()	
{	
    int unique = 0; // unique has block scope	
    // output #1: uses global reused; prints 42 0	
    cout << reused << " " << unique << endl;	
    int reused = 0; // new, local object named reused hides global reused	
    // output #2: uses local reused; prints 0 0	
    cout << reused << " " << unique << endl;	
    // output #3: explicitly requests the global reused; prints 42 0	
    cout << ::reused << " " << unique << endl;	
    return 0;	
}	 

Output #1 appears before the local definition of reused. Thus, this output

statement is the one which uses the name reused that is defined in global scope. This statement outputs

42 0

Output #2 occurs after the local definition of reused. It is now in scope. Therefore, this second output statement simply uses the local object named reused rather than global one and outputs

0 0

Output #3 overrides the default scoping rules using the scope operator. The global scope has no name. Thus, when the scope operator(::) has an empty left-hand side. It interprets it as a request to fetch the name on the right-hand side of the global scope. Thus, the expression uses the global reused and outputs

42 0

Variable Type Conversion

A variable of one type can be converted into another. It is known as “Type Conversion.” Let’s see the rules for converting different C++ variable types:

Assigning of non-bool to a bool variable yields false if the value is 0 and true otherwise.

bool b = 42;            // b is true

Assigning of a bool to one of the other arithmetic types yields 1 if the bool is true and 0 if the bool is false.

bool b = true;
int i = b;              // i has value 1

Assigning a floating-point value to a variable of int type yields the value which is truncated. The value that is stored is the part before the decimal point.

int i = 3.14;               // i has value 3

Assigning of an int value to a variable of float type results in the fractional part becoming zero. Precision is usually lost if the integer has more bits than the floating variable can accommodate.

Int i=3;
double pi = i;          // pi has value 3.0

If we try to assign an out of range value to a variable of unsigned type, the result is the remainder of the value %(modulo)

For example, an 8-bit unsigned char type can hold values from 0 through 255, inclusive. Assigning a value outside this range will result in the compiler assigning the remainder of that value modulo 256. Therefore, by the logic above, assignment of –1 to an 8-bit unsigned char gives that object the value 255.

unsigned char c = -1;   // assuming 8-bit chars, c has value 255

If we try to assign an out-of-range value to an object of signed type, the result is unpredictable. It is undefined. The program might appear to work on the outside, or it might crash, or it might produce garbage values.

signed char c2 = 256;   // assuming 8-bit chars, the value of c2 is undefined

The compiler applies these same type of conversions when we use a value of one type where a value of other type is expected.

int i = 42;
if (i) // condition will evaluate as true
i = 0; 

If this value= 0, then the condition is false; all other (non-zero) values yield true. By the same concept, when we use a bool in an arithmetic expression, its value is always converted to either 0 or 1. As a result, using a bool in an arithmetic expression is usually almost surely incorrect.

Caution: Don’t Mix Signed and Unsigned Types

Expressions that mix signed and unsigned can yield surprising and wrong results when the signed value is negative. As discussed above signed values are automatically converted to unsigned.

For example, in an arithmetic expression like

x* y

If x is -1 and y is 1, and if both x and y are int, then the value is, as expected, -1.

If x is int and y are unsigned, then the value of this expression depends on how many bits an integer has on the compiling machine. On our machine, this expression yields 4294967295.

Register Variables

Registers variables are faster to access compared to memory variables. So, variables which are frequently used in a C++ program can be put in registers using register keyword. The register keyword tells the compiler to store the given variable in a register. It’s compiler’s choice whether to put it in a register or not. Generally, compilers themselves do various optimizations which include putting some of the variables in the register. There is no limit on the number of register variables in a C++ program. But the compiler may not store the variable in a register. This is because register memory is very limited and is most generally used by the OS.

To define:

register int i;

Comments

Comments are the portions of the code ignored by the compiler. It allows the programmer to make notes in the relevant areas of the source code/program. Comments come either in block form or single lines. The program comments are explanatory statements. It can be included in the C++ code which helps anyone reading its source code. All programming languages allow some form of comments. C++ supports both single-line and multi-line comments.

  • Single-line comments are the ones which start with // and continue until the end of the line. If the last character in a comment line is a \ then the comment will continue in the next line.
  • Multi-line comments are the ones which start with /* and end with */.
/* This is a comment */
/* C++ comments can  also 
* span multiple lines 
*/

Escape Sequences

Some characters, such as backspace and control characters, have no visible image. Such characters are known as non-printable characters. Other characters (single and double quotation marks, question mark, and backslash) have special meaning in the many programming languages.

Our programs are not able to use any of these characters directly. Instead, we can use an escape sequence to represent such char. An escape sequence begins with a backslash.

The C++ programming language defines several escape sequences:

What does it do? Character

Newline

\n

Vertical tab

\v

Backslash

\\

Carriage return

\r

Horizontal tab

\t

Backspace

\b

Question mark

\?

Formfeed

\f

Alert (bell)

\a

Double quote

\”

Single quote

\’

We use an escape sequence as if it were a single character:

cout << '\n';        // prints a newline
cout << "\tguru99!\n";   // prints a tab followed by "guru99!" and a newline 

We can also write generalized escape sequences \x followed by one or more hexadecimal digits. Or we use a \ followed by one, or two, or three octal digits. The generalized escape sequence represents the numeric value of the character. Some examples (assuming the Latin-1 char set):

\7 (bell)    \12 (newline)      \40 (blank)
\0 (null)    \115 ('M')         \x4d ('M') 

We can use pre-defined escape sequences, as we are using any other character.

cout << "Hi \x4dO\115!\n";  // prints Hi MOM! followed by a newline
cout << '\115' << '\n';     // prints M followed by a newline 

Summary

  • A C++ variable provides us with a named storage capability.
  • C++ variable types: int, double, char, float, string, bool, etc.
  • The contained (or nested) scope is referred to as an inner scope, and the containing scope is the outer scope.
  • A variable of one type can be converted into another. It is known as “Type Conversion.”
  • Registers variables are faster to access compared to memory variables.
  • Comments are the portions of the code ignored by the compiler.
  • Some characters, such as backspace and control characters, have no visible image.