1 / 56

# More Pointers and Arrays - PowerPoint PPT Presentation

More Pointers and Arrays. Kernighan/Ritchie: Kelley/Pohl:. Chapter 5 Chapter 6. Lecture Overview. Strings and characters String functions in the standard library sizeof Revisited Multidimensional arrays Pointers to pointers and pointer arrays Pointers to functions. Strings.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about ' More Pointers and Arrays' - sheng

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

### More Pointers and Arrays

Kernighan/Ritchie:

Kelley/Pohl:

Chapter 5

Chapter 6

• Strings and characters

• String functions in the standard library

• sizeof Revisited

• Multidimensional arrays

• Pointers to pointers and pointer arrays

• Pointers to functions

• As we have seen before, strings in C are one-dimensional arrays of type char

• By convention, strings end with a '\0', thus memory allocated to hold a string should include one additional space

• A string constant is treated by the compiler as a pointer to the string's base address

• p can be used like any other pointer:

• To further emphasize this point:

• Note that such code should never be usedin any real program!

char *p = "abc";

printf ("%s %s\n", p, p + 1);

abc bc

printf ("%c %c\n", "abc"[1], *("abc" + 2));

b c

• The library ctype.h provides macros to check whether a character belongs to a certain character class

• Some examples:

• isspace– Checks for white-space

• isalpha– Checks for an alphabetic character

• isdigit– Checks for a digit (0 through 9)

• islower– Checks for a lower-case character

Example –Counting Words in a String

#include <ctype.h>

int count_words (char *s) {

int cnt = 0;

while (*s != '\0') {

while (isspace (*s)) /* skip white space */

s++;

if (*s != '\0') { /* found a word */

cnt++;

while (!isspace (*s) && *s != '\0')

s++; /* skip the word */

}

}

return cnt;

}

The Character Type Library – Complete List

• Strings and characters

• String functions in the standard library

• sizeof Revisited

• Multidimensional arrays

• Pointers to pointers and pointer arrays

• Pointers to functions

• The standard C library provides several functions for handling strings

• The function prototypes for string handling functions are given in the standard header file string.h

• Functions are available for comparing, copying or concatenating strings

• All string functions take arguments and return values of type char *

• Some of the parameters also include the const qualifier, which means:

• The characters pointed to cannot be changed

• The pointer itself can be changed

• Allocating enough memory to store the results is the responsibility of the caller

• This function takes two strings as arguments, concatenates them, and puts the result in s1

• The programmer must ensure that s1 points to enough space to hold the result

• The string s1 is returned

char *strcat (char *s1, const char *s2);

• The strings are passed as arguments, and neither one is changed by the function

• An integer is returned that is less than, equal to, or greater than zero, depending on whether s1 is lexicographically less than, equal to, or greater than s2

int strcmp (const char *s1, const char *s2);

• The string s2 is copied into s1 until (and including) the character '\0'

• Whatever exists in s1 is overwritten

• It is assumed that s1 has enough space to hold the result

• The value s1 is returned

char *strcpy (char *s1, const char *s2);

• The strdup() function returns a pointer to a new string which is a duplicate of the input string s

• Memory for the new string is obtained with malloc(), and can be freed with free()

char *strdup (const char *s);

• This function simply counts the number of characters in the string

• The character '\0' is not included in the count

• Note that in C the size of the string is not kept, and must be recomputed every time

size_t strlen (const char *s);

• Looks for the first occurrence of the character c inside the string s

• Returns a pointer to the position in the string where c was found

char *strchr (const char *s, int c);

• Looks for the first occurrence of the sub-string s2 inside the string s1

• Returns a pointer to the beginning of s2 within s1

char *strstr (const char *s1, const char *s2);

Example – String Functions

#include <string.h>

int main() {

char *question = "Do you want to understand?";

you = strstr (question, "you");

strcpy (q_mark, " something,\ntry to change it.");

}

If you want to understand something,

try to change it.

• Strings and characters

• String functions in the standard library

• sizeof Revisited

• Multidimensional arrays

• Pointers to pointers and pointer arrays

• Pointers to functions

sizeof Revisited

• As we have seen, the sizeof operator can be applied to variables or to types

• sizeof can also be applied to arrays

• In this case, it returns the size of the memory occupied by the complete array

• This only works for static arrays – will not work for pointers

sizeof String – Example

#include <stdio.h>

int main() {

char *question = "Do you want to understand?";

printf ("question size: %d\n", sizeof (question));

return 0;

}

Size of question: 4

sizeof Example Explained

• sizeof is a compile-time operator

• It cannot know in advance where question will point to during run-time

• answer is an array, which is essentiallya constant pointer to static memory

• Therefore, answer will always point to the same 80 character memory block

sizeof Array – Example 1

