Pointer Arithmetic & Const Correctness

পয়েন্টার arithmetic ও const correctness

Read: ~35 min 18 practice problems

1. Pointer Arithmetic Is Type-Sized

p + 1 doesn't add 1 byte — it adds sizeof(*p) bytes. So an int* increments by 4, a double* by 8.

p + 1-এর অর্থ হলো p + sizeof(*p) বাইট এগিয়ে যাওয়া। অর্থাৎ pointer-এর ধরন অনুযায়ী এক ধাপ-এর আকার নির্ধারিত হয়।
arith.cpp
#include <iostream>

int main() {
    int a[] = {10, 20, 30, 40};
    int* p = a;

    std::cout << *p     << "\n"; // 10
    std::cout << *(p+1) << "\n"; // 20
    std::cout << p[2]   << "\n"; // 30  (p[i] == *(p+i))
    std::cout << (p+1) - p << "\n"; // 1 (not 4!)
}

2. Arrays Decay to Pointers

When you pass an array to a function, it silently becomes a pointer to its first element. Size info is lost. This is one major reason to prefer std::vector or std::array.

decay.cpp
#include <iostream>

void f(int arr[]) {
    std::cout << sizeof(arr) << "\n"; // 8 (a pointer!), not 20
}

int main() {
    int a[5] = {1,2,3,4,5};
    std::cout << sizeof(a) << "\n";   // 20
    f(a);
}

3. const Placement — Three Variants

DeclarationMeaning
const int* pPointer to const int — cannot modify *p, but can change p.
int const* pSame as above (const binds to int).
int* const pConst pointer — cannot change p, but can modify *p.
const int* const pBoth fixed. Cannot change p nor *p.
Rule of thumb (read right-to-left) const int* p = "p is a pointer to int that is const". int* const p = "p is a const pointer to int".

4. Const Correctness

Mark anything that doesn't change as const. The compiler enforces it; readers benefit.

correct.cpp
#include <iostream>
#include <string>

// "I won't modify s. The reader knows."
size_t countA(const std::string& s) {
    size_t c = 0;
    for (char ch : s) if (ch == 'a') ++c;
    return c;
}

int main() {
    std::string s = "banana";
    std::cout << countA(s) << "\n";
}

5. Reading Complex Declarations

Read right-to-left, and group by parens:

DeclarationMeaning
int* p[10]Array of 10 pointers to int
int (*p)[10]Pointer to an array of 10 ints
int* f()Function returning int*
int (*f)()Pointer to function returning int

6. Practice Problems

  1. Given int a[]={1,2,3,4,5}; int* p=a;, what is *(p+3)?
    ✨ Show Answer

    4 (a[3]).

  2. Are p[2] and *(p+2) equivalent?
    ✨ Show Answer

    Yes, by definition.

  3. If p is double*, by how many bytes does p+1 advance?
    ✨ Show Answer

    8 bytes (sizeof double).

  4. Read: const int* p
    ✨ Show Answer

    Pointer to a const int. Can change which int p points to, but can't modify the int through p.

  5. Read: int* const p
    ✨ Show Answer

    Const pointer to int. The pointer itself can't be changed, but the int can.

  6. Why does sizeof differ inside a function vs outside?
    ✨ Show Answer

    Arrays decay to pointers when passed. Inside the function, you have a pointer; sizeof gives pointer size (8 on 64-bit), not array size.

  7. Use a pointer to iterate an array of 5 ints.
    ✨ Show Answer
    int a[] = {1,2,3,4,5};
    for (int* p = a; p < a + 5; ++p) std::cout << *p << " ";
  8. Write a function with signature void print(const int* arr, size_t n).
    ✨ Show Answer
    void print(const int* arr, size_t n) {
        for (size_t i = 0; i < n; ++i) std::cout << arr[i] << " ";
    }
  9. What's const char* good for?
    ✨ Show Answer

    String literals: const char* msg = "hello";. The literal lives in read-only memory; modifying it is UB.

  10. Why must member functions be marked const when they don't modify state?
    ✨ Show Answer

    So you can call them on const objects. Without the const-qualifier, calling on a const object fails to compile.

  11. Difference between const int* p and int const* p?
    ✨ Show Answer

    None. Both: pointer to const int.

  12. Can you have a const int* const p?
    ✨ Show Answer

    Yes. Both target and pointer are const. Useful for "fixed pointer to fixed data".

  13. Show that const-cast can strip const (and is dangerous).
    ✨ Show Answer
    const int x = 5;
    int* p = const_cast<int*>(&x);
    *p = 10; // UB if x was originally const

    Don't do this except for legacy C-API interop.

  14. What's the result of p2 - p1 for two pointers into the same array?
    ✨ Show Answer

    The number of elements between them, not bytes. Type: std::ptrdiff_t.

  15. Read: void (*pf)(int)
    ✨ Show Answer

    Pointer to a function taking int and returning void.

  16. Why is iterating with begin()/end() better than raw pointers?
    ✨ Show Answer

    Iterators work for any container (vector, list, map, ...). Raw pointer iteration only works for arrays/vectors. Iterators integrate with STL algorithms.

  17. Can you increment a const int*?
    ✨ Show Answer

    Yes. The pointer itself isn't const, only what it points to. p++ is allowed.

  18. Write a const-correct function that returns the length of a C-string.
    ✨ Show Answer
    size_t strlen_my(const char* s) {
        size_t n = 0;
        while (*s++) ++n;
        return n;
    }

Summary

Pointer arithmetic moves in type-sized steps. Arrays decay to pointers when passed — losing size info. Read declarations right-to-left to decode const: const T* = pointer to const, T* const = const pointer. Be aggressively const-correct; the compiler will help you.

Next Module → Strings: std::string and string_view.