» Quick Introduction to C++ » 1. Basics » 1.2 Primitives

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 and unsigned 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 and unsigned 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 (1s) in its binary representation.

Loading...
> code result goes here
Prev
Next