Skip to content
This repository has been archived by the owner on Jan 12, 2022. It is now read-only.

L18 [C Arrays]

Richard Luo edited this page Dec 14, 2021 · 1 revision

Marginally Indexed Arrays

Arrays of pointers

char *month_name(int n) {
    
    static char *name[] = {
        "Illegal Month",
        "January", "February", "March",
        "April", "May", "June",
        "October", "November", "December"
    };

    return (n < 1 || n > 12) ? name[0] : name[n];
}

If a variable never changes, you can just put it on the stack frame. This way, a block of memory (probably in the constant area) is initialized like this for all string constants:

Illegal month\0January\0February\0March\0April\0May\0June\0July\0August\0September\0October\0November\0December\0

So when the function is called, the line return (n < 1 || n > 12) ? name[0] : name[n]; gives us back the address (a pointer) to the month.

Question #1: A marginally indexed array takes

A. more space than a 2D array

B. less space than a 2D array

C. the same amount of space as a 2D array

D. depends on whether all the items in the second dimension of the array are the same or different sizes

In the example above, Marginally sized array = 13 * size of the largest pointer

  • Space is wasted since you have to allocate space for the largest array

2D Arrays

For the following code, what is the size of a?

int main() {
    int a[5][7];
}

Answer: the size of a is 4 (size of int) * 5 * 7 = 140.

Follow up question: what is sizeof a[3]?

4 * 7 = 28

How do you skip over a multidimensional array? row_index * sizeof(row)

After that, to get to the desired element of that row, add column_index * sizeof(array_type)

Pointer Calculations On Our Own

Hehe, may be on final

What do you do if you want to compute array memory addresses yourself?

  • Cast the pointer to (char *)
    • sizeof(char) is 1 byte, always byte addressible
  • To access element (r, c) in arr:
int arr[5][10];
int offset = (r * 10 + c) * sizeof(int);
int *p = (int *)((char *)arr + offset);

Multidimensional Array Parameters

Do you need to know need the first dimension to declare an array? No!

Since C does not check array bounds, all you need is offset = i * columns + j to calculate the address of a given element (i, j).

For a 3D array, offset = (i * rows * columns) + (j * columns) + k and a[i][j][k] == *(*(*(a + i) + j) + k) where a is the pointer to the first element such as int a[3][4][5]

Recitation

How do you read C type declarations? Is char *argv[] a pointer to an array or an array of pointers?

Process

  1. Identify the name
  2. Go right of the name until you hit the end or the right paren
  3. Go left of the name until you hit the end or the left paren
  4. Repeat

In this case, you would first identify argv as the name, [] as array of, and * as pointer.

What about for types of functions? int *(add)(int, int);

Add is a function that takes two integers that returns a pointer to int.

Check your understanding with CDECL: https://cdecl.org/

What about for types of functions? int *(*add)(int, int);

  1. (*add) Add is a pointer to
  2. (int, int) function that takes in 2 ints
  3. int * that returns pointer to int

Declare a variable named 'foo' which holds 7 pointers to pointers to longs stored inside of an array.

long **foo[7]