<<

C for Engineers and Scientists: An Interpretive Approach

Chapter 11: Pointers

Pure awesomeness! 

but remember: With great power comes great responsibility

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. for Engineers and Scientists: An Interpretive Approach

A pointer is defined as a variable which contains the address of another variable or dynamically allocated memory.

Place an asterisk „*‟ in front of the variable name:

int i, *p; Although not mandatory, it‟s good programming style to start or end pointer names with p, or even ptr.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

The Size of Pointer Variables

The variable of pointer type is used to hold an address of memory.

Its size is implementation-dependent, typically: • 4 bytes for 32- machines • 8 bytes for 64-bit machines

It is independent of the variable type that it points to • Pointers to char have the same size as pointers to long long int

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

#include

int main() { char *pc; int *pi; double *pd;

printf("sizeof(char *) = %u\n", sizeof(char *)); printf("sizeof(pc) = %u\n", sizeof(pc)); printf("sizeof(pi) = %u\n", sizeof(pi)); printf("sizeof(pd) = %u\n", sizeof(pd)); return 0; }

Output when the program is executed in a 32-bit machine:

sizeof(char *) = 4 sizeof(pc) = 4 sizeof(pi) = 4 sizeof(pd) = 4

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer Operators & (address operator) – To obtain the address of a variable, add the address operator „&‟ in front of the variable name. int i = 10; int *iPtr; iPtr = &i; //iPtr gets address of i

* (indirection/dereferencing operator) – To declare a pointer, place it in front of the identifier. – To obtain the value of a variable, place it in front of the pointer‟s name. *iptr is the value of i – Can be used for assignment *iptr = 5; // changes i to 5

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer Operators

“The two worlds”

& is the “escalator up” * is the “escalator down”

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer representations

int i = 10; int *iPtr; iPtr = &i; //iPtr gets address of i

iPtr i

iPtr i A000 8000 A000 8000 42 A000 8004 43

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer representations

Indirection

iPtr i

Multiple indirection

iPtrPtr iPtr i

So then the “two worlds” ...

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers#include and Scientists: An Interpretive Approach

void main() { int i, j, *p; //i and j as int, p as pointer to int

i = 10; j = 0; p = &i; //p is assigned the address of i.

printf("The value of i is %d\n", i); printf("The value of j is %d\n", j); printf("The address of i is %p\n", &i); printf("The value of p is %p\n", p); printf("The value of *p is %d\n", *p);

*p = 20; //The memory pointed to by p is assigned 20 j = *p; //j is assigned the value pointed to by p

printf("After indirection operations\n"); printf("The value of i is %d\n", i); printf("The value of j is %d\n", j); printf("The address of i is %p\n", &i); printf("The value of p is %p\n", p); printf("The value of *p is %d\n", *p); }

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Memory layout for two integers and one pointer

p = &i; If the address of i is 0x00E81E20, the value of p is 0x00E81E20 The program performs the indirection operations: *p = 20; j = *p;

BEFORE AFTER

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Output:

The value of i is 10 The value of j is 0 The address of i is 00E81E20 The value of p is 00E81E20 The value of *p is 10 After indirection operations The value of i is 20 The value of j is 20 The address of i is 00E81E20 The value of p is 00E81E20 The value of *p is 20

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Null pointers

What happens if we declare a pointer, but do not initialize it? int *iPtr;

The standard mandates the null pointer: • A null pointer is guaranteed to compare unequal to a pointer to any object • Conversion of a null pointer to another pointer type yields a null pointer of that type • Any two null pointers shall compare equal.

OK, but this still does not say what is the null pointer ... Let’s try to see one!

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach In C99, global and static pointers are initialized by default to null pointers, but auto pointers are not

Probably run-time error

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Null pointers

The C99 standard requires a macro NULL to be defined in stddef.h (implementation-dependent).

This is what I found in MSVC:

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Null pointers

