Erin's CS stuff

CS stuff!

Pass by Address

Pass by Address utilizes pointers as parameters to bypass the limitations of scope and allow access to variables outside of the function. In our class, this is often to used to "output" multiple values instead of being constrained by the single value we can output through the function return mechanism.

Background

Pass by Address is a pretty complex concept, in large part because it combines many technical details to be able to accomplish something kind of abstract, so covering some background knowledge first might be helpful.

Pass by Value

It might help to start by examining the default method of managing parameters in C: Pass by Value.

In C (and C++), the default approach for managing "input" during a function call is to copy the value of the matching argument and store it in the function parameter. This supports scope rules by reinforcing a very concrete boundary around the functions and separating the arguments from the parameters. Any changes made to the parameter within the function do not affect the original argument at all (if it seems like it does, then it's actually Pass by Address under the hood).

We've delved a little into how variables work, so now it's time to contemplate a new level of data type! During runtime, the variable name is bound to a memory address that the operating system chooses. While we can't/shouldn't determine what that memory address is, we can not only access it, we can store it! And that's what pointers are for.

Pointers are a special kind of variable that are specifically for storing the memory addresses of other variables. As such, pointers are only ever used as a reference to another variable and they must be "pointed" to one to work properly (we'll go over the syntax and details of that below).

They're useful in a couple of situations that you'll cover in CS 202 (like polymorphism and dynamic memory allocation) or CPE courses, but we'll use them almost exclusively for Pass by Address (and just a smidge for File IO). Because of that, we'll cover general pointer syntax under the background section.

Declaration

A big difference when using pointers is the data type portion of the declaration. Because they are a used as references to other variables, we must consider what type of variable they will "point" to, which gets used in the declaration. For example, if we need a pointer to point to an integer variable, the declaration will include the int type, along with an asterisk *:

int* agePtr;
(I often add "ptr" to the end of the pointer variable name to help me keep track of things)

Assignment

We won't do it in this class, but if you wanted to explicitly point at a variable, that other variable must first exist (order is important here!). Then we can combine the address of operator & with the assignment operator =:

int age;
int* agePtr;

agePtr = &age; // agePtr now "points to" age

Aliasing

Finally, once a pointer is referencing another variable, the pointer can be used as a alias by appling the dereference operator *:

int age = 0;
int* agePtr;

agePtr = &age;
*agePtr = 45; // uses the pointer as an alias to save 45 in the age variable
printf("%d\n", age); // would display 45

Syntax

Prototypes

We will use the asterisk * for any pointer parameters.

void swapInts(int* val1, int* val2);

Calls

We will use our new address of operator & in the function call.

int x = 5, y = 42;
swapInts(&x, &y); 
// now x stores 42 and y stores 5

Definitions

The asterisk * is used as the dereference operator within the function definition.

void swapInts(int* val1, int* val2){ // val1 "points at" (stores the memory address of) x and val2 "points at" y
  int temp = *val1; // stores the value from x in temp
  *val1 = *val2;    // overwrites the value in x with the value in y
  *val2 = temp;     // overwrites the value in y with the value that had been in x at the beginning of the function
}