Primitives
Primitive types in C++ are shown below:
Integer Types
int
: Integer type.short
: Short integer type.long
: Long integer type.long long
: Long long integer type.signed
andunsigned
versions of the above types.
Floating-Point Types
float
: Single-precision floating-point type.double
: Double-precision floating-point type.long double
: Extended-precision floating-point type.
Character Types
char
: Character type.signed char
andunsigned char
: Signed and unsigned character types.
Boolean Type
bool
: Boolean type representing true or false.
Void Type
void
: Represents the absence of a type. Typically used as the return type for functions that do not return a value.
Initialization
int myInt = 42;
short myShort = 123;
long myLong = 123456789L;
long long myLongLong = 1234567890123456789LL;
unsigned int myUnsignedInt = 42u;
unsigned short myUnsignedShort = 123u;
unsigned long myUnsignedLong = 123456789ul;
float myFloat = 3.14f;
double myDouble = 3.14;
long double myLongDouble = 3.14L;
char myChar = 'A';
bool myBool = true;
Integer promotion
If an int
can represent all the values of a smaller integer type (such as char
or short
), the smaller type is converted to int
before performing the operation.
For example:
char c = 'A';
int result = c + 1; // 'A' (char) promoted to int before addition
int i = 5;
float f = 2.5f;
float result = i + f; // int promoted to float before addition
Type Qualifiers
Type qualifiers are keywords that modify the properties of variables or objects.
const
The const
qualifier is used to specify that a variable's value cannot be changed after it has been initialized.
const int x = 5; // x is a constant integer
volatile
The volatile
qualifier indicates that a variable's value may be changed at any time by external forces, such as hardware or other parts of the program.
volatile int sensorValue; // variable may be changed asynchronously (e.g., by hardware interrupts)
mutable
The mutable
qualifier is used with class member variables to indicate that they can be modified even if the containing object is const.
class Example {
public:
mutable int counter; // can be modified even in const member functions
};
restrict
The restrict
qualifier is used in C99 and later versions to indicate that a pointer is the only way to access a particular object during its lifetime, helping the compiler perform certain optimizations.
void exampleFunction(int* restrict a, int* restrict b);
Storage Class specifiers
Storage class specifiers are keywords that define the storage duration, linkage, and scope of variables.
auto
The auto
specifier is used to declare automatic variables. It is rarely used explicitly because the compiler automatically deduces the type of a variable.
auto x = 42; // Compiler deduces the type of x
register
The register
specifier suggests to the compiler that a variable should be stored in a CPU register for faster access.
However, modern compilers often ignore this suggestion as they are efficient in register allocation.
register int count = 0; // Suggests to store 'count' in a register
static
The static
specifier has different meanings based on its context:
- When used with a local variable, it makes the variable retain its value between function calls.
- When used with a global variable, it limits the scope of the variable to the file in which it is declared.
- When used with a function, it specifies internal linkage.
static int globalVar = 10; // Limited to the file scope
void exampleFunction() {
static int localVar = 5; // Retains its value between function calls
}
extern
The extern
specifier is used to declare a variable or function that is defined in another source file. It specifies external linkage.
extern int globalVar; // Declares a global variable defined in another file
extern void externalFunction(); // Declares a function defined in another file
Typedef
The typedef
keyword is used to create an alias or synonym for an existing type.
It helps in making complex type declarations more readable and manageable.
#include <iostream>
typedef int myInt;
int main() {
// Using the typedef alias
myInt x = 42;
std::cout << "Value of x: " << x << std::endl;
return 0;
}
Alternatively, in modern C++ (C++11 and later), you can use the using
keyword for type aliases:
#include <iostream>
using myInt = int;
int main() {
// Using the type alias
myInt x = 42;
std::cout << "Value of x: " << x << std::endl;
return 0;
}
Bitwise Operations
bitwise operations are used to manipulate individual bits of integer values.
The bitwise operators include AND (&
), OR (|
), XOR (^
), NOT (~
), left shift (<<
), and right shift (>>
).
#include <iostream>
int main() {
// Bitwise AND (&)
int a = 5; // binary: 0101
int b = 3; // binary: 0011
int result_and = a & b; // binary: 0001 (1 in decimal)
std::cout << "Bitwise AND: " << result_and << std::endl;
// Bitwise OR (|)
int result_or = a | b; // binary: 0111 (7 in decimal)
std::cout << "Bitwise OR: " << result_or << std::endl;
// Bitwise XOR (^)
int result_xor = a ^ b; // binary: 0110 (6 in decimal)
std::cout << "Bitwise XOR: " << result_xor << std::endl;
// Bitwise NOT (~)
int result_not_a = ~a; // binary: 11111111111111111111111111111010 (assuming 32-bit integer)
std::cout << "Bitwise NOT for a: " << result_not_a << std::endl;
// Left Shift (<<)
int result_left_shift = a << 1; // binary: 1010 (10 in decimal)
std::cout << "Left Shift: " << result_left_shift << std::endl;
// Right Shift (>>)
int result_right_shift = a >> 1; // binary: 0010 (2 in decimal)
std::cout << "Right Shift: " << result_right_shift << std::endl;
return 0;
}
Compound Assignment
Compound assignment operators in C++ combine an arithmetic or bitwise operation with assignment. They provide a concise way to perform an operation and assign the result to a variable.
#include <iostream>
int main() {
int a = 5;
a += 3; // Equivalent to: a = a + 3
std::cout << "a after addition: " << a << std::endl;
a -= 2; // Equivalent to: a = a - 2
std::cout << "a after subtraction: " << a << std::endl;
a *= 4; // Equivalent to: a = a * 4
std::cout << "a after multiplication: " << a << std::endl;
a /= 2; // Equivalent to: a = a / 2
std::cout << "a after division: " << a << std::endl;
a %= 3; // Equivalent to: a = a % 3
std::cout << "a after modulus: " << a << std::endl;
a &= 1; // Equivalent to: a = a & 1
std::cout << "a after bitwise AND: " << a << std::endl;
a |= 8; // Equivalent to: a = a | 8
std::cout << "a after bitwise OR: " << a << std::endl;
a ^= 6; // Equivalent to: a = a ^ 6
std::cout << "a after bitwise XOR: " << a << std::endl;
a <<= 1; // Equivalent to: a = a << 1
std::cout << "a after left shift: " << a << std::endl;
a >>= 2; // Equivalent to: a = a >> 2
std::cout << "a after right shift: " << a << std::endl;
return 0;
}
Code Challenge
Write a function named
countSetBits
that takes an unsigned integer as input and returns the count of set bits (1
s) in its binary representation.