int main() {

int a[] = {12, 32, 434, 43, 26, 873, 43};

int array_size = sizeof (a) / sizeof (int);

int i;

printf ("Size of a: %d\n", sizeof (a));

for (i = 0; i < array_size; i++)

printf ("%d ", a[i]);

printf ("\n");

}

Size of a: 28

12 32 434 43 26 873 43

sizeof Array – Example 2

int main() {

double a[] = {12, 32, 434, 43, 26, 873, 43};

int array_size = sizeof (a) / sizeof (int);

int i;

printf ("Size of a: %d\n", sizeof (a));

for (i = 0; i < array_size; i++)

printf ("%.0f ", a[i]);

printf ("\n");

}

Size of a: 56

12 32 434 43 26 873 43 0 -1 0 -1 0 0 -1

sizeof Array – Example 3

int main() {

double a[] = {12, 32, 434, 43, 26, 873, 43};

int array_size = sizeof (a) / sizeof (a[0]);

int i;

printf ("Size of a: %d\n", sizeof (a));

for (i = 0; i < array_size; i++)

printf ("%.0f ", a[i]);

printf ("\n");

}

Size of a: 56

12 32 434 43 26 873 43

• Strings and characters

• String functions in the standard library

• sizeof Revisited

• Multidimensional arrays

• Pointers to pointers and pointer arrays

• Pointers to functions

• The C language allows arrays of any type, including arrays of arrays

• With two bracket pairs, we can obtain a two-dimensional array

• This idea can be iterated to obtain arrays of higher dimension

int a[100]; /* a one-demensional array */

int b[2][7]; /* a two-dimensional array */

int c[5][3][2]; /* a three-dimensional array */

• Elements of a two dimensional array are stored contiguously one after the other

• However, it is convenient to think of the array as having rows and columns

• To define an array with 3 rows and 5 columns:

int a[3][5];

• Like simple arrays, multidimensional arrays can be initialized with a list of literals:

int main() {

int array[3][5] = { { 1, 3, 5, 7, 9 },

{ 11, 13, 15, 17, 19 },

{ 21, 23, 25, 27, 29 } };

printf ("sum: %d\n", sum (array));

return 0;

}

sum: 225

Two-dimensional Arrays – Formal Parameter Declaration

• The compiler only needs to know the number of elements in each row, so the parameter could be defined as either of:

int sum (int a[3][5]) {

int i, j, sum = 0;

for (i = 0; i < 3; ++i)

for (j = 0; j < 5; ++j)

sum += a[i][j];

return sum;

}

int a[3][5]

int a[][5]

int (*a)[5]

• To access an element in the array, we use:

• The following expressions are equivalent:

a[i][j]

*(a[i] + j)

(*(a + i))[j]

*((*(a + i)) + j)

*(&a[0][0] + 5*i + j)

Two-dimensional Array Access – Example

a[0][0]

(*(a + 1))[4]

a[1][2]

*a[1]

*(a[2] + 1)

*(a[0] + 12)

*(&a[0][0] + 5*2 + 4)

Two-dimensional Array Access – Example

• a is an array of size 3

• Each element of a is an array of size 5

• For example, a[1] is an array of 5 integers

• a[1]+2 moves two integers (or 8 bytes) forward – the result is an array of integers

• a+2 moves 10 integers forward, since each element of a is an array of 5 integers

• Strings and characters

• String functions in the standard library

• sizeof Revisited

• Multidimensional arrays

• Pointers to pointers and pointer arrays

• Pointers to functions

• In C, pointers are just another type of variables

• Therefore, they can be stored in arrays,or pointed to by other pointers

• A pointer which points to another pointer will have a special type, such as:

int **ppi;

Pointers to Pointers – Example

• When we wanted to swap between two variables, we used pointers

• Similarly, when we want to swap between pointers, we will need pointers to pointers:

void swap_char_ptrs (char **ppx, char **ppy) {

char *tmp;

tmp = *ppx;

*ppx = *ppy;

*ppy = tmp;

}

Pointers to Pointers – Example

int main() {

char *first = "Hello, world!\n";

char *second = "Goodbye, world...\n";

swap_char_ptrs (&first, &second);

printf (first);

printf (second);

return 0;

}

Goodbye, world...

Hello, world!

• The array used in the sum example could have been defined as a pointer array:

b[0]

b[1]

b[2]

• The syntax of C may cause some confusion between a two-dimensional array and an array of pointers

• Both a[1][2] and b[1][2] are syntactically legal references to a memory location of type int

int a[3][5];

int *b[3];

• The definition of a allocates 15 int-sized memory locations

• The space of any unused array slots is wasted

• The definition of b only allocates 3 pointers, which should be initialized

• The space allocated for the pointers themselves is wasted, but the (larger) space for array slots can be accurately allocated

