C Parameters

If you are performing an operation with some input and do not care about any changes to the input, pass the data type itself.

If you are modifying a specific instance of some value, pass the location of what you would like to modify.

STACK
Address     Value
--------    ------
0x1f0       3       <- x
0x10        0x1f0   <- intPtr (pointer to x)

Why Use Pointers?

Enables pass-by-reference style (not native in C).

Efficient for memory manipulation.

Required for working with dynamically allocated memory.

When to Pass by Value vs. Pointer

IntentHow to PassExample
Read-only accessValueint x
Modify caller’s variablePointerint *x
void doubleNum(int *x) {
    *x = *x * 2;
}

int main() {
    int num = 2;
    doubleNum(&num);
    printf("%d", num);  // Prints 4
}

Arrays and Memory

Arrays Are Contiguous Memory Blocks

char str[] = "apple";  // 'a' 'p' 'p' 'l' 'e' '\0'

Array Behavior

  • Cannot reassign array: nums = nums2; is illegal.
  • sizeof(array) gives full size only inside the same scope
  • Array Passed to Function Becomes Pointer
void myFunc(char *str) {
    // sizeof(str) == 8, just a pointer
}

example:

char str[] = "apple";

Address     Value
--------    ------
0x100       'a'
0x101       'p'
0x102       'p'
0x103       'l'
0x104       'e'
0x105       '\0'

Pointer Arithmetic Visualization

char *str = "apple";  // stored in .data segment

str + 1 --> points to "pple"
str + 3 --> points to "le"
DATA SEGMENT
Address     Value
--------    ------
0xff0       'a'      <- str
0xff1       'p'
0xff2       'p'
0xff3       'l'
0xff4       'e'
0xff5       '\0'

Arrays of Pointers

Used to group multiple strings (e.g., argv in main(int argc, char *argv[])).

Pointer Arithmetic

Pointer arithmetic depends on the type of the pointer.

char *str = "apple";
char *str3 = str + 3;
printf("%s", str3); // Outputs "le"

int nums[] = {52, 23, 12, 34};
int *nums3 = nums + 3;
printf("%d", *nums3); // 34

str[2] == *(str + 2)
// Pointer Difference Gives Element Offset, Not Bytes
int diff = nums3 - nums; // 3, not bytes!

const Keyword

Use const to declare global constants in your program. This indicates the variable cannot change after being created.

Sometimes we use const with pointer parameters to indicate that the function will not / should not change what it points to. The actual pointer can be changed, however.

// This function promises to not change str’s characters
int countUppercase(const char *str) {
    int count = 0;
    for (int i = 0; i < strlen(str); i++) {
        if (isupper(str[i])) {
            count++;
        }
    }
    return count;
}

By definition, C gets upset when you set a non-const pointer equal to a const pointer. You need to be consistent with const to reflect what you cannot modify.

Structs

Basic Struct

struct date {
    int month;
    int day;
};

With typedef

typedef struct {
    int month;
    int day;
} date;

date today = {1, 28};

Passing Structs

  • By value: copies the entire struct.
  • By pointer: modifies the original.

Arrays of Structs

typedef struct {
    int x;
    char c;
} my_struct;

my_struct array_of_structs[5];
array_of_structs[0] = (my_struct){0, 'A'};

Ternary Operator

A shorthand conditional expression.

int x = (argc > 1) ? 50 : 0;