CSci-E26 Section Notes 2021-10-04

Table of Contents

1 Pointers and Arrays

// Making a constant for things like this means that it can be changed in
// only one place rather than in several when needs evolve.
#define BUFSIZE 100

char buffer[BUFSIZE] = "abcdef";

char *str = buffer;		// assign str to start of buffer
char *str2 = buffer + 3;	// assign str2 to the "def" in buffer
char *str3 = &buffer[3];	// exactly the same as above

buffer[3] == 'd';			// buffer[3] is a char
strcmp(&buffer[3], "def") == 0;	// &buffer[3] is a char *, so string

// No difference between a pointer to a character vs a string, except that
// in the latter case we are assuming there are more characters after the
// first one and they end with a null terminator ('\0')

// Two-dimensional array of characters.
char fields[NUMFIELDS][BUFSIZE];

// One-dimensional array of pointers to characters (strings). Note that
// none of these pointers actually point to storage until you set them
// to point to somewhere. These can point to existing strings that are
// stored elsewhere in some manner. The way this often works is there
// is an int variable that starts at zero and represents how many words
// in the array have been filled in. Often these are filled in dynamically
// as we shall soon learn. Of course, you need to check that this number
// never gets to be greater than or equal to MAXWORDS.
char *words[MAXWORDS];

// Pointer-to-pointer to char, which usually represents a pointer to an
// array of strings. This can be used when you don't know what the maximum
// is. Typically one starts with an array of N pointers, and if you use
// that up you can reallocate it to be twice as large. You need to track
// both how many words have been stored and also what the current capacity
// of the array is.
char **words2 = NULL;

// Weirdness of C:
// a[b] is the same as *(a + b) is the same as b[a]
// Note that one of a or b needs to be a pointer or array expression and the
// other an int expression.

// Two dimensional array of ints.
int nums[4][4] = {
    { 0, 2, 4, 6  },
    { 1, 3, 5, 7  },
    { 2, 4, 8, 16 },
    { 0, 0, 1, 1  },
};

// The above is really stored as one long sequence of int cells.
//
//   nums:
//   +---------------+---------------+---------------+---------------+
//   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//   |  0|  2|  4|  6|  1|  3|  5|  7|  2|  4|  8| 16|  0|  0|  1|  1|
//   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//   +---------------+---------------+---------------+---------------+
//
// The dimensionality of a multi-dimensional array controls how the
// offset calculations are made to find the element.

int main()
{
    int *numptr = nums[2];            // pointer to int or more than one int
    int (*arrptr)[4] = &nums[1];      // pointer to array of four ints, or ...
    int *ptrs[] = {                   // array of pointers to int(s)
	nums[1], &nums[2][1], &nums[0][1]
    };

    printf("%d\n", numptr[1]);        // 4
    printf("%d\n", arrptr[1][2]);     // 8

    // Produces
    //   1 1
    //   4 8
    //   2 6
    for (int i = 0; i < sizeof(ptrs) / sizeof(*ptrs); ++i) {
	printf("%d %d\n", ptrs[i][0], ptrs[i][i]);
    }

    printf("%d\n", ptrs[2][10]);      // 16
}

// Scanf is a little odd, because to store into a simple scalar variable
// like an int, you need to use the address-of operator:
scanf("%d", &number);
// But to store into an array, you just need the name of the array
// because it's already an address, and arrays are passed by reference.
scanf("%s", buffer);
// Note you can pass a pointer value as well, but beware because there has
// to be storage there which can hold whatever the user types.
// For this reason it is safer to use the "%99s" format, which gives the
// maximum number of chars to put into the buffer (a null is then appended,
// so it should be one less than the actual size of the buffer).

Author: Alexis Layton

Created: 2021-10-04 Mon 21:54

Validate