Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

43
Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6

Transcript of Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

Page 1: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

Pointers and Arrays

Kernighan/Ritchie:Kelley/Pohl:

Chapter 5Chapter 6

Page 2: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

222

Lecture Overview

Arrays

Pointers

Call-by-reference

Arrays, pointers and pointer arithmetic

Dynamic Memory Allocation

Page 3: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

333

Arrays

Programs often use homogeneous data

For example:

When the size of the data is too large, arrays are a better solution:

int grade0, grade1, grade2;

int grades[3];

Page 4: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

444

Arrays

It is good programming practice to define the size of an array as a symbolic constant

The standard idiom for processing an array defined this way is using a for loop

#define SIZE 8

int array[SIZE];

for (i = 0; i < SIZE; i++) printf ("%d ", array[i]);

Page 5: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

555

Array Initialization

A special format exists for initializing arrays

If the list of initializers is shorter than the array, the rest of the array is set to zero

In this case, the last two elements (f[3] and f[4]) will be initialized to zero

float f[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };

float f[5] = { 0.0, 1.0, 2.0 };

Page 6: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

666

Array Initialization

Depending on its storage class, an array may or may not be automatically initialized static and external arrays are always

initialized – this is done by setting all of their elements to zero

automatic arrays will not necessarily be initialized (depends on the compiler), and thus they should be assumed to contain garbage

Page 7: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

777

Array Initialization

If an array is declared without a size, it is implicitly given a size according to the number of initializers

Thus, the following two array declarations are equivalent:

int a[] = {2, 3, 5, -7};

int a[4] = {2, 3, 5, -7};

Page 8: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

888

Array Initialization

Character arrays may be initialized in the same way:

However, since character arrays serve as strings in C, the following short-cut is also available (equivalent to the above):

char s[] = {'a', 'b', 'c', '\0'};

char s[] = "abc";

Page 9: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

999

Lecture Overview

Arrays

Pointers

Call-by-reference

Arrays, pointers and pointer arithmetic

Dynamic Memory Allocation

Page 10: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

101010

Pointers

A simple variable in a program is storedin a certain number of bytes, at some particular memory location (or address)

Pointers are used to access memory and manipulate addresses

If v is a variable, then &v is the addressin memory where its value is stored

Page 11: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

111111

Pointers

Memory addresses are values that can be manipulated much like integer values

The following declares a pointer to int:

Examples of assignment to the pointer p:

int *p;

p = 0;p = NULL; /* equivalent to p = 0; */p = &i; /* i must be an integer. */p = (int *)1776; /* an absolute memory address */

Page 12: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

121212

Pointers

A basic example of how the pointer mechanism works:

We think of the pointer p is an arrow, which at this stage is pointing to nothing:

int a = 1, b = 2, *p;

1 2

a b p

?

Page 13: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

131313

Pointers

Now, assume that the next line of code is:

After this statement, the memory contentswill look like this:

1 2

a b p

p = &a;

Page 14: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

141414

Pointers

Finally, consider the following assignment:

This assigns the value pointed to by p to b

Since p points to a, this is equivalent to the statement:

b = *p;

b = a;

Page 15: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

151515

Pointers – Example

Print the address and value of a variable:

#include <stdio.h>

int main() {

int i = 7; int *p = &i;

printf (" Value of i: %d\n", *p); printf ("Location of i: %p\n", p);

return 0;}

Page 16: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

161616

Pointers – Example

The output of the program in our system:

The actual location of a variable in memory is system-dependent

The variable p is of type int *, and its initial value is &i

The operator * dereferences p

Value of i: 7Location of i: 0xbffff924

Page 17: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

171717

Pointer Expressions

Evaluating some pointer expressions:

Declarations and initializations int i = 3, j = 5, *p = &i, *q = &j, *r; double x;

Expression Equivalent expression Valuep == &i* * &pr = &x7 * * p / * q + 7*(r = &j) *= *p

p == (&i)*(*(&p))r = (&x)(((7 * (*p))) / (*q)) + 7(*(r = (&j))) *= (*p)

13

illegal1115

Page 18: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

181818

Pointer Expressions

The third line tries to assign the address of a double variable to a pointer to int

In the fourth line: The first '*' is the multiplication operator The second '*' is the dereference operator

In the fifth line, r is assigned the address of j, and then another assignment multiplies *r (which now means j) by *p

Page 19: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

191919

Lecture Overview

Arrays

Pointers

Call-by-reference

Arrays, pointers and pointer arithmetic

Dynamic Memory Allocation

Page 20: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

202020

Call-by-reference

In C, all parameters are passed by value

In other languages, it is possible to pass parameters by reference, allowing the called function to modify them

The same effect can be achieved in C, using pointers as function arguments

Page 21: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

212121

Call-by-reference – Example

Let us try to write a function that swaps the values of its two arguments:

This will have no effect on a and b:

void try_to_swap (int x, int y) { int tmp; tmp = x; x = y; y = tmp;}

try_to_swap (a, b);

Page 22: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

222222

Call-by-reference – Example

However, using pointers we can write the swap() function as follows:

This will swap the values of a and b:

void swap (int *px, int *py) { int tmp; tmp = *px; *px = *py; *py = tmp;}

swap (&a, &b);

Page 23: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

232323

Lecture Overview

Arrays

Pointers

Call-by-reference

Arrays, pointers and pointer arithmetic

Dynamic Memory Allocation

Page 24: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

242424

Arrays and Pointers

Arrays and pointers are very similar

An array name is actually a pointer to the first element in the array

Similarly, a pointer can be subscripted just as if it were an array

However, there is one major difference: the value of a pointer can change, while an array points to a fixed address

Page 25: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

252525

Arrays and Pointers