What exactly does a null pointer point to? Memory address zero, but the OS does not allow access to it!

It‟s actually more complicated …

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Common misconception refuted:

The asterisk in declaration is not an indirection operator

int i; int *p = &i; // initializes p, not *p

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

We have covered Section 11.1

Solve in notebook end-of-chapter – 1 – 3

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Lab week 11 - Arrays and pointers

Write programs to do the following: 1. Declare 2 integers, declare 2 pointers to integers, make the pointers point to the integers, print all integers and pointers. 2. Print the integers the other way (using the pointers). 3. Print the pointers the other way (using the integers). 4. Calculate and print the sum of the integers: 1. Using the integers 2. Using the pointers

Conclusion: Any task involving variables can be performed using pointers to those variables!

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Lab week 11 - Arrays and pointers

Conclusion: Any task involving variables can be performed using pointers to those variables!

5. Write a program similar to the one before, to multiply two integers

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Lab week 11 - Arrays and pointers

The part on arrays should be in the second half of the lab, but we had a re-take of the second exam instead.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach 11.2 Pointer Arithmetic The following arithmetic operations can be performed on pointers:

• Add an integer to a pointer

p = p+i; // or even p += i;

The following calculation is performed:

0x008C955C + 2*sizeof(int) = 0x008C9564

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer Arithmetic

• Subtract an integer from a pointer

p = p-i; //or even p -= i;

The following calculation is performed:

0x008C955C - 2*sizeof(int) = 0x008C9554

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer Arithmetic • Increment/decrement pointer (++ or --)

• Subtract pointers from each other (p2-p1) – p1 and p2 must point to the same . – p2-p1 gives the number of elements from p1 to p2 (counting only one end!) – ptrdiff_t is a signed integer type defined in stddef.h

int, really #include ... int a[6], *p1, *p2; ptrdiff_t n; p1 = &a[1]; p2 = &a[4]; n = p2-p1; // n is 3

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Label used by Microsoft in their 32-bit OS to prepare programmers for the transition to the 64-bit OS

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointer Arithmetic

These are all the legal arithmetic operations on pointers. No multiplication, division, integer division or remainder!

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. Cint for Engineers a[6] and = Scientists:{100,200,300,400,500,600}, An Interpretive Approach *p; Pointer arithmetic p = &a[0] ; example printf(“%d”, *p); //100

p += 3;

printf(“%d”, *p); //400 printf(“%d”, *(p+1)); //500 printf(“%d”, *(p -1)); //300 printf(“%d”, *p + 1)); //401

*p = 11; // sets a[3] = 11 The contents of the *(p+2) = 12; // sets a[5] = 12 array at the end *(p -2) = 13; // sets a[1] = 13

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Order of operations

char dest[100], src[100] = “original string”; char *dp = &dest[0], *sp = &src[0];

/* copy src to dest inside function strcpy() */ while(*sp != „\0‟) *dp++ = *sp++;

*dp = „\0‟;

*dp++ = *sp++ is equivalent to *dp=*sp; dp++; sp++;

The pre-increment form *++p increments p, then dereferences it.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Array bounds

When processing arrays using pointers, care must be taken to stay within the range defined for the array.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

11.3 Passing Function Arguments by Reference

• Pointers can be used to pass the addresses of variables to functions and access variables through their addresses indirectly. • Through this method, it is possible to write functions to alter arguments passed into them.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Program 1:

Write a program to swap the values of a and b. Output: #include void swap(int x, int y) { int temp; a = 5, b = 6 temp = x; x = y; y = temp; }

int main() { int a = 5, b = 6;

swap(a, b); printf("a = %d, b = %d\n", a, b); // a = 5, b = 6 return 0; }

Note: Program 1 would does not swap the values of a and b, which are being passed by value (copy!) . It only swaps x and y.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach What is going on in memory? Before swap operations

After swap operations

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Program 2:

#include Output: void swap(int *pa, int *pb) { int temp;

temp = *pa; a = 6, b = 5 *pa = *pb; *pb = temp; }

