pointers and arrays c and data structures baojian hua [email protected]

38
Pointers and Arrays C and Data Structures Baojian Hua [email protected]

Post on 21-Dec-2015

232 views

Category:

Documents


2 download

TRANSCRIPT

Pointers and Arrays

C and Data StructuresBaojian Hua

[email protected]

Pointers and Addresses

Think the memory as a big array With each slot a distinct address In these slides, I’ll use pseudo-

address A pointer is a variable that

contains a memory addressx

?

?

?

?

p

1000

1004

1008

1012

1016

Pointers and Addresses// in C’s syntax:

// x is declared as an integer

int x = 88;

x=88

?

?

?

?

1000

1004

1008

1012

1016

Pointers and Addresses// in C’s syntax:

// x is declared as an integer

int x = 88;

// p is declared as a pointer to an integer

int *p;

x=88

?

?

?

?

p=???

1000

1004

1008

1012

1016

Pointers and Addresses// in C’s syntax:// x is declared as an integerint x = 88;// p is declared as a pointer to an integerint *p;

// p points to xp = &x;

// Question: could we write this?p = (int *)1000;

x=88

?

?

?

?

p=1000

1000

1004

1008

1012

1016

Dereference// symbol * has another meaning as dereference

int x = 88;

int *p; // p’s value is junk

p = &x;

// *p takes the value in

// the memory slot p points to

int y = *p;

x=88

?

?

?

?

p=1000

1000

1004

1008

1012

1016

Dereferenceint x = 88;

int *p;

p = &x;

// here, *p and x denotes the same memory slot

// as we can see:

*p = 99;

// or try this:

++(*p);

x=99

?

?

?

?

p=1000

1000

1004

1008

1012

1016

Pointer Assignment// Pointers are just ordinary variables, so

// they could also be used in assignment

int x = 88;

int *p, *q, *r;

p = &x;

q = p;

r = q + 1;x=88

?

?

?

?

p=1000

1000

1004

1008

1012

1016

q=1000

r=1004

Pointers and Function Arguments// C uses call-by-value strategy. So arguments

// from caller are not changeable. Consider:

void swap (int x, int y)

{

int temp;

temp = x;

x = y;

y = temp;

}

// and a call:

swap (a=3, b=5); a==3 b==5

x==3 y==5

Pointers and Function Arguments// C uses call-by-value strategy. So arguments

// from caller are not changeable. Consider:

void swap (int x, int y)

{

int temp;

temp = x;

x = y;

y = temp;

}

// and a call:

swap (a=3, b=5); a==3 b==5

x==5 y==3

Pointers and Function Arguments// To achieve this using pointers:

void swap (int *x, int *y)

{

int temp;

temp = *x;

*x = *y;

*y = temp;

}

// and a call:

swap (&a, &b);a==3 b==5

x:2000 y:8400

Pointers and Function Arguments// To achieve this using pointers:

void swap (int *x, int *y)

{

int temp;

temp = *x;

*x = *y;

*y = temp;

}

// and a call:

swap (&a, &b);a==5 b==3

x:2000 y:8400

Pointers and Function Arguments

In summary, pointer arguments make it possible: to access data in the caller to change values of arguments to return values implicitly

See next slide for an example

Pointers and Function Arguments// implicit returned values:

void sum (int x, int y, int *result)

{

*result = x + y;

return;

}

// the caller:

int s;

sum (3, 4, &s);

// everywhere in system code

Pointers and Arraysint a[5];

int *p;

p = &(a[0]);

?

?

?

?

?

p

0

1

2

3

4

a

Pointers and Arraysint a[5];

int *p;

p = &(a[0]);

// the assignments

*p = 88;

// and

a[0] = 88;

// take the same effect

88

?

?

?

?

p

0

1

2

3

4

a

Pointers and Arraysint a[5];

int *p;

p = &(a[0]);

// we could also do arithmetic

// operations on pointers, as in:

*(p+1) = 77;

// recall that the compiler automatically moves

// the pointer p to an appropriate location.

88

77

?

?

?

p

0

1

2

3

4

a

Pointers and Arraysint a[5];

int *p;

p = &(a[0]);

// By definition, the value of an

// array variable a equals the address

// of a’s first element. So the above

// code is equivalent to:

p = a;

// However, a is not changeable, this is illegal:

a++;

88

77

?

?

?

p

0

1

2

3

4

a

Arrays as Function Arguments// array as function argument is essentially a

// pointer to the first element of the array. So

void foo (int a[])

{

…;

}

// could also be written as:

void foo (int *a)

{

…;

}

Address Arithmetic// More forms of address arithmetic:int *p;int i;// increment:p + i;// decrement:p – i;// substractionint *q;p – q;// or:q – p;