• A ragged array is an array of pointers used as a two-dimensional array

• Requires allocating memory for each row

• Can save space when row sizes differ

• Makes it possible to operate on complete rows, and not only on individual cells

Ragged Arrays – Example

int main() {

char in_word[MAX_WORD_LEN];

char *words[MAX_WORDS];

int len, cnt = 0;

while (scanf ("%s", in_word) == 1) {

len = strlen (in_word);

words[cnt] = malloc ((len+1) * sizeof(char));

strcpy (words[cnt], in_word);

cnt++;

}

sort_words (words, cnt);

print_words (words, cnt);

}

Ragged Arrays – Example

void sort_words (char *w[], int n) {

int i, j;

for (i = 0; i < n; i++)

for (j = i + 1; j < n; j++)

if (strcmp (w[i], w[j]) > 0)

swap_char_ptrs (&w[i], &w[j]);

}

void print_words (char *w[], int n) {

int i;

for (i = 0; i < n; i++)

printf ("%s ", w[i]);

printf ("\n");

}

• Pointer arrays may be initialized not only dynamically, but also statically:

• The syntax is similar to the initializationof a two-dimensional array:

char *words[] = {

"this", "is", "a", "list", "of", "words" };

char words[][10] = {

"this", "is", "a", "list", "of", "words" };

Initialization of Pointer Arrays – Example

• We could have written our word sorting program to work on a static list of words:

int main() {

char *words[] = {

"this", "is", "a", "list", "of", "words" };

int cnt = sizeof (words) / sizeof (char *);

sort_words (words, cnt);

print_words (words, cnt);

}

a is list of this words

• Strings and characters

• String functions in the standard library

• sizeof Revisited

• Multidimensional arrays

• Pointers to pointers and pointer arrays

• Pointers to functions

• In C, pointers can point to anything, including functions

• Pointers to functions can be used just like any other pointers. They can be:

• Used in assignments

• Placed in arrays

• Passed as arguments

• Returned by functions

• To define a variable of type pointer to function, we use a definition such as:

• This sets up f_ptr as a pointer to a function that accepts no arguments, and returns int

• The parenthesis in the definition are mandatory

int (*f_ptr)();

Pointers to Functions – Example

#include <math.h>

#define PI 3.14159265358979323846

double my_tan (double x);

int main() {

double x = PI / 4;

double (*f)(double x);

f = sin;

printf ("f(x): %f\n", (*f)(x));

f = cos;

printf ("f(x): %f\n", (*f)(x));

f = my_tan;

printf ("f(x): %f\n", (*f)(x));

} ...

Pointers to Functions – Example

• The printf lines are similar, but the result is different each time, because the value of f changes

...

double my_tan (double x) {

return sin(x) / cos (x);

}

f(x): 0.707107

f(x): 0.707107

f(x): 1.000000

• Without the parenthesis f will be a function returning pointer to double:

• On the other hand, in the usage of f the parenthesis can be dropped:

is equivalent to:

• The parenthesis are used for clarity andfor consistency with the definition

double *f(double x);

(*f)(x)

f(x)

• We define a function that accepts a pointer to another function as an argument

• The passed function is then activated:

#include <math.h>

#define PI 3.14159265358979323846

double square_f (double (*f)(double y), double x) {

double f_val = (*f)(x);

return pow (f_val, 2);

}

...

...

double identity (double x) { return x; }

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

double x = PI / 4;

printf ("sin(PI/4)^2: \t%f\n", square_f (sin, x));

printf ("cos(0)^2: \t%f\n", square_f (cos, 0));

printf ("2^2: \t%f\n", square_f (identity, 2));

}

sin(PI/4)^2: 0.500000

cos(0)^2: 1.000000

2^2: 4.000000

• Finally, we show how function pointers can be used as array elements

• This can significantly increase the flexibility of the program

• Can be useful, for example, to define the behavior of different menu items, by assigning a function to each button

Arrays of Pointers to Functions – Example

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

double val, res = -1;

char func_name[MAX_WORD_LEN];

char *func_names[] = {"sin", "cos", "tan"};

double (*funcs[])(double) = {sin, cos, tan, exit};

int i, n = sizeof (func_names) / sizeof (char *);

while (scanf ("%s %f", func_name, &val) == 2) {

for (i = 0; i < n; i++)

if (!strcmp (func_names[i], func_name))

break;

res = (*funcs[i])(val);

printf ("%f\n", res);

}

}

• One of the weaknesses of C is that variable declarations may become too complex

• In the previous example, it is not easy to understand what is the type of funcs

• If we define a function pointer as:

then the definition of funcs is simplified:

typedef double (*Func_ptr)(double);

Func_ptr funcs[] = {sin, cos, tan, exit};