7. 16-bit Sum Product

Write a function named compute that calculates the sum and product of two 16-bit signed integers and returns both results using reference parameters.

Function Requirements:

  • a and b
    • Passed by value
    • Type: int16_t
  • sum and product
    • Passed by reference
    • Type: int32_t
  • Behavior:
    • sum = a + b
    • product = a * b
    • Arithmetic must be performed using 32-bit widening to avoid overflow

In main():

  1. Read two integers a and b from standard input
  2. Call compute(a, b, sum, product)
  3. Print sum and product separated by a single space

 

Example 

Input:

30000 2

Output:

30002 60000

Constraints:

  • a and b are 16-bit signed integers
    • Range: -32768 to 32767
  • sum and product are 32-bit signed integers
  • The multiplication result will always fit within a 32-bit signed integer
  • Results must be returned only via reference parameters
  • Do not use:
    • Pointers
    • Global variables
    • Structs or classes
    • Dynamic memory
  • Use fixed-width integer types (<cstdint>) to ensure portability

 

 

 

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."