1. Pointer Reference Increment

Write two C++ functions that increment an integer value using two different parameter-passing techniques commonly used in embedded and firmware development:

  1. void incrementPtr(int* x)
     Increments the value pointed to by x.
     If x is nullptr, the function must do nothing.
  2. void incrementRef(int& x)
     Increments the referenced value x.

The program reads an integer from standard input, calls both functions separately, and prints the results.

You only need to implement the two functions.
The main() function is provided and must not be modified.

Assumptions:

  • The input value fits within the range of int
  • Overflow behavior is not tested 

 

Example 1

Input

5

Output

After incrementPtr: 6
After incrementRef: 6

 

Example 2

Input

0

Output

After incrementPtr: 1
After incrementRef: 1

 

 

 

Need Help? Refer to the Quick Guide below

A Reference in C++ is an alias (an alternative name) for an existing variable.

Unlike a pointer, which holds a memory address and can be NULL, a reference must be initialized to a valid object and cannot be changed to refer to a different object later.

Think of it as a const pointer that is automatically dereferenced for you.

Syntax & Usage

1. Basic Declaration

int x = 10;
int &ref = x;  // 'ref' is now an alias for 'x'

ref = 20;      // Modifies 'x' directly
// x is now 20

2. Pass-by-Reference (Function Parameters)

In C, to modify a variable inside a function, you pass a pointer. In C++, you pass a reference.

C Style (Pointers)C++ Style (References)

void update(int *val) {
  *val = 50;
}

void update(int &val) {
  val = 50;
}
Call: update(&x);Call: update(x);

3. const Reference (Read-Only Access)

Used to pass large objects (like structs or buffers) efficiently without copying them and without allowing modification.

struct SensorData {
    float x, y, z;
    uint32_t timestamp;
};

// Efficient: No copy created, but strictly Read-Only
void processData(const SensorData &data) {
    // data.x = 0;  // ❌ Error: Read-only
    printf("%f", data.x); // ✅ OK
}

Pointer vs. Reference (Crucial for Embedded)

FeaturePointer (int*)Reference (int&)
NullabilityCan be NULL (needs checking).Cannot be NULL (always valid).
ReassignmentCan point to different addresses.Bound to one object forever.
Memory AddressHas its own address on stack.Shares address of the target.
SyntaxRequires * to access value.Accessed like a normal variable.
Embedded UseLow-level hardware/buffer access.High-level APIs and safety.

Relevance in Embedded/Firmware

1. Efficient Driver APIs

Passing hardware driver objects (like UART or SPI classes) by value copies the entire object, which breaks register mappings. Passing by pointer creates messy syntax (->). References offer the best of both:

// Clean syntax, no copying, no NULL checks needed
void generic_log(UART_Driver &uart, const char *msg) {
    uart.send(msg);
}

2. Operator Overloading

References are mandatory for operator overloading (e.g., operator=, operator[]), which allows you to treat hardware buffers like standard arrays.

3. Range-Based For Loops

When iterating over a container or array without copying elements:

// 'byte' is a reference to the actual array element
for (uint8_t &byte : rx_buffer) {
    byte = 0; // Clear buffer efficiently
}

4. Singleton Access

Returning a reference from a Singleton getInstance() is safer than a pointer because the user knows it will never be null.

Common Pitfalls (Practical Tips)

PitfallDetails
❌ Dangling Reference

Returning a reference to a local variable destroys the stack frame, leaving the reference pointing to garbage.

int& bad() { 
  int x=10; 
  return x; 
} // CRASH
❌ "Null" Reference

While technically impossible, dereferencing a NULL pointer and casting it to a reference leads to undefined behavior.

int *p = NULL; 
int &r = *p; // UB
❌ Reference to BitfieldYou cannot create a reference to a bitfield in a struct because bits don't have unique memory addresses.
✅ Use References for APIPrefer const Type& for input arguments in functions to avoid unnecessary copying of structs.
✅ Use Pointers for OptionalIf a parameter is optional (can be NULL), use a pointer. References imply "this must exist."