COMP10002-Notes

View on GitHub

Functions and Memory Addresses

Functions

Functions allows programmers to reuse code. Separating code into functions often leads to less repetition, and more readable code!

Much like variables, we need to tell the compiler the ‘type’ of our function. In C, this means specifying the type of the returned value and the types of the function’s arguments.

    [return value type] function_name([type] arg1, [type] arg2) {
            ...
    }

A function that you are familar with is the main function

    int main(int argc, char *argv[]) {
            return 0;
    }

From the definition, we know that the main function returns an integer, and takes two arguments: an integer argc, and argv (argv’s type is more complicated and will be explained shortly).

If your function doesn’t return a value, declare your function with the void type

    void print_number(int n) {
            printf("%d\n", n);
    }

Memory

Here comes the most important concept for a C programmer, the memory stack. Computers memory is essentially a huge table for storing data. This table stores data in bytes and each byte is labelled 0, 1, 2… This label is also called an address or a pointer.

Address/Pointer Data
0 255
1 0
2 0
3 11

Memory Operators

You can get the address of a variable in your program with the & operator.

You can use it to print out the address of a local variable.

    int num = 0;
    printf("%p\n", &num);

Note: %p is the format specifier for an address (pointer).

A pointer to a variable of [type] has the type of [type]*. We can store the pointer to num with

    int num = 0;
    int *num_pointer = #

You can get the value at a pointer / change the value at a pointer using the * operator.

    int num;
    int *num_pointer = #
    *num_pointer = 0; // num = 0
    int other = *num_pointer; // int other = num;

Hexadecimals

On my computer, printing the pointer of num gave me 0x7ffbffffa93c. This is a number in hexadecimal form. Hexadecimal numbers have 16 symbols (0123456789abcdef) instead of 10. This allows us to represent large numbers in less symbols. Because computer addresses can get very large, they are usually printed in hexadecimal form.

Stack

A C program stores local variables in memory consecutively. This section of memory is referred to as “the stack”.

    int a = 0;
    int b = 0;
    printf("%p %p\n", &a, &b);

The above code gave me 0x7ffbffffa960 and 0x7ffbffffa964. The value of the pointers will change every time I run the program because the next available address on the stack will change depending on the other programs running on my computer. What will not change is the relative difference between the pointers. int variables have a size of 4 bytes on my computer. Because local variables are assigned memory consecutively, a and b are next to each other in memory.

Address/Pointer Data
0x7ffbffffa960 0
0x7ffbffffa961 0
0x7ffbffffa962 0
0x7ffbffffa963 0

Pointers and Functions

A C program copies the value of variables passed into a function. This means that the address of the variable you pass in to a function will be different to the address of the variable in the function.

    void print_address(int n) {
            printf("%p\n", &n);
    }

    int main(int argc, char *argv[]) {
            int num = 0
            printf("%p\n", &num);
            print_address(num);
    }

The above code will print two different addresses. This means that any changes to the argument’s value inside a function will not change variables outside of the function.

Variable scope

Local variable - a variable that can only be accessed inside of the function, it’s value is ‘destroyed’ after the function ends. int a = 0;

Static variable - a variable that can only be accessed inside the function, but it’s value persists between function calls. static int a = 0;

Global variable - a variable that can accessed by every function, defined outside of a function. int a = 0;

Changing variables in function

What can you do if you want your function to change the value of a variable outside the function? You can pass the address of that variable as an argument instead.

    void add_one(int *n_pointer) {
            *pointer = *pointer + 1;
    }
    int main(int argc, char *argv[]) {
            int num = 0;
            add_one(&num);
            printf("%d\n", num);
    }