CS110_07a_ptrFuncs - EECS110: 7a Pointers, Functions &...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: EECS110: 7a Pointers, Functions & Memory Jack Tumblin [email protected] . (Recall) Example III void my_swap3(int *pa, int *pb); int main (void) { int x=10, y=25; int *px, *py; px = &x; py = &y; swap3(px, py); return 0; } void swap3(int *pa, int *pb) { int tmp; tmp = *pa; *pa = *pb; *pb = tmp; } Computer Memory address var name: value 900: x: 904: y: 10 25 908: px: 900 912: py: 916: pa: 904 900 PY PY CO CO PY PY CO CO 920: pb: 904 924: (Recall) Function Calling Details Actual arguments == The values used during function calling (a.k.a. actual parameter) Formal parameters == The function's local variables in the argument list (these vars. are declared in the function prototype). actual arguments int main(void) { add(3,4); return 0; } formal parameters int add (int x, int y) { return (x+y); } (Recall) Function Calling Details At the start of a function call, The actual arguments are copied to the formal parameters (an assignment) IMPORTANT! Know these two terms well! IMPORTANT formal parameters actual arguments int main(void) { add(3,4); return 0; } int add (int x, int y) { return (x+y); } (Recall) Function and Arrays The actual argument below is an array name; it holds address of 0th byte in array, (a constant) The formal parameter is a local array name; copies the address from the argument actual argument int main(void) { double arr[2]={0.0,0.0}; dset(arr,1); return 0; } formal parameter void dset(double x, int y) { x[y] = 42.0; } `Pass by Reference' Parameter y copies a VALUE to use in function Important Jargon: `pass by value' Parameter x copies the ADDRESS of value(s) to use; it `refers' to the values without copying them. Important Jargon: `pass by reference' actual int main(void) arguments { double arr[2]={0.0,0.0}; dset(arr,1); return 0; } formal parameters void dset(double x, int y) { x[y] = 42.0; } `Pass by Reference' Array arguments are `passed by reference' to functions--and can be BOTH input & output. (both main() and dset() can set array element values). Pointers let us pass ANY data by reference... actual arguments int main(void) { double arr[2]={0.0,0.0}; dset(arr,1); return 0; } formal parameters void dset(double x, int y) { x[y] = 42.0; } `Pass by Reference' Function arguments that are pointers (or array names) Copy an address to the formal parameters Indexing formal parameter lets us modify the value at or near the pointer `pass by reference' int main(void) { double val=1.234; double *pd; actual arguments formal parameters void dfixit(double *x) { x[0] = 42.0; } pd = &val; dfixit(&val); return 0; } `Pass by Reference' Subtlety For function arguments that are pointers Copy an address to the formal parameters: one-way But changing formal parameter (the address) in the function NEVER changes the actual argument! main (void) { double val=1.234; double *pd; actual argument pd = &val; dfixit(pd); // now val=42.0 // pd unchanged formal parameters void dfixit(double *x) { x[0] = 42.0; x++; // move!? } NO! } Can't change pd! `Pass by Reference' Compact, fast, efficient (copies just the address, not all the data) Powerful: arguments can be input, output, or both !DANGER! Gave a function some invalid pointer arguments? Expect the worst kinds of havocthe wrong thing stored in the wrong place at the wrong time!! Pointer Return Types Functions whose return type is a pointer? HOW: function prototype looks like this: char* findNextVowel( char* str); ! MORE POINTER DANGER ! A function's variables are local andignores whitespace A matter of style: C temporary; char* findNextVowel( char* str they may vanish when you leave the function ); char *findNextVowel( char* str); Don't return pointers to local variables! char* findNextVowel( char *str); char *findNextVowel( inputs Better idea: return pointers received as char *str); (a very common practice. See examples in book) Try again: Never return pointers to local variables UNLESS you used the `static' keyword... Pointer Return Types Functions whose return type is a pointer? HOW: function prototype looks like this: char* findNextVowel( char* str); ! MORE POINTER DANGER ! A function's variables are local andignores whitespace A matter of style: C temporary; char* findNextVowel( char* str they may vanish when you leave the function ); char *findNextVowel( char* str); Don't return pointers to local variables! char* findNextVowel( char *str); char *findNextVowel( inputs Better idea: return pointers received as char *str); (a very common practice. See examples in book) Tumblin Recommends Try again: Never return pointers to local variables (clarity, consistency) used the `static' keyword... UNLESS you Pointer Return Types Functions whose return type is a pointer? HOW: function prototype looks like this: char* findNextVowel( char* str); ! MORE POINTER DANGER ! A function's variables are local and temporary; they may vanish when you leave the function Don't return pointers to local variables! Better idea: return pointers received as inputs (a very common practice. See examples in book) Try again: Never return pointers to local variables UNLESS you used the `static' keyword... Pointer Return Types Functions whose return type is a pointer? HOW: function prototype looks like this: char* findNextVowel( char* str); ! MORE POINTER DANGER ! A function's variables are local and temporary; they may vanish when you leave the function Don't return pointers to local variables! Better idea: return pointers received as inputs (a very common practice. See examples in book) And again:Never return pointers to local variables UNLESS you used the `static' keyword... Function & Pointer: Caution I int main (void) { int *pscore; int num[2]; void Jprnt(int *ptr) { (copy value of pscore (an address) into ptr num[0] = 32; num[1] = 16; pscore = num; Jprnt(pscore); *pscore = 5; return 0; } printf("%d", *ptr); ptr = ptr+1; } USELESS! Jprnt() exits, and ptr dies! pscore pointer was not changed by the Jprnt() function! Function & Pointer: Caution II int main(void) { int *pscore, num; num = 32; pscore = incr(num); *pscore = num; return 0; } int *incr(int x) { x = x+10; return &x; } !!NOOOO!!! When incr() exits, variable x dies! Out of scope; its memory may get reassigned to a different variable, maybe now, later, or never. Main function LOOKS ok, but isn't; pscore is now an invalid pointer, but you'll get no error DEBUG NIGHTMARE! message and no warning. static keyword static static static int i; // double arr[5]; // void setKey(int *a); // put before data type OK for arrays & ptrs and functions too... WEIRD! (at least) 2 meanings: 1) "only accessible from inside this module", or (`module' is one .c file and it's .h file interface) interface Sets scope for functions; can't call them except from within this file And scope for `global' variables, `global' arrays (See pg. 359, 410) 2) "Always keep this named memory valid" For local variables, declared within a function DIFFERS from global variable; name can STILL go out-of-scope But pointers to it (set when name was in-scope) always work! static keyword static static static int i; // double arr[5]; // void setKey(int *a); // put before data type OK for arrays & ptrs and functions too... WEIRD! (at least) 2 meanings: 1) "only accessible from inside this module", or (`module' is one .c file and it's .h file interface) interface Sets scope for functions; can't call them except from within this file And scope for `global' variables, `global' arrays (See pg. 359, 410) 2) "Always keep this named memory valid" For local variables, declared within a function DIFFERS from global variable; name can STILL go out-of-scope But pointers to it (set when name was in-scope) always work! static Example int* magic_num(int strt); // prototype int main(void) { int i=0, *pI; // ptr to integer pI = magic_num(i); printf("random 4fib=%d\n",*pI); return 0; Result: } int* magic_num(int strt) { static int keep[9] = {0,1,2,3,5,8,13,21,34}; int *pOut; pOut = keep + strt + rand()%4; keep array stays valid in memory, but return(pOut); } strt and pOut do not. not >random 4fib=3 > How Can Pointers Claim Memory? An array resides in a named block of memory. Array size is constant: fixed when array is declared. int list[4]; list d n 0 0 0 3 z p 0 0 0 1 0 0 0 6 0 0 0 4 0 0 0 8 j list[0] list[1] list[2] list[3] Pointers p1 can point to blocks of memory (like a movable array name) but have no elements of its own. how can they get their own memory blocks to control? What if you want to vary array size, or choose array size size after the program starts running? (at `run time'?) Answer: Dynamic Allocation Dynamic Allocation == memory taken and/or released during execution. Dynamic Allocation enables us to : claim a computed # of elements at run time (function: malloc) malloc release all elements you reserved (function: free) free Less important variants (OK to ignore them) can: change the number of elements (function: realloc) realloc claim already-zero-valued memory (function: calloc) calloc Not worth using--slow, inflexible. Write your own... ...
View Full Document

This note was uploaded on 10/05/2011 for the course COMPUTER S 110-1 taught by Professor Tumblin during the Spring '11 term at Northwestern.

Ask a homework question - tutors are online