/*
 * Copyright ©2026 Soham Pardeshi. All rights reserved.
 * Permission is hereby granted to students registered for University of
 * Washington CSE 333 for use solely during Summer Quarter 2026 for
 * purposes of the course. No other use, copying, distribution, or
 * modification is permitted without prior written consent. Copyrights
 * for third-party components of this work must be honored. Instructors
 * interested in reusing these course materials should contact the author.
 */

#include <iostream>   // for std::cout, std::endl
#include <cstdlib>    // for EXIT_SUCCESS

using std::cout;
using std::endl;

// Two ways to let a function modify the caller's variable.

void IncPtr(int* p) { *p += 1; }  // pointer version: caller passes &a, body uses *p
void IncRef(int& r) {  r += 1; }  // reference version: caller passes a, body uses r

// A big struct is expensive to copy.  Passing by const reference hands the
// function a read-only alias: no copy, and the compiler forbids modifying it.
// This is the most common reference idiom in C++.
struct Image {
  int width, height;
  char pixels[1000000];  // ~1 MB of data
};

void Save(const Image& img) {       // no copy, cannot mutate img
  cout << img.width << "x" << img.height << endl;
}

int main(int argc, char** argv) {
  int a = 5;
  IncPtr(&a);  // caller writes &a
  IncRef(a);   // caller writes a  -- no stars, no ampersands
  cout << "a = " << a << endl;  // 7

  Image big = {640, 480, {}};
  Save(big);  // passed by const&, so no 1 MB copy is made
  return EXIT_SUCCESS;
}

// Compile with:
//   g++ -Wall -g -std=c++17 -o refparams refparams.cc