220 likes | 333 Views
CSSE221: Software Dev. Honors Day 27. Announcements Projects turned in? The 2 required Angel surveys are due by 9 pm tonight. Graded based on thoughtful responses Questions? We will cover everything you need to know to do parts 1-3 of C Projects over the weekend. This week: Intro to C.
E N D
CSSE221: Software Dev. Honors Day 27 • Announcements • Projects turned in? • The 2 required Angel surveys are due by 9 pm tonight. • Graded based on thoughtful responses • Questions? • We will cover everything you need to know to do parts 1-3 of C Projects over the weekend.
This week: Intro to C • Monday: • Project day • Tuesday: • Introduction to C • Thursday: • (15 min) Simple C File I/O • (30 min) Pointers and using them to change arguments passed to functions. • (20 min) Arrays and pointer arithmetic • (15 min) Dynamic memory allocation
1. File handling Open a file using fopen • Returns a file pointer to access the file: FILE* • Modes: • “r” (read) • “w” (write) • “a” (append) A few more file handling functions: • fprintf - write to the stream in the format specified. • fscanf - read from the stream. Returns the number of items read, which can be used in a loop termination condition. • fclose - close the file and return the file pointer. • fgets - gets a whole line at a time • feof - returns true (1) after an fscanf fails (useful for error-checking) Defined in stdio.h (fgets in ctype.h) Let’s try one together (hidden slides available if you want more info later)
2. Can functions modify arguments? • In Java, no! (pass by value) • Consider this function: void increment(int takeMeHigher){ takeMeHigher ++; } • How is this C function invoked? • increment(up); • Will calling the function change the values of the arguments up?
References to simple variables double change = 0.45; double *pChange; pChange = &change *pChange = .62; // makes change == .62 int num = 4; int *pNum; pNum = # *pNum == num == 4 pNum: pChange: num: change: //// 0.62 4 . . . 0.45 Pointers need to be used to change the value of an argument A pointer is a variable that holds the address of a variable
Recap: Pointer Operators, & • The address operator, &: • &var gives the address where var's value is stored • Examples: • xPtr = &x;/* Read "xPtr gets the address of x" */ • dPtr = &d;/* Read "dPtr gets the address of d" */
Recap: Pointer Operators, * The format string, "%d", says that we want to print an int. *xPtris the thing pointed to by xPtr. That is, *xPtris the value of x. This says that the thing pointed to by dPtr should get the value 3.14159. So the result is the same as d = 3.14159. • Use * two ways: • In type declarations, * says that the name refers to address of something: int *xPtr; double *dPtr; • In expressions, *var gives the "thing" pointed to by var • printf("%d", *xPtr); • *dPtr = 3.14159;
3. Pass pointers if you want to change arguments • How do we modify increment() so that it actually changes the values of its argument? • By passing pointers to the parameters to be changed • You’ll do this with increment and swap shortly.
Hands-on activity • Checkout project CDemos/PointerSandbox from SVN • Let’s start on Q1 together • Then finish through Q5.
Pass pointers if you want to change arguments /* Actually modifies the values of the variables its parameters point to. */ void swap(int* x, int* y) { int temp = *x; *x = *y; *y = temp; } Note also what we passed: swap(&a, &b)
Another look at the use of & in scanf int x, y; scanf("%d %d", &x, &y); What would happen if we used y instead of &y?
Using Pointers to "Return" Multiple Results This says that the thing pointed to by mean should get the value stored in meanValue. • C only allows us to return one value from a function • Can use pointers to return multiples • Suppose we want a function that takes an array and returns the mean, min, and max values: • void calcStats(double[ ] values, int count, double *mean, double *min, double *max) {/* … some logic omitted …*/ *mean = meanValue; *min = minValue; *max = maxValue;}
Pointer Pitfalls • Don't try to dereference an unassigned pointer: • int *p;*p = 5; /* oops! */ • Pointer variables must be assigned address values. • int x;int *p = x; /* oops, RHS should be &x */ • Be careful how you increment • *p +=1; /* is not the same as … */ • *p++;
Pointers to structs…and a nifty shorthand Passing pointers to structs to methods is more efficient (the whole struct doesn’t get copied): juan = makeStudent(“Juan”, 2007, 3.2); printGPA(&juan); void printGPA(Student *s) { printf(“%4.2lf\n”, (*s).gpa); } typedef struct{ char*name;intyear;doublegpa; } Student; printf(“%4.2lf\n”, s->gpa); If you need to dereference a pointer to a struct and use the dot operator, use -> instead: (*s).f == s->f
Break • Starring Binky! • (See http://cslibrary.stanford.edu/104/)
4. Arrays and Pointer Arithmetic int a[10]; See below instead a: a[0] a[1] a[9] int *pa; So *(pa + 1) == ______ and pa + 1 == ______ And pa and a can almost be used interchangeably… Except the value of pa can be modified, but a can’t. pa = &a[0]; pa: pa + 5: pa + 1: a: a[0] a[1] a[9]
Arrays as function parameters • int [ ] and int * are equivalent, when used as parameters in a function definition. • void f (int a[], int count) { … • void f (int *a, int count) { … • Note that in neither case can we know the size of the array, unless it is passed in as a separate parameter. • In either case, the 5th element of a can be referred to as • a[5] • *(a+5)
Back to the Hands-on activity • First, let’s see in the debugger that arrays and pointers are the same. • Q6 asks you to fill an array with data, then display it. I want you to do this using subscripts, then again using pointer arithmetic.
Explicit allocation and de-allocation by user using malloc() and free(). Functions: (void *) malloc(size_t size); void free(void *ptr); bytes sizeof(type) void* is a “generic” pointer. malloc returns a chunk of memory that can be used as any type. We must cast the results of malloc to the type that we want, like (double*). #include <stdio.h> int main() { int *ptr; /* allocate space to hold 4 ints */ /* do stuff with the data */ ptr[3] = 4; //or *(ptr+3)=4; /* free up the allocated space */ return 0; } 5. Dynamic Memory Allocation
Explicit allocation and de-allocation by user using malloc() and free(). Functions: (void *) malloc(size_t size); void free(void *ptr); bytes sizeof(type) void* is a “generic” pointer. malloc returns a chunk of memory that can be used as any type. We must cast the results of malloc to the type that we want, like (double*). #include <stdio.h> int main() { int *ptr; /* allocate space to hold 4 ints */ ptr=(int*)malloc(4*sizeof(int)); /* do stuff with the data */ ptr[3] = 4; //or *(ptr+3)=4; /* free up the allocated space */ free(ptr); return 0; } 5. Dynamic Memory Allocation
int *ptr; ptr ? 6000 4 4000 ptr = (int*)malloc(4 * sizeof(int));//Address 6000 on the heap is allocated *ptr=4; free(ptr); Final note: If there is no more memory available, malloc will return NULL, so it’s good to check for thiscase.
Last hands-on activity • Q7 asks you to write code that uses a dynamic array.