Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.
-
Upload
ellen-moore -
Category
Documents
-
view
231 -
download
3
Transcript of Pointers and Arrays Kernighan/Ritchie: Kelley/Pohl: Chapter 5 Chapter 6.
Pointers and Arrays
Kernighan/Ritchie:Kelley/Pohl:
Chapter 5Chapter 6
222
Lecture Overview
Arrays
Pointers
Call-by-reference
Arrays, pointers and pointer arithmetic
Dynamic Memory Allocation
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];
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]);
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 };
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
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};
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";
999
Lecture Overview
Arrays
Pointers
Call-by-reference
Arrays, pointers and pointer arithmetic
Dynamic Memory Allocation
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
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 */
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
?
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;
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;
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;}
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
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
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
191919
Lecture Overview
Arrays
Pointers
Call-by-reference
Arrays, pointers and pointer arithmetic
Dynamic Memory Allocation
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
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);
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);
232323
Lecture Overview
Arrays
Pointers
Call-by-reference
Arrays, pointers and pointer arithmetic
Dynamic Memory Allocation
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
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
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
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]);
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
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
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
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
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)
333333
Lecture Overview
Arrays
Pointers
Call-by-reference
Arrays, pointers and pointer arithmetic
Dynamic Memory Allocation
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)
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
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
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()
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;}
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!
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
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);}
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
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