340 likes | 443 Views
CS 108 Computing Fundamentals April 15, 2014. Structures. Thus far we have used variables which have been atomic in nature single data types ( int, double, char, etc…) these atomic variables cannot be "broken down" into anything simpler and still maintain identity/meaning
E N D
CS 108 Computing Fundamentals April 15, 2014
Structures • Thus far we have used variables which have been atomic in nature • single data types (int, double,char, etc…) • these atomic variablescannot be "broken down" into anything simpler and still maintain identity/meaning • C provides us with the capability to create composite data types and use them to create composite variables • A composite data type is called a structure (struct) • A structure can contain both "built-in" data types (int, double,char, etc…) and/or other structures
Structures • Structures are the basis for more advanced data structures (more advanced than arrays or multi-dimensional arrays) • Structures combined with pointers can be used to build linked data structures such as lists, stacks, queues, trees, graphs, etc… (CS 240 and beyond) • We need these more advanced data structures to allow us to model more complex systems and solve more difficult problems • Structures are important in computing… without them it would extremely difficult (if not impossible) to implement concepts like relational databases, file processing, and object-orientation
Structures • Structures allow us to much more accurately describe (or model) an object • Think of an object as a noun… a person, place, thing, or event • Examples of objects: students, courses, majors, flights, doctors, concerts, musical groups, teams, players, etc…
Structures • An object can be described or modeled by listing the unique characteristics of the object • A course can be described by title, credit hours, prerequisites, description, meeting time, instructor, etc… • A student can be described by first name, last name, ssn, major, gpa, date-of-birth, etc… • Notice that the "characteristics" must have different data types • We can use a structure to create a model of an object
Structures • Creating a structure is a two-step process 1) create a structure definition ("defines" a structure framework) 2) create an instance of a defined structure • Memory is not actually allocated until an instance is created • Syntax of a structure definition: struct structure_name { data_type name_of_element_1 ; data_type name_of_element_2 ; . . . data_type name_of_element_n ; } ;
Structures • Example of a structure definition: struct student { char first_name[20] ; char last_name[20] ; char ssn[10] ; char major[50] ; float gpa ; } ; • Each listed characteristic of a structure definition is called an element
Structures • Syntax for creating an instance of a defined structure: struct structure_name instance_name ; • Example of creating an instance of a defined structure : struct student student_1 ; • student_1 is a variable name that is an instance of the studentstructure… this means that student_1 has all the characteristics and properties of the student structure definition
Structures • Because a variable that is the instance of a structure may contain many elements, each element must be reachable… we use "dot notation" via the "." operator struct student { char first_name[20]; char last_name[20]; char ssn[10]; char major[50]; float gpa ; } ; struct student student_1 ; student_1.first_name = "Chris" ; student_1.ssn = "111223333" ; student_1.gpa = 2.0 ;
Structures • We can initialize the instance of a structure while we are creating it: struct student student_1 = {"Chris", "Urban", "111223333", "Computer Science", 2.0} ; • Notice that it is possible to use the = operator on a structure variable, but only when creating a structure instance. When the = sign is used, each element of the structure at the right hand side is copied into the structure at the left hand side "in order"… if you mess-up the order then your input will be useless trash (if it doesn’t crash). An example of a mess: struct student student_1 = { 2.0, "111223333", "Computer Science", "Chris", "Urban" } ;
#include <stdio.h> // 1.c #include<string.h> struct student { char first_name[20] ; char last_name[20] ; char ssn[10] ; char major[50] ; float gpa ; } ; int main ( void ) { struct student student_1; strcpy(student_1.major, "Computer Science" ); // The order is not strcpy(student_1.first_name, "Chris" ); // important when strcpy(student_1.last_name, "Urban" ); // directly assigning strcpy(student_1.ssn, "111223333" ); // element values. student_1.gpa = 2.0; printf("\n\nLast name: %s", student_1.last_name); printf("\nSSN: %s \n\n\n", student_1.ssn); return (0) ; }
typedef • typedef is used to create aliases for structure definitions by providing a structure tag name • A structure tag name (alias) can be used to assign a specific structure to a variable (create an instance of a structure) • Using the structure tag name (alias) provides a mechanism for declaring an instance of a structure that is very similar to the mechanism we have used to declare variables of standard data types • Essentially, typedef allows us to create our own data types
typedef • Creating a structure using typedef is (also) a two-step process: • 1) use typedef and struct to create a structure definition with a structure tag name (alias) • 2) create an instance of a typedef defined structure using struct and a structure tag name • Syntax of a structure definition using typedef and a structure tag name: typedef struct structure_name { data_type name_of_element_1; data_type name_of_element_2; . . . data_type name_of_element_n ; } tag_name ;
typedef • Example of a structure definition using typedef and a structure tag: typedef struct student { char first_name[20] ; char last_name[20] ; char ssn[10] ; char major[50] ; float gpa ; } stdnt ; • Again, each listed characteristic is called an element • The name of the structureand the tag namemay be the same… I typically don't make them the same to emphasize when I'm using the structure name or the structure tag
typedef • Syntax for creating an instance of a structure that has been defined using typedef and a structure tag: structure_tag_name instance_name ; • Example of creating an instance of a defined structure : stdnt student_1 ; • student_1 is a variable name that is of type stdnt which means that student_1 is an instance of the student structure • Using typedef makes passing structures to functions a little easier (more on this in a few slides)
#include <stdio.h> //2.c #include<string.h> typedef struct student { char first_name[20]; char last_name[20]; char ssn[10]; char major[50]; float gpa ; } stdnt ; int main ( void ) { stdnt student_1 ; strcpy(student_1.major, "Computer Science"); // The order is not strcpy(student_1.first_name, "Chris"); // important when strcpy(student_1.last_name, "Urban"); // directly assigning strcpy(student_1.ssn, "111223333"); // element values. student_1.gpa = 2.0; printf("\n\nLast name: %s", student_1.last_name); printf("\nSSN: %s \n\n\n", student_1.ssn); return (0) ; }
#include <stdio.h> //2a.c… the structure name and tag are the same #include<string.h> typedef struct student { char first_name[20]; char last_name[20]; char ssn[10]; char major[50]; float gpa ; } student ; int main ( void ) { student student_1 ; // I'm defining this variable using the structure tag strcpy(student_1.major, "Computer Science"); // The order is not strcpy(student_1.first_name, "Chris"); // important when strcpy(student_1.last_name, "Urban"); // directly assigning strcpy(student_1.ssn, "111223333"); // element values. student_1.gpa = 2.0; printf("\n\nLast name: %s", student_1.last_name); printf("\nSSN: %s \n\n\n", student_1.ssn); return (0) ; }
#include <stdio.h> //2b.c… the structure name and tag are the same #include<string.h> typedef struct student { char first_name[20]; char last_name[20]; char ssn[10]; char major[50]; float gpa ; } student ; int main ( void ) { struct student student_1 ; // I'm defining this variable using the structure name strcpy(student_1.major, "Computer Science"); // The order is not strcpy(student_1.first_name, "Chris"); // important when strcpy(student_1.last_name, "Urban"); // directly assigning strcpy(student_1.ssn, "111223333"); // element values. student_1.gpa = 2.0; printf("\n\nLast name: %s", student_1.last_name); printf("\nSSN: %s \n\n\n", student_1.ssn); return (0) ; }
Arrays of Structures • You can think of a single instance of a structure as a record from a database • An array of structures is (conceptually) a collection of records… essentially a database table typedef struct student { char first_name[20]; char last_name[20]; char ssn[10]; char major[50]; float gpa ; } stdnt; stdnt student_records [ 10 ];
#include <stdio.h> //3.c #include<string.h> typedef struct student { char first_name[20] ; char last_name[20] ; } stdnt ; int main ( void ) { stdnt student_records [ 3 ]; int index = 0; strcpy(student_records[0].first_name, "Jane"); strcpy(student_records[0].last_name, "Jones"); strcpy(student_records[1].first_name, "Chris"); strcpy(student_records[1].last_name, "Urban" ); strcpy(student_records[2].first_name, "Peggy"); strcpy(student_records[2].last_name, "Flemming" ); for (index = 0; index < 3; index = index + 1) printf("\nFirst: \t %s \t\t Last: \t %s \n", student_records[index].first_name, student_records[index].last_name) ; printf("\n\n\n") ; return (0) ; }
Passing Structures By Value • A structure must exist (we must create it) before a structure can be passed to a function • Prototype syntax when typedef is not used to create the structure: function_return _type function_name ( struct structure_name instance_name ) ; // italics means "optional" • Example of a PCF prototype if typedef isnot used to create the structure: void printer (struct student ); // Notice that I did not use an // instance name in this prototype
Passing Structures By Value • Prototype syntax when typedef is used to create the structure: function_return _type function_name ( structure_tag_name instance_name ) ; // italics means "optional" • Example of a PCF prototype if typedef is used to create the structure: void printer ( stndt ); • Note: stndt looks very similar to passing an int or char (for example) by value
#include <stdio.h> //4.c #include<string.h> typedef struct student { char first_name[20] ; char last_name[20] ; } stdnt ; void printer ( stdnt ) ; int main ( void ) { stdnt student_1; strcpy(student_1.first_name, "Jackie"); strcpy(student_1.last_name, "Jones"); printf("\n\n%s %s \n\n", student_1.first_name, student_1.last_name) ; printer (student_1); printf("%s %s \n\n", student_1.first_name, student_1.last_name) ; return (0); } void printer ( stdnt zoo ) { strcpy(zoo.first_name , "Sarah" ) ; printf("%s %s \n\n" , zoo.first_name, zoo.last_name) ; }
Passing Structures By Reference • Before learning to pass structures by reference, we must introduce another means of accessing elements of a structure: the structure pointer operator -> • Syntax for using the structure pointer operator -> pointer_of_structure_type -> element_name • Example of using the structure pointer operator -> student_ptr->gpa = 2.0 ;
Passing Structures By Reference • Example of using the structure pointer operator -> student_ptr->gpa = 2.0 ; • This can be very useful when a pointer of a structure type is created and we need to indirectly reference an element’s value
#include <stdio.h> //5.c #include<string.h> typedef struct student { char first_name[20]; char last_name[20]; } stdnt ; int main ( void ) { stdnt student_1; stdnt * st_ptr ; st_ptr = &student_1; strcpy( st_ptr->first_name, "Jackie"); strcpy( st_ptr->last_name, "Jones"); printf("\n\n%s %s \n\n", st_ptr->first_name , st_ptr->last_name) ; return (0); }
Passing Structures By Reference • When you understand the structure pointer operator then passing structures by reference is not too difficult • Essentially, it's the same as passing another variable by reference • You need to include in the function prototype and definition that a pointer of structure type is going to be used • Also need to use the structure pointer operator
#include <stdio.h> //6.c #include<string.h> typedefstruct student { char first_name[20]; char last_name[20] ; } stdnt ; void printer ( stdnt * ); int main ( void ) { stdnt student_1;stdnt *st_ptr ; st_ptr = &student_1; strcpy(student_1.first_name, "Jackie"); strcpy(student_1.last_name, "Jones"); printf("\n\n%s %s \n\n", student_1.first_name, st_ptr->last_name) ; // Demo'ing use printer (st_ptr); // of structure printf("%s %s \n\n", st_ptr->first_name, student_1.last_name) ; // pointer return (0) ; // operator } void printer ( stdnt *zoo ) { strcpy(zoo->first_name, "Sarah"); printf("%s %s \n\n", zoo->first_name, zoo->last_name) ; return ; }
Passing Arrays of Structures • Just like passing an array, passing an array of structures is automatically passing by reference • Supply the function prototype and declaration with a pointer to the structure
#include <stdio.h> //7.c … using only array notation #include<string.h> typedef struct sq_cube { int input; int square; int cube ; } sq_c ; void populate ( sq_c [ ] ); int main ( void ) { sq_c table_1 [ 12 ] ; int index = 0; populate ( table_1 ) ; for (index = 0; index <12; index++) printf("\nInput: \t %d \t\t Square: \t %d \t\t Cube: \t %d\n", table_1[index].input, table_1[index].square, table_1[index].cube) ; return (0) ; } void populate ( sq_c ssqq_cc [ ] ) { int index = 0; for (index = 0; index <12; index++) { ssqq_cc[index].input = index ; ssqq_cc[index].square = index * index ; ssqq_cc[index].cube = index * index * index ; } return ; }
#include <stdio.h> // 8.c… same a 7.c but using only pointer notation #include<string.h> // with the exception of creating the array table_1 in main ( ) typedef struct sq_cube { int input; int square; int cube ; } sq_c ; void populate ( sq_c * ) ; int main ( void ) { sq_c table_1 [ 12 ] ; int index = 0; populate ( table_1 ) ; for (index = 0; index <12; index++) printf("\nInput: \t %d \t\t Square: \t %d \t\t Cube: \t %d\n", table_1[index].input, table_1[index].square, table_1[index].cube) ; return (0) ; } void populate ( sq_c * ssqq_cc ) { int index = 0; for (index = 0; index <12; index++) { (ssqq_cc + index)->input = index ; (ssqq_cc + index)->square = index * index ; (ssqq_cc + index)->cube = index * index * index ; } return ; }
#include <stdio.h> //9.c… same as 7.c but using both array and pointer notation #include<string.h> typedef struct sq_cube { int input; int square; int cube ; } sq_c ; void populate ( sq_c * ) ; int main ( void ) { sq_c table_1 [ 12 ] ; int index = 0; populate ( table_1 ) ; for (index = 0; index <12; index++) printf("\nInput: \t %d \t\t Square: \t %d \t\t Cube: \t %d\n", table_1[index].input, table_1[index].square, table_1[index].cube) ; return (0) ; } void populate ( sq_c * ssqq_cc ) { int index = 0; for (index = 0; index <12; index++) { ssqq_cc[index].input = index ; ssqq_cc[index].square = index * index ; ssqq_cc[index].cube = index * index * index ; } return ; }
#include <stdio.h> // 10.c… same a 7.c but using both array and pointer notation #include<string.h> // to the extreme, part 1 typedef struct sq_cube { int input; int square; int cube ; } sq_c ; void populate ( sq_c [ ] ); int main ( void ) { sq_c table_1 [ 12 ]; int index = 0; populate (table_1); for (index = 0; index <12; index++) printf("\nInput: \t %d \t\t Square: \t %d \t\t Cube: \t %d\n", table_1[index].input, table_1[index].square, table_1[index].cube) ; return (0) ; } void populate (sq_c * ssqq_cc ) { int index = 0; for (index = 0; index <12; index++) { (ssqq_cc + index)->input = index ; ssqq_cc [index].square = index * index ; (ssqq_cc + index)->cube = index * index * index ; } return ; }
#include <stdio.h> // 11.c… same a 7.c but using both array and pointer notation #include<string.h> // to the extreme, part 2 typedef struct sq_cube { int input; int square; int cube ; } sq_c ; void populate ( sq_c * ); int main ( void ) { sq_c table_1 [ 12 ]; int index = 0; populate (table_1); for (index = 0; index <12; index++) printf("\nInput: \t %d \t\t Square: \t %d \t\t Cube: \t %d\n", table_1[index].input, table_1[index].square, (table_1 + index)->cube ) ; return (0) ; } void populate (sq_c ssqq_cc [ ] ) { int index = 0; for (index = 0; index <12; index++) { (ssqq_cc + index)->input = index ; ssqq_cc [index].square = index * index ; (ssqq_cc + index)->cube = index * index * index ; } return ; }