int main() { int a = 5, b = 6;

swap(&a, &b); printf("a = %d, b = %d\n", a, b); // a = 6, b = 5 return 0; }

Note: This program does swap the values of a and b, and yields a=6 and b=5.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach What is going on in memory? Before swap operations

After swap operations

*pa means a *pb means b

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Example:

Function scanf() uses pointers to pass results through its arguments.

/* File: scanfc.c */ #include

int main() { int num;

printf("Please enter an integer number:\n"); scanf("%d", &num); // pass a pointer to scanf() printf(“Your input number is %d\n", num); return 0; }

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Another use for passing by reference:

Problem: Write a function disc() to calculate the area and circumference of a disc. The radius of the disc is passed as an argument.

Do you notice something unusual?

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Solution: Use arguments to return values!

#include #include /* for M_PI */

/* function disc() calculates area and circumference of a disc with a given radius. */ void disc(double radius, double *area, double *circum) { *area = M_PI * radius *radius; *circum = 2*M_PI*radius; }

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

int main() { double radius; /* radius of the disc */ double area, circum; /* area and circumference of the disc */

/* printf("Enter the radius for the disc (m): "); scanf("%lf", &radius); */ radius = 3.5; /* radius is 3.5 meters */

disc(radius, &area, &circum); printf("area = %f (m^2)\n", area); printf("circumference = %f (m)\n", circum); return 0; }

Output > disc.c area = 38.484510 (m^2) circumference = 21.991149 (m)

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

We have covered Sections 11.2 and 11.3

• Read and understand Program 11.2 (pp.379-381) – getchar() – putchar() • Solve in notebook end-of-chapter – 1, 2, 3

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach A function returning values both ways

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach A function returning values both ways

“Black box” diagram

fractional part of x, returned normally, through x name of function decompose integer part of x, returned through the 2nd parameter, iptr

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach A function returning values both ways

Nitty-gritty precision

?

The C99 standard speaks: “The precision takes the form of a period (.) followed either by an asterisk * (described later) or by an optional decimal integer; if only the period is specified, the precision is taken as zero.”

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach 11.4 Using const Qualifier with Pointers

The type qualifier const can be used to prevent the modification of the object pointed to by a pointer. #include Remember: /* a sample implementation of strcpy() */ char *strcopy(char *dp, const char *sp) { *dp++ = *sp++; char *retp = dp; is equivalent to while(*sp != '\0') *dp = *sp; *dp++ = *sp++; dp++; } *dp = '\0'; sp++; return retp; } void main() { const char *src = “original string"; Output: char dest[100];

strcopy(dest, src); dest = original string printf("dest = %s\n", dest); }

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

FYI: Two places for const

const int *a; read from R to L! int *const a;

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach 11.5 Pointers and Arrays

An array name is a constant pointer!

That‟s why we cannot write That‟s why we can write str++; scanf("%s", str);

Its value is the address of the first element of the array. • instead of p = &a[0]; we can write p = a;

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Subtle trap • If a is the name of an array, a and &a evaluate to the same thing: the address of a[0]. • But if p is a “free-floating” pointer that took the value of a through assignment, p and &p are not the same!

char str[] = "Hello"; char *p = str;

scanf("%s", str); scanf("%s", &str); scanf("%s", p); scanf("%s", &p);

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Conclusion …

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Pointers and Arrays

We can perform array subscripting operations using either the array name or some other pointer(s)

Example: int a[6] = {1,2,3,4,5,6}; int *p; The 3rd element of array a can be accessed in 4 ways: a[2] *(a+2) p[2] *(p+2)

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Pointers and multi-dimensional arrays

Example: (Draw the memory diagram!)

int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; int *p;

p = &a[1][0]; p[0] = 15; // a[1][0] = 15 // *p = 15 *(p + 2) = 17; // a[1][2] = 17 *(p + 5) = 42; // a[2][1] = 42

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach 11.6 Using Pointers to Pass 1D Arrays to Functions

• When an array is passed to a function, what is actually passed is the address of the first element of the array. – Arrays are passed by reference! (Does it make sense? Why?) • In the called function, this argument is a local variable of pointer type. • That is why pointers can be used to pass 1D arrays to functions.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach #include VLA #include #include #include double func(int n, double aa[n]); double func(int n, double *a);

void main() { void main() { double a[5] = {1, 2, 3, 4, 5}; double a[5] = {1, 2, 3, 4, 5}; double b[6] = {1, 2, 3, 4, 5, 6}; double b[6] = {1, 2, 3, 4, 5, 6}; double sum; double c[2][3] = {1, 2, 3, 4, 5, 6}; double sum;

sum = func(5, a); sum = func(5, a); printf("sum = %f\n", sum); printf("sum = %f\n", sum);

sum = func(6, b); sum = func(6, b); printf("sum = %f\n", sum); printf("sum = %f\n", sum);

sum = func(2*3, &c[0][0]); printf("sum = %f\n", sum); } }

double func(int n, double aa[n]) { double func(int n, double *a) { double sum = 0; double sum = 0; int i; int i;

for(i=0; i

The function definition double func(int n, double *a) can be replaced by double func(int n, double a[])

The statement sum += *(a+i); can be replaced by sum += a[i];

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

We have covered Sections 11.4, 11.5, 11.6

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Quiz

int a[5] ={1,2,3,4,5}, *p; p = a+2;

What is the output from each expression below? Draw a memory map!

p[2], p[-2], *p, p[0], *a, *(a+2), a[5], p[10], p[-10], a[10]

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

11.7 Dynamic Allocation of Memory

• A problem with using a fixed-size array is that either the array size is too small to handle special cases, or it is too big and the resource is wasted. • Without using VLAs in C99, this problem can be solved by dynamically allocating memory using the standard functions malloc(), calloc(), and realloc(). The function prototype for malloc() void * malloc(size_t size) • Each allocation of memory yields a pointer to an object that occupies a new area of memory. • The pointer returned points to the start (lowest byte address) of the allocated space.

Example: Remember char *str; ? sizeof ... str = (char *)malloc(100*sizeof(char));

• The return type of function malloc() is a pointer to void. It is typically cast to the pointer type of the lvalue.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

• The sizeof operator can be used to compute the size, in bytes, of a variable or type. It is useful to allocate memory for variables whose sizes may change from one implementation to another. For example, double *dp = (double *)malloc(100*sizeof(double));

• Whenever malloc() is unable to allocate the requested memory, it returns a NULL pointer. • It is important to check the returned value of malloc() when it is called: int *p = (int *)malloc(100*sizeof(int)); if(p == NULL){ printf(”out of memory\n”); return -1; }

Function exits with error code

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

• It is usually a good idea to deallocate memory once it is no longer being used. • Dynamically allocated memory is deallocated with the function free() – If p contains a pointer previously returned by malloc(), the statement free(p) releases the memory dynamically allocated.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

• Sample Problem

The system in Figure1 (a) consists of a single body with mass m moving on a horizontal surface. An external force p acts on the body. The coefficient of kinetic friction between body and horizontal surface is . The freebody diagram for the system is shown in Figure1 (b).

Figure1: The system diagram and FBD of a sample problem

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C/* for File: Engineers acceldynmemory.c and Scientists: An Interpretive*/ Approach #include #include //for malloc() and free() #define M_G 9.81

int accel(int n) { Look Mom, double *a, *t, t0, tf; double mu, m, p; no VLAs! void main() { int i; int retval;

mu = 0.2; m = 5; retval = accel(100); //100 points t0 = 0; if (retval == -1) tf = 10; printf(“Error: function call a = (double *) malloc(sizeof(double)*n); failed.\n”); if(a == NULL) { retval = accel(11); // 11 points printf("Error: not enough memory\n"); if (retval == -1) return -1; printf(“Error: function call } failed.\n”); t = (double *) malloc(sizeof(double)*n); } if(t == NULL) { printf("Error: not enough memory\n"); return -1; } printf(" time accel (m/s^2)\n"); printf("------\n"); If function accel() for(i=0; i

We have covered the first part of Section 11.7

• Read and understand Program 11.9, Copying Strings (pp.396-398) • Solve in notebook end-of-chapter 4

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Lab week 12

Ch.8, Prob.4. Write a function with the prototype int f(void); that prints out n asterisks, where n represents the number of times it has been called. If it is called three times, for instance, the output will be * * * * * * Test the function by calling it five times. (a) Use a static variable inside the function. (b) Use a global variable inside the function.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Lab week 12 int N; int M=90; int funct4(int n){ int i; Ch.10, Prob.4. int m = n; int a[n][n]; Identify and correct the int b[n][m]; errors in the following code int c[printf("%d\n", n)][n]; involving VLAs. int d[n][N]; Briefly explain them. int e[n][M]; int f[n] = {1, 2, 3, 4}; static int g[n]; for(i=0; i

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach int N; Hints … int M=90; int funct4(int n){ int i; int m = n; int a[n][n]; int b[n][m]; int c[printf("%d\n", n)][n]; int d[n][N]; int e[n][M]; int f[n] = {1, 2, 3, 4}; static int g[n]; for(i=0; i

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach int N; int M=90; int funct4(int n){ Yes, printf() does return an integer (the # of int i; characters it prints), but … int m = n; int a[n][n]; int b[n][m]; int c[printf("%d\n", n)][n]; int d[n][N]; Cannot initialize VLAs int e[n][M]; with initializer list int f[n] = {1, 2, 3, 4}; (Why?) static int g[n]; for(i=0; i

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Lab week 12

Ch.10, Prob.38.

1 2 3 1 4 7 1 A 4 5 6 B AT 2 5 8 v 2 7 8 9 3 6 9 3

Write a program to: a. Declare, initialize and print A, B, v. b. Calculate and print the following expressions: vv, A+B, A-B, Av, AB, Abv, 5ABAB, AB(AB+I)

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Quiz

End-of-chapter exercise 4:

Use the function malloc() to do the following: (a) For integer pointer p, allocate memory for a 10- element array. Fill each element with the value of 5, then free the memory.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Quiz

(a) For integer pointer p, allocate memory for a 10- element array. Fill each element with the value of 5, then free the memory Answer:

p = (int *)malloc(10*sizeof(int)); for(i=0; i¡10; i++) p[i] = 5; free(p);

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Quiz

(b) Suppose the variable str was declared as a pointer to char. Allocate enough memory to store the string "This string".

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Quiz

(b) Suppose variable str was declared as a pointer to char. Allocate enough memory to store the string "This string". Answer:

str = (char *)malloc(11*sizeof(char)+1); or str = (char *)malloc( (strlen(”This string”)+1)*sizeof(char));

include string.h

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Function calloc() void *calloc(size_t num, size_t elsize);

It allocates an amount of memory equal to num*elsize.

Unlike malloc(), calloc() initalizes the space allocated with zeros (cleares it).

int *p = calloc(100, sizeof(int));

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Function realloc() void *realloc(void *ptr, size_t size);

It changes the size of the previously allocated memory pointed to by ptr to that specified by size. The value of size may be greater or less than the original.

• If ptr is Null, the call is equivalent to malloc(size). • If size is zero, the call is equivalent to free(ptr). • Returns a pointer to the newly allocated memory, which may be different from ptr • If the function call of realloc() fails, the original block is left unchanged and NULL is returned.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Function realloc() void *realloc(void *ptr, size_t size);

How about the content of the allocated memory? It is copied from the old memory, up tp the lesser of the two.

What if ptr does not point to dynamically allocated memory? The C99 standard speaks: “[…] if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined.”

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach realloc()example

If ptr points to memory allocated for an integer array of 10 elements, the following statement will reallocate memory for the pointer to reduce the size of the array to 5 elements. Memory for the other five elements is returned to the OS for reuse. The first 5 elements of the old array are copied automatically into the new array:

ptr = realloc(ptr, 5*sizeof(int));

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach 11.8 Functions Returning Pointers

int *func(par1, par2);

When a function is passed or returns a pointer, the pointer must point to a global variable or dynamically allocated memory.

• A variable of automatic duration has a local scope. The variable of automatic duration and its associated memory will not be available when the program control is out of the scope. Using a pointer to point to the address of the variable of automatic duration is a programming bug.

• Function can also return a pointer related to an address passed from its argument.

• If the function is called successfully, it returns a valid pointer. Otherwise, it returns NULL.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers#include and Scientists: An Interpretive Approach/* File: returnptr_err.c */ int g = 10; int *fun1(void) { int *p; p = &g; return p; // pointer to global variable } int *fun2(int n) { int *p; p = (int *)malloc(sizeof(int)*n); if(p == NULL) printf("Error: no memory\n"); return p; // pointer to dynamically allocated memory } int *fun3(void) { int i, *p; p = &i; return p; // Error: pointer to auto variable } void main() { int *p; p = fun1(); // ok *p = 10; // g is now 10; p = fun2(); // ok *p = 10; // ok free(p); p = fun3(); // bad *p = 10; // Error: program may crash } Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach 11.9 Pointers to Pointers

A pointer to a pointer is a variable which contains the address of another pointer.

int i; // i is an integer i = 10; int *p = &i; // p points to i int **pp = &p; // pp points to p

Here, **p refers to memory address of pointer p which in turn refers to the memory address of variable i.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Memory map for previous example

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach Important application of ptp: array of strings

char *s1 = "ab"; char *s2 = "py"; char **pp; pp = (char **)malloc(3*sizeof(char *)); //let’s say 4006c8d0 pp[0] = s1; //holds string "ab" pp[1] = s2; //holds string "py" pp[2] = NULL; //holds null 00000000 pp[1][1]; //holds character y

4006c8d0 4006c8d0

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

Another application: perform dynamic allocation of memory through a function

See program on following slide: • The first call to function func() makes a point to the integer g, which is equal to 10. • The second call to func() makes a point to allocated memory for an array of 3 integers.

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach /* File: pointer2.c */ #include #include

int func(size_t n, int **aa); int g=10;

void main() { Output: int *a, status;

*a = 10, a[0] = 10 func(0, &a); // a pointer to g *a = 20, a[0] = 20 printf("*a = %d, a[0] = %d\n", *a, a[0]); status = func(1, &a);// a pointer to allocated memory if(!status) { printf("*a = %d, a[0] = %d\n", *a, a[0]); free(a); } } Wouldn‟t this work int func(size_t n, int **aa) { with just *aa? Why if(n==0) { bother using pointer *aa = &g; to pointer? } else { *aa = (int *)malloc(n*sizeof(int)); if(*aa == NULL) { printf("Error: no memory\n"); return -1; } **aa = 20; //make g 20 } return 0; }

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

We have covered Sections 11.7, 11.8, 11.9

• Read and understand Program 11.9, Copying Strings (pp.396-398)

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved. C for Engineers and Scientists: An Interpretive Approach

SKIP the rest of Ch.11

Homework for Ch.11 Due Monday after Thanksgiving: End of chapter: • 5 (Hint: use ptp!) • 6 • 8 • 9

Created by Harry H. Cheng, 2009 McGraw-Hill, Inc. All rights reserved.