Lecture 17 More and More Pointers

Joseph Haugh

University of New Mexico

Free Recall

  • Open a blank text file or pull out a piece of paper.
  • Write down everything your remember from the last lecture and beyond.

Review Quiz

What is the output of the following pieces of code?

Review Quiz

void main(void) {
    /* Assume sizeof(int) = 4 */
    int x = 5; /* addr = 0x4A */
    int *y = &x + x;
    printf("&x=%p, y=%p\n", &x, y);
}

Review Quiz

void main(void) {
    /* Assume sizeof(int) = 4 */
    int x = 5; /* addr = 0x4a */
    int *y = &x + x;
    printf("&x=%p, y=%p\n", &x, y);
}
&x=0x4a, y=0x5e

Review Quiz

int and int* are always the same size.

Review Quiz

int and int* are always the same size.

False

Review Quiz

* means what in C?

Review Quiz

* means what in C?

  • Multiplication
  • Pointer declaration
  • Pointer dereference

Review Quiz

& means what in C?

Review Quiz

& means what in C?

  • Binary AND
  • Address of

Review Quiz

Given the following memory:

Address Value
0x40 5
0x44 7
0x48 9

What will the following code print?

int array[] = {5, 7, 9};
printf("%p\n", array);

Review Quiz

Given the following memory:

Address Value
0x40 5
0x44 7
0x48 9

What will the following code print?

int array[] = {5, 7, 9};
printf("%p\n", array);

0x40

Initializing Arrays

  • Arrays are initialized using the following syntax:

    int array[] = {1, 2, 3, 4, 5};
  • The size of the array is optional when doing this.

  • You can initialize an array of pointers:

    char *array[] = {"one", "two", "three"};

Multi-Dimensional Arrays

Multi-dimensional arrays are arrays of arrays.

int matrix[10][5];

matrix is an array of 10 arrays, each containing 5 integers.

It can be initialized as follows:

int matrix[10][5] = {
    {1, 2, 3, 4, 5},
    {6, 7, 8, 9, 10},
    /* ... */
};

Multi-Dimensional Arrays

When passing a multi-dimensional array to a function, you must specify the size of all but the first dimension.

void foo(int matrix[][5]) {
    /* ... */
}

Arrays of pointers to arrays are often used in lieu of multi-dimensional arrays.

int *matrix[10];

Is an array of 10 pointers to arrays of integers.

Arrays of Pointers

We can do some interesting things with arrays of pointers.

int *foo[2]; /* Array of two integer pointers */
int a[3];    /* Array of three ints */
int b[4];    /* Array of four ints */
foo[0] = a;
foo[1] = b;
foo[0][0] = 0;   /* a[0] = 0; */
foo[0][1] = 1;   /* a[1] = 1; */
foo[1][3] = 3;   /* b[3] = 3; */
foo[0][3] = 3;   /* ERROR! */

Multi-Dimensional Arrays…

Arrays of pointers to arrays are especially useful for arrays of Strings:

char *colors[3] = {"red", "green", "blue"};
colors[0][0] == 'r'
colors[1][0] == 'g'
colors[2][0] == 'b'

Pointer to String Constant

void main(void) {
  char str1[] = "Hello World";
  char *str2 = "Hello World";
  str1[6] = 'X';
  printf("str1=%s\n", str1);
  printf("str2=%s\n", str2);
  str2[6] = 'X';
  printf("str2=%s\n", str2);
}

str1=Hello Xorld

str2=Hello World

Segmentation fault

Line 7 fails because str2 is a pointer to a string constant and thus, in read-only memory.

Address Arithmetic

int n = 17;
int* a = &n;
short* b = (short*)&n;
char* c = (char*)&n;

printf("%p %p %p\n", a, b, c);
a++; b++; c++;

printf("%p %p %p\n", a, b, c);
printf("%d\n", n);

Line 7: The values at a*, b*, and c* are incremented by the size of their respective types and their values are now undefined.

0x7ffffba2610c 0x7ffffba2610c 0x7ffffba2610c

0x7ffffba26110 0x7ffffba2610e 0x7ffffba2610d

17

String Length by Index & Address Arithmetic

int strLen(char s[]) {
  int i=0;
  while (s[i]) i++;
  return i;
}
int strLen2(char *s) {
  char *p = s;
  while (*p) p++;
  return p - s;
}

Command Line Arguments

int main(int argc, char *argv[]) {

Call program: ./a.out Hello World

argv -> argv[0] -> a.out\0
argv[1] -> Hello\0
argv[2] -> World\0

argv is a pointer to an array of pointers.

Each pointer is the address of the first char in a null terminated string.

Echo Arguments: Array Style

void main(int argc, char *argv[]) { 
  int i;
  printf("Number of arguments = %d\n", argc);
  for (i = 0; i < argc; i++) { 
    printf("  argv[%d]=%s\n", i, argv[i]);
  }
}

a.out pi is 3.1415

Number of arguments = 4

argv[0]=a.out

argv[1]=pi

argv[2]=is

argv[3]=3.1415

argv[i] is the address of a null terminated string

Echo Arguments: Pointer Style

void main(int argc, char *argv[]) { 
  printf("main(): argc=%d\n", argc);
  while (argc-- > 0) { /* test first, then decrement */
    printf("argc=%d: %s\n", argc, *argv++);
  }
}

What is going on with *argv++?

  1. Dereference argv. This is argv[0]: a pointer to the first argument.
  2. Send that pointer to %s.
  3. Increment argv, not *argv. Now points to argv[1].

a.out Hello World

main(): argc=3

argc=2: a.out

argc=1: Hello

argc=0: World