360 likes | 442 Views
Lecture06: Complex Types 4/18/2012 Slides modified from Yin Lou, Cornell CS2022: Introduction to C. 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. Complex Types. Structures
E N D
Lecture06: Complex Types4/18/2012Slides modified from Yin Lou, Cornell CS2022: Introduction to C
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.
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
Preliminary types we have learned • Integer • short • int • long long int • Real number • float • double • Character • char • String • char[]
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'; }
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; }
Structure Syntax To define a structure Definition struct structure_name { /* list of variable declarations */ }; To declare a variable of the new structure type Example void main() { struct structure_name variable_name; } The struct keyword is required in both places
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'; }
Structures and typedef // 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); } Example (revised from example 2) void main() { point a = {12.0, 42.0}; point b = {15.0, 36.0}; printf(“The distance is %lf”, distance(a, b) ); return 0; }
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 = ?, ? }
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 }
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); }
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); }
Pointers and Arrays • What is *(a + i)? • Try this: for (i = 0; i < 5; ++i) { mean += *(a + i); } 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);
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); }
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
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); }
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); }
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; }
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; }
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; }
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
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); } }
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.
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
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]; } }
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
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]; };
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]); }
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 }
Function Pointers • Points to a function • Has a *-type of the function it points to
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: 5store 1: sevenstore 2: watsonsstore 3: starbucksstore 4: chanelstore 5: coachfrom the way you went back, you will met:coachchanelstarbuckswatsonsseven
Exercise 2 • Problem: • Given a list of student grading information, can you tell me who is the first place? • Program: • enter how many students: 3s1 name: Jonns1 english: 75s1 chinese: 88s2 name: Manys2 english: 69s2 chinese 62s3 name: MrTops3 english: 100s3 chinese: 100The first place is MrTop who got 200 points in total!
Explaination about Assignment #6 ♤A Pointer array void main() { struct card_t* deck[52]; fill_deck(deck); print_deck(deck); } ♤2 ♤3 ♤4 ♤5 ♤6 ♤7 ♤8 ♤9
Explaination about Assignment #6 ♤A Pointer array void main() { struct card_t* deck[52]; fill_deck(deck) shuffle(deck); print_deck(deck); } ♤2 ♤3 ♤4 ♤5 ♤6 ♤7 ♤8 ♤9
Explaination about Assignment #6 ♤A Pointer array void main() { struct card_t* deck[52]; fill_deck(deck) shuffle(deck); print_deck(deck); } ♤2 ♤3 ♤4 ♤5 ♤6 ♤7 ♤8 ♤9