Practicing C C++

Basic Function with Return Value:

int add(int a,  int b) {
  return a + b;
}
int result = add(5, 3);

Reference, address, pointer are vital and fundamental concepts in C and C++! A variable is a named storage location in memory that holds a value. It has a specific data type, which determines what kind of data it can store (e.g., integer, float, character). when you use a reference in C++ (like int& a), you are creating a reference to a variable, not a value.

When you declare a reference using the syntax int& a, you are telling the compiler that a will be a reference to an int variable. This means that a does not have its own memory address; it shares the memory address of the variable it references.

Function with Reference Parameters:

void swap(int& a, int& b) {
  int temp = a;
  a = b;
  b = temp;
}

The C style function is

void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
// Usage: swap(&x, &y);"

to visualize memory view

Before swap:
x: [5]  ◄── a points here
y: [10] ◄── b points here

Step 1: int temp = *a;
x: [5]  ◄── a points here
y: [10] ◄── b points here
temp: [5]

Step 2: *a = *b;
x: [10] ◄── a points here (changed!)
y: [10] ◄── b points here
temp: [5]

Step 3: *b = temp;
x: [10] ◄── a points here
y: [5]  ◄── b points here (changed!)
temp: [5]

Note the key is pointer, a variable in integer to store address, i.e. to point to other variable/address. reference is just alias to make syntax neater, it’s essentially still the concept of pointer. Pointer itself can not be assigned a value.

In the swap function above, the deeper I think, the more it’s simple if you got the gist or fundamental understanding what the problem is and how the computer works: the problem is to swap assignment of two values to two variable, say numbers 3 to a and 4 to b; in computer, variables are address/containers, hence it’s unavoidable we manipulate the address by using pointer (or reference to reduce syntax complexity). hence inputs are two pointers, and when you execute the codes using actual values, you use &a &b, they are what pointers are — addresses! It’s just that simple.

Add on on what “assigning a value” (b = a) really mean in C C++: what happens in memory depends on the types of a and b (e.g., primitive types, pointers, or structures). Here’s an explanation of the key scenarios:

1. For Primitive Data Types (int, float, char, etc.)

  • What Happens:
    The value stored in the memory location of a is copied into the memory location of b. The two variables are now independent; changes to one will not affect the other.
  • Memory Representation:
    If a is stored at address 0x100 with a value of 10, and b is at address 0x104, after b = a, the value 10 is copied into b.

2. For Pointers

  • What Happens:
    The address stored in a (if a is a pointer) is copied into b. After this, both a and b point to the same memory location.
  • Memory Representation:
    If a points to address 0x200 (where the value is 10), and b = a is executed, b will also point to 0x200. Changes to the value at the address affect both pointers.

3. For Arrays

  • What Happens:
    • Arrays in C cannot be assigned directly (e.g., b = a where both are arrays is invalid).

4. For Structures

  • What Happens:
    When b = a is performed and a and b are structures (e.g., struct myStruct), the entire structure is copied. Each field in a is copied to the corresponding field in b.
  • Memory Representation:
    The structure fields are duplicated in memory. Changes to b do not affect a.

Note for structures, Key Points About the Memory Change:

The memory required for the structure is the sum of the sizes of its fields, plus any padding added by the compiler for alignment. For example, if x and y are integers (4 bytes each), the structure uses 8 bytes in memory (not including padding).

Field-by-Field Copy:

During b = a, the data stored in each field of a is copied to the corresponding field in b.

This is done automatically by the compiler, so you don’t need to manually copy each field.

Independent Memory:

b gets its own memory allocation for its fields (b.x and b.y), distinct from a.

Modifying b.x or b.y does not alter a.x or a.y because they reside at separate memory addresses.

Size of the Structure:

The memory required for the structure is the sum of the sizes of its fields, plus any padding added by the compiler for alignment. For example, if x and y are integers (4 bytes each), the structure uses 8 bytes in memory (not including padding).

So now it’s become more and more crystal clear why swap function can be written literally and comprehensively using pointer and if use reference, the syntax become much cleaner, but to the level of understanding swap using reference, it’s simple,

void swap(int& a, int& b) {
  int temp = a;
  a = b;
  b = temp;
}

a and b are passed in as alias, i.e. reference to x and y (x and y be assigned, i.e. be allocated memory and given integer values respectively in the main function), since they are alias, they are called in such way but the memory addresses are not newly created, still pointing to the x and y. Within body of function, you can directly do the swapping (no need to specify pointer, dereference etc. in the comprehensive version of swap function) and return the same as using the comprehensive swap function.

Referencing provides a great syntax sugar coated the codes neat and clean to look at.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.