Character Pointers and Functions// Recall that a string s is a sequence of// characters terminated with a null char \0. And// the storage it occupies is one more than the// characters in the string. So,“hello, world”// will occupy 12 bytes, rather than 11.

// Any string s passed as argument to a function // is the address of the first element of s. Soprintf (“hello, world\n”);// could roughly reads:char *s = “hello, world\n”;printf (s);

String Copy// copy from src to dstvoid strCopy (char *dst, char *src){ int i = 0;

// recall the relationship between pointer// and array

while (dst[i]=src[i]) i++; return;}

String Copy// A pointer-based version:void strCopy (char *dst, char *src){ while (*dst=*src) { dst++;

src++;}

return;}

String Copy// Or even:void strCopy (char *dst, char *src){ while (*dst++ = *src++) ;

return;}

Pointer Arrays; Pointers to Pointers // An array could contain pointers, as in:

int *(a[10]);

// a is an array containing 10 pointers to

// integers. And we may write a summation func:

sum = 0;

for (int i=0; i<10; i++)

sum += *(a[i]);

Pointer Arrays; Pointers to Pointers // Pointer Arrays to string:char *(a[10]);// a print function printing all stringsfor (int i=0; i<10; i++) printf (“%s\n”, a[i]);// Rethink the prototype of main function:int main (int argc, char *argv[]);// argc is the numbers of command arguments,// including the name of the executable, with all// arguments (an array of pointers to string) // stored in argv.

Pointer Arrays; Pointers to Pointers // Sample program:int main (int argc, char *argv[]){

for (int i=0; i<argc; i++) printf (“argv[%d]=%s\n”, i, argv[i]);

return 0;}

// Compile this program, and// run it (on Linux):$./a.out hello world// or (on Windows):c:\a.exe hello world

Pointers to Functions Besides for calling, in essence, a C function

could be: assigned to other variables stored in data structures passed as arguments returned from functions But could not nest

Though some compilers support this feature In the following slides, we’d see how to do all

these really cool things Essential to understand OO languages, say C++ or

Java And functional languages, say ML or F#

What’s a Function in Memory?// A function is // essentially a // pointer!int sum (int x, int y){ int temp;

temp = x + y; return temp;}

// Roughly as right:

temp=x+y

?

return temp

?

sum:

10001004100810121016

Function Variable Declaration// Syntax for Function variable declaration:type (*name)(type1, …, typen);// Example:int (*f) (int, int);

// Or, much simpler: :-)typedef type (*tyName) (type1, …, typen);tyName fName;// Example again:typedef int (*tyFun) (int, int);tyFun f;

// We’d like to discuss “typedef” in next slide, // for now, I’ll make use of the raw form.

Function Variable Assignmentint sum (int x, int y){

int temp = x + y; return temp;}

int main () { int (*f1)(int, int);

int (*f2)(int, int);

f1 = &sum;f2 = sum;

return 0;}

temp=x+y

?

return temp

?

sum:

10001004100810121016

f1

f2

Function Variable Callint sum (int x, int y) {

int temp = x+y; return temp;}int main() {

int (*f)(int, int);

f = sum; f (3, 4);

(*f) (7, 8); // another form return 0;}

Function as Arguments// We cook a “higher order” functions:int hf (int x, int y, int (*f)(int, int));

// And the sameple definition of “high”:int hf (int x, int y, int (*f)(int, int)){ return f (x, y);}

Function as Arguments// First, I cook some functions:int sum (int i, int j) { return i+j;}

int mult (int i, int j) { return i*j;}// Now I may call function “hf” with:hf (3, 4, sum);// orhf (3, 4, mult);

Function as Return Values// Functions can return functions:int (*f(int)) (int, int);

int (*f(int kind)) (int, int) { switch (kind) {

case 0: return sum;case 1: return mult;default: error (“…”); return NULL;};

}

Functions Stored in Data Structures// As the function name is just a pointer, so it // is possible to store functions in any other // data structures.// For instance:int (*A[3])(int, int);// declares a 3-element array A, with each slot a// function of type “int * int -> int”.// Sample operations on this array A:A[0] = sum;A[1] = mult;A[2] = sum;// … and a call:A[1](8, 9);

Function Pointer Beyond(Note: This is NOT C)// Nested functions:int (*foo (int x))(int, int){

int local = 100;int bar (int y){ return local+y;}return bar;

}// And a call:foo (3)(4);// Why C does not support this feature?

Summary Function pointers make functions first-class:

assignment passed as arguments, returned as results stored in data structures

This mechanism make it possible to implement call back or dynamic code dispatch think objects and methods in C++/Java/C# more on this topic later