CS/CE 218 Lecture -*- Outline -*- connection: we've finished our survey of the basics of C, the structureless types such as int and double, and the operations on the pc (statements). We've also taken a look at the large scale structure of C programs (separate compilation, information hiding, etc.). Now it's time to look at the facilities for constructing complex data structures in C... * memory, pointers, and arrays advert: this is the key to understanding what really goes on in a program. We'll be studying 3 types: pointers, arrays, and structures (later). ** What you already know (Pascal translation) The main difference between the pointers in Pascal and C is that in Pascal you couldn't point at just anything... /* C */ { Pascal } ----------------------------------------------------- int i; var i: integer; int *ptr; var ptr: integer^; int ai[10]; var ai: array[0..9] of integer; ptr = (int *) malloc(sizeof(int)); new(ptr); *ptr = *ptr + 1; ptr^ := ptr^ + 1; free(ptr); dispose(ptr); ptr = &i; { illegal! } ptr = &ai[0]; { illegal! } ptr = ai; { illegal! } ----------------------------------------------------- ** memory model (how C sees memory cells and addresses) (section 5.1) C was built to give access to memory in a computer Q: How would you describe the memory of a computer? a big array (of characters) indexed by addresses (ints) (draw picture) group chars (bytes) into shorts (2) and longs (4) *** picturing pointers Q: Can you draw a picture for the following code? ------------- char c = 'g'; char *p; p = &c; ------------- p: |----------| c:|---| | ------------> | g | |----------| |---| Q: How do you picture c? Where is &c? &c is the arrow (it's not p) *** operations provided by C Q: How would you describe memory as an abstract data type? values: finite mapping from addresses to characters ops: store(addr, char) fetch(addr) Q: Can you desribe the execution of the statement i = i + 1 in terms of the memory (stores and fetches)? i denotes a memory cell, on the rhs, fetch the value from i, add 1; on the lhs get the address of i, store the value object == variable (cell) or function sometimes called an lvalue (page 197), can appear on lhs of = name == piece of syntax that denotes an object (an identifier) not all objects have names (some are garbage) not all identifiers name objects (e.g., typedefs) address == index into memory, a pointer these are NOT objects, but simply (r)values Ways to convert adresses to objects and vice versa ------------- &: object -> address *: address -> object ------------- Q: Is &c = 'g' legal? What about *(&c) = 'g' ? int i; &i address of i *&i the object i scanf("%d", &i); scanf needs an address (*&i)++ same as i++ (&i)++ illegal! Q: In the following picture p: |----------| c:|---| | ------------> | g | |----------| |---| where is *p? *p is not the arrow, *p is exactly c. &c is the arrow! **** pointers (and pointer variables) are typed as in Pascal Q: How would you explain the syntax of pointer declarations? The type of pointers to int is int *, declaration of variable like int *i; idea: declaration shows how variable is used to get an int similarly: ----------- extern float *truncate(int *, double * d); ----------- Q: What does ptr hold if declared as int *ptr? A variable of type int * holds addresses that point to ints it doesn't hold ints can change such a variable's value by assigning it a value of the same type ------------- int *p, *q, i = 3; p = &i; q = p; ------------- Q: Is the following legal? -------------- int *p; double *q; p = q; -------------- operations given above aren't quite accurate, since addresses are typed &: T -> T* *: T* -> T **** addresses are not the same as integers (however, C evolved from this position) Q: Why not? Not conceptually; for example, an address might be larger than an int it might require special operating system privilages to create So int *p; p = 1; is illegal (and will generally get you in trouble). However, 0 (NULL) is always a legal address only int that can be assigned to a pointer variable *** you can only point at objects, not values (skipped, redundant) Q: Why? That is variables, parts of arrays, etc. or functions So the following are illegal &3 int i; &&i an address is not an object int a[10]; &a array names are just addresses register int i; &i ** using pointers to get call by reference (var parameters) (section 5.2) Q: What is call by value? In C all actual parameters are passed by value; you can get effect of pass by reference (Pascal var) by passing a pointer. (We'll see that an array name denotes a pointer value later.) Q: Why does the function next (below) need a pointer as an argument? ------------- void next(int *ptr) /* effect: increment *ptr by 4 */ { *ptr += 4; } ------------- (consider not having the pointer argument, e.g., ptr += 4) Q: What is printed by the following? ------- extern void next(int *ptr); int i = 3; int *ptr = &i; next(&i); next(ptr); printf("%d %d\n", i, *ptr); ------- point out the aliasing skipped this in lecture, redundant with a quiz More realistic example, extract the code while (isdigit(s[++i] = c = getch())) ; from getop on page 78, where it's used twice... void get_digits(char s[], int * i, int * c) { while (isdigit(s[++*i] = *c = getch())) ; }