Lecture06: Complex Types 4/18/2012 Slides modified from Yin Lou, Cornell CS2022: Introduction to C 1 Administrative Items • Midterm exam in class on 4/25 – Cover from the start to Pointers and Arrays • Assignment #6 due on 5/2 • r, long double, etc. 2 Complex Types • Structures – User-defined combinations of other types • Enumerations – User-defined weekday: sunday, monday, ... • Unions – Same data, multiple interpretations • Arrays and pointers of the above • Function pointers 3 Preliminary types we have learned • Integer – short – int – long long int • Real number – float – double • Character – char • String – char[] 4 Structure example 1: student • Structures aggregate variables of different types – Defined with the keyword struct • Example struct student { int id; int year; char grade; }; void main() { struct student s; s.id = 10001; s.year = 2011; s.grade = 'A'; } 5 Structure example 2: 2-D Points struct point { double x; double y; }; double distance(struct point p1, struct point p2) { double dx = p1.x - p2.x; double dy = p1.y - p2.y; return sqrt(dx * dx + dy * dy); } void main() { struct point a; struct point b; a.x = 12.0; a.y = 42.0; b.x = 15.0; b.y = 36.0; printf(“The distance is %lf”, distance(a, b) ); return 0; } 6 Structure Syntax To define a structure To declare a variable of the new structure type Definition struct structure_name { /* list of variable declarations */ }; Example void main() { struct structure_name variable_name; } The struct keyword is required in both places 7 Structures and typedef • To avoid the struct keyword, use a typedef • Create alias for struct student called student_t Example (revised from example 1) struct student { int id; int year; char grade; }; typedef struct student student_t; void main() { student_t s; s.id = 10001; s.year = 2011; s.grade = 'A'; } 8 Structures and typedef Example (revised from example 2) // a shortcut to define structure typedef struct point { double x; double y; }; double distance(point p1, point p2) { double dx = p1.x - p2.x; double dy = p1.y - p2.y; return sqrt(dx * dx + dy * dy); } void main() { point a = {12.0, 42.0}; point b = {15.0, 36.0}; printf(“The distance is %lf”, distance(a, b) ); return 0; } 9 Structures in C • C treats structures as if they were primitive data types – i.e. not like reference types (e.g. in Java) – Passing a structure as an argument to a function means that a temporary copy is made of the entire structure – Assignments do a deep copy of the entire structure Example void reset(point p) { p.x = p.y = 0; } void main() { point a; a.x = 12.0; a.y = 42.0; printf(“before: [%.1lf, %.1lf]\n", a.x, a.y); // a = 12.0, 42.0 reset(a); printf(“after: [%.1lf, %.1lf]\n", a.x, a.y); // a = ?, ? } 10 Structures in C • C treats structures as if they were primitive data types – i.e. not like reference types (e.g. in Java) – Passing a structure as an argument to a function means that a temporary copy is made of the entire structure – Assignments do a deep copy of the entire structure Example void main() { point a; a.x = 12.0; a.y = 42.0; point b = a; printf(“before: [%.1lf, %.1lf]\n", b.x, b.y); // b = 12.0, 42.0 b.x = 0; printf(“after: [%.1lf, %.1lf]\n", b.x, b.y); // a = 0.0, 42.0 } 11 Pointers and Arrays • Access array elements using pointers void main() { int a[] = {3, 7, -1, 4, 6}; int i; double mean = 0; // compute mean of values in a for (i = 0; i < 5; ++i) { mean += *(a + i); } mean /= 5; printf("Mean = %.2f\n", mean); } 12 Pointers and Arrays • Access array elements using pointers void main() { int a[5] = {3, 7, -1, 4, 6}; int i; double mean = 0.0; // compute mean of values in a for (i = 0; i < 5; ++i) { mean += a[i]; } mean /= 5.0; printf("Mean = %.2f\n", mean); } 13 Pointers and Arrays • What is *(a + i)? for (i = 0; i < 5; ++i) { mean += *(a + i); } • Try this: int a[5]; // print the address of array a printf("%d\n", a); // print the address of a[0] printf("%d\n", &a[0]); // print the address of a[1] printf("%d\n", &a[1]); // test what is “a + 1” printf("%d\n", a + 1); 14 Structures and Function Calls • Function calls with structure arguments can be expensive. 10000+ bytes must be copied typedef struct { char name[10000]; int id; } person; void print_person(person p) { printf("%d %s\n", p.id, p.name); } void main() { person a = {"Mike Smith", 1234}; print_person(a); } 15 Solution • Use pointers. Only the address of the structure is copied, not the entire structure. • Use &s to get the address of a structure s • Use *p to get the structure pointed by p • Use (*p).field to access a field of the structure • Or a cleaner syntax: – p->field 16 Pointers to Structures typedef struct { char name[10000]; int id; } person; void print_person(person *p) { printf("%d %s\n", p->id, p->name); } void main() { person a = {"Mike Smith", 1234}; print_person(&a); } 17 Pointers to Structure typedef struct { char name[10000]; int id; } person; void print_person(person *p) { printf("%d %s\n", p->id, p->name); } void main() { person *p; p = (person *) malloc(sizeof(person)); strcpy(p->name, "Mike Smith"); p->id = 1234; print_person(&a); free(p); } 18 What is #define ? • Easy to map a number into a meaningful word • Common usage 1: #define SIZE 1000 int main() { int array[SIZE]; for (int i = 0; i < SIZE; i++) array[i] = 0; return 0; } 19 What is #define ? • Easy to map a number into a meaningful word • Common usage 2: #define sun 0 #define mon 1 #define tue 2 #define wed 3 #define thu 4 #define fri 5 #define sat 6 int main() { int week; scanf("%d", &week); if (week == wed) { // do something } return 0; } 20 What is #define ? • #define can also be dangerous!! • Common error: #define FIVE 4 + 1 #define SIX 5 + 1 int main() { printf("%d\n", FIVE * SIX); return 0; } 21 Enumerations enum days {mon, tue, wed, thu, fri, sat, sun}; // Same as: // #define mon 0 // #define tue 1 // ... // #define sun 6 enum days {mon = 3, tue = 8, wed, thu, fri, sat, sun}; // Same as: // #define mon 3 // #define tue 8 // #define wed 9 // ... // #define sun 13 22 Enumerations enum days day; // Same as: int day; for (day = mon; day <= sun; ++day) { if (day == sun) { printf("Sun\n"); } else { printf("day = %d\n", day); } } 23 Enumerations • • • • • Basically integers Can use in expressions like this Makes code easier to read Cannot get string equiv. Caution: day++ will always add 1 even if enum values aren't contiguous. 24 Creating Your Own Types • C lets you name your own types using typedef • Example typedef double scalar; scalar add(scalar a, scalar b) { return a + b; } • typedef syntax – As if you're declaring a variable of the type you want to redefine – Give the variable the name of the new type – Put typedef in front 25 More on typedef typedef double scalar; typedef scalar vector[10]; scalar add_scalars(scalar a, scalar b) { return a + b; } void add_vectors(vector result, vector a, vector b) { int i; for (i = 0; i < 10; ++i) { result[i] = a[i] + b[i]; } } 26 Structures and the Heap • So far we've been storing structures on the stack • Structures can also be stored on the heap – Call malloc() to request a memory region of the correct size (Use sizeof to determine the correct size) – Cast the pointer returned by malloc to a pointer to the structure – Free the region when the structure is no longer needed 27 Union • A union is a variable that stores objects of dierent types – But it can only store one object at a time – Like a structure, but all fields start at offset 0 • e.g. You have a floating point number – Sometimes you want to treat it as a oat – Sometimes you want to treat it as an int – Sometimes you want to treat it as a char array Example union new_float { float float_view; int int_view; char array_view[4]; }; 28 Example union new_float { float float_view; int int_view; char array_view[4]; }; void main() { union new_float f; f.float_view = 3.7; printf("%f %d %c %c %c %c\n", f.float_view, f.int_view, f.array_view[0], f.array_view[1], f.array_view[2], f.array_view[3]); } 29 Function Pointers int min(int a, int b); int max(int a, int b); int foo(int do_min) { int (*func)(int, int); // declaring func. ptr if (do_min) { func = min; } else { func = max; } return func(10, 20); // indirect call } 30 Function Pointers • • Points to a function Has a *-type of the function it points to 31 Exercise 1 • Problem: – I walked down the street one day and found n stores. I wrote down the names of these stores. Can you tell me when I went back, what store would I meet first during the way? Can you list these n stores in order? • Program: – enter how many stores you met: 5 store 1: seven store 2: watsons store 3: starbucks store 4: chanel store 5: coach from the way you went back, you will met: coach chanel starbucks watsons seven 32 Exercise 2 • Problem: – Given a list of student grading information, can you tell me who is the first place? • Program: – enter how many students: 3 s1 name: Jonn s1 english: 75 s1 chinese: 88 s2 name: Many s2 english: 69 s2 chinese 62 s3 name: MrTop s3 english: 100 s3 chinese: 100 The first place is MrTop who got 200 points in total! 33 Explaination about Assignment #6 Pointer array void main() { struct card_t* deck[52]; fill_deck(deck); print_deck(deck); } ♤A ♤2 ♤3 ♤4 ♤5 ♤6 ♤7 ♤8 ♤9 34 Explaination about Assignment #6 Pointer array void main() { struct card_t* deck[52]; fill_deck(deck) shuffle(deck); print_deck(deck); } ♤A ♤2 ♤3 ♤4 ♤5 ♤6 ♤7 ♤8 ♤9 35 Explaination about Assignment #6 Pointer array void main() { struct card_t* deck[52]; fill_deck(deck) shuffle(deck); print_deck(deck); } ♤A ♤2 ♤3 ♤4 ♤5 ♤6 ♤7 ♤8 ♤9 36