Suppose that a is an array and that i is an int, then a[i] is equivalent to *(a + i)

Similarly, if p is a pointer, then p[i] is equivalent to *(p + i)

This means that we can use array notation with pointers, and vice versa

Page 26: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

262626

Arrays and Pointers – Example

#include <stdio.h>#define SIZE 7

int main() { int a[SIZE] = {12, 32, 434, 43, 26, 873, 43}; int i;

for (i = 0; i < SIZE; i++) printf ("%d ", a[i]); printf ("\n");

return 0;}

12 32 434 43 26 873 43

Page 27: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

272727

Arrays and Pointers – Example

The array traversal loop in the previous example can be written in different ways:

for (i = 0; i < SIZE; i++) printf ("%d ", *(a + i));

int *pa = a; for (i = 0; i < SIZE; i++) printf ("%d ", *(pa++));

for (i = 0; i < SIZE; i++) printf ("%d ", i[a]);

Page 28: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

282828

Pointer Arithmetic

Pointer arithmetic is one of the most powerful features of C

If the variable p is a pointer to a particular type, then the expression p + 1 yields the correct machine address for storing or accessing the next variable of that type

Other expressions may be used, such as: p++, p + i or p += i

Page 29: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

292929

Pointer Arithmetic – Example

#include <stdio.h>

int main() { double a[2], *p, *q;

p = a; /* points to base of array */ q = p + 1; /* equivalent to q = &a[1]; */ printf ("%d\n", q - p); printf ("%d\n", (int)q - (int)p);

return 0;}

18

Page 30: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

303030

Pointer Arithmetic – Example

The previous output assumes that a double is stored in 8 bytes

p points to a double and q points to the next double, therefore the difference in array elements is 1

However, the difference in actual memory locations is 8

Page 31: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

313131

Arrays as Function Arguments

In a function definition, a parameter that is declared as an array is actually a pointer

For convenience, bracket notation is also allowed, but the two are equivalent

Inside the function, the parameter may be treated as a pointer, as an array, or alternately as both

Page 32: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

323232

Arrays as Function Arguments – Example

The function header may be replaced with:

/* n is the size of a[]. */double sum (double a[], int n) { int i; double sum = 0.0;

for (i = 0; i < n; ++i) sum += a[i];

return sum;}

double sum (double *a, int n)

Page 33: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

333333

Lecture Overview

Arrays

Pointers

Call-by-reference

Arrays, pointers and pointer arithmetic

Dynamic Memory Allocation

Page 34: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

343434

Dynamic Memory Allocation

Until now we have seen two ways of allocating memory: At compile time, for static and global variables During run-time, for automatic (local) variables

Both types require knowing the amount of memory that should be allocated beforehand (when the program is written)

Page 35: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

353535

Dynamic Memory Allocation

Sometimes there is a need to explicitly tellthe system to allocate memory during the program's operation

This is called dynamic allocation

Memory is allocated using the library function malloc(), defined in stdlib.h Other functions exist, such as calloc() or realloc() but we will not discuss them here

Page 36: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

363636

Dynamic Memory Allocation

Dynamic allocation is used to create space for arrays, structures and unions

The function malloc() takes a single argument of type size_t, and returns: NULL, if the required amount of memory cannot

be allocated, or: A pointer of type void *, which points to a

memory block of the requested size

Page 37: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

373737

Dynamic Memory Allocation

The memory allocated by malloc() is not initialized to any value

Space that was dynamically allocated is not returned to the system upon function exit

The space must be freed explicitly by the programmer, through a call to free(ptr) ptr is a pointer that points to a block of space

previously allocated by malloc()

Page 38: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

383838

Dynamic Memory Allocation – Example 1

#include <stdio.h>

int main() {

float arr[20];

arr[0] = 2; printf ("Value of first cell: %f\n", *arr); arr[7] = 17; printf ("Value of 8th cell: %f\n", *(arr + 7));

return 0;}

Page 39: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

393939

Dynamic Memory Allocation – Example 1

#include <stdio.h>

int main() {

float *arr;

arr[0] = 2; printf ("Value of first cell: %f\n", *arr); arr[7] = 17; printf ("Value of 8th cell: %f\n", *(arr + 7));

return 0;}

Wrong!

Page 40: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

404040

Dynamic Memory Allocation – Example 1

#include <stdio.h>

int main() {

float *arr = (float *)malloc (20 * sizeof (float));

arr[0] = 2; printf ("Value of first cell: %f\n", *arr); arr[7] = 17; printf ("Value of 8th cell: %f\n", *(arr + 7));

free (arr); return 0;}

OK

Page 41: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

414141

Dynamic Memory Allocation – Example 2

int main() { int *grades, num_grades; int i, sum = 0; printf ("Please enter number of grades: "); scanf ("%d", &num_grades); grades = (int *)malloc (num_grades * sizeof (int)); printf ("Please enter grades: "); for (i = 0; i < num_grades; i++) scanf ("%d", &grades[i]); for (i = 0; i < num_grades; i++) { printf ("Grade %d: \t%d\n", i + 1, grades[i]); sum += grades[i]; } free (grades); printf ("Average: \t%d\n", sum / num_grades);}

Page 42: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

424242

Dynamic Memory Allocation – Example 2

The output of the previous program:

Please enter number of grades: 5Please enter grades: 10 5 18 19 8Grade 1: 10Grade 2: 5Grade 3: 18Grade 4: 19Grade 5: 8Average: 12

Page 43: Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.

434343

Dynamic Memory Allocation – Example 2

When calling malloc() we need to take into account: The number of elements required The size of each element (using sizeof())

The type of the pointer returned by malloc() is void *, and therefore we need to cast it into the required type