pointers and arrays c and data structures baojian hua [email protected]
Post on 21-Dec-2015
232 views
TRANSCRIPT
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]);
// 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;}
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 = ∑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?