220 likes | 397 Views
Chapter 7. Arrays & Structures. Arrays of Strings. We have seen in our earlier discussions that we can represent strings in C by building arrays of type char . Example: char name[25]; /*reserves space for 25 characters*/
E N D
Chapter 7 Arrays & Structures
Arrays of Strings • We have seen in our earlier discussions that we can represent strings in C by building arrays of type char. • Example: char name[25]; /*reserves space for 25 characters*/ • But what would we do if we wanted tostore an array of names? Say the names of all students in a class? • Because one string is an array of characters, an array of strings is a two-dimensional array of characters in which each row is one string. • The following statements declare an array that is capable of storing up to 30 names, each of which is less than 25 characters in length. • #define NUM_NAMES 30 • #define STRING_LENGTH 25 • . . . • char names[NUM_NAMES][STRING_LENGTH]; • Arrays of strings can be initialized at declaration using {}’s and a list of initializers. • char months[12][4] = {“Jan”,”Feb”,“Mar”,“Apr”,”May”,”Jun”, • “Jul”,”Aug”,”Sep”,”Oct”,”Nov”,”Dec”};
A question is, “what if we wanted to use arrays to read in, store, work with, and finally print out a variety of data for a set of students?” • Say we want to be able to store each student’s: name, age, and gpa? • We can not do this with a single array since arrays are homogeneous, and we have a need to store strings for each student name, ints for each student’s age, and floats for each student’s gpa. • How would we do this? • Typically, we would create three different arrays (one for each type of data). • Example: • #define NUM_STUDENTS 5 • #define STRING_LENGTH 10 • . . . • char names[NUM_STUDENTS][STRING_LENGTH]; • int age[NUM_STUDENTS]; • float gpa[NUM_STUDENTS];
Parallel Arrays Note: all related information for the ith student will be found in the ith location of each element of the arrays: Example: the 3rd student’s information is found in - names[3] and age[3] and gpa[3] the ith student’s information is found in - names[i] and age[i] and gpa[i]
Parallel Arrays (example) #include <stdio.h> #define NUM_STUDENTS 5 #define STRING_LENGTH 10 int main(void) { char names[NUM_STUDENTS][STRING_LENGTH]; int age[NUM_STUDENTS]; float gpa[NUM_STUDENTS]; int i,num = 0; printf("Enter a student's name, age, and gpa\n"); printf("Use a format like: Smith 23 3.4\n\n"); while (scanf("%s%d%f",names[num],&age[num],&gpa[num]) != EOF) { num++; } printf("\n\n=========================================================\n"); for (i = 0; i < num; i++) printf("\nThe student %s is %d years old and has a %f gpa\n", names[i], age[i], gpa[i]); printf("\n\nTerminating"); return 0; }
Structures • In addition to the basic data types such a char, int, float, and double, C supports user-defined data types. • Many applications work with collections of related items of information - we just looked at one way of handling this situation in C by employing parallel arrays. • C provides a data type called a structure that makes this operation simpler. • A structure is a collection of related data items of different type under one common name. • The individual items that comprise the structure can be any valid C data types including arrays and other structures (so it is possible to have a structure nested inside a structure). • To create a structure, you must: • Define the structure • Declare variables of that typ.e • The structure definition specifies a template for the structure and informs the compiler about the various elements that will make up the structure. • The declaration actually creates structure variables of the type defined in the structure definition.
Structures (continued) • Example: consider the syntax for defining a structure that can hold the related information (name, age, and gpa) that we did earlier with parallel arrays - • struct student_record • { • char name[25]; • int age; • float gpa; • }; • The structure name, in this case (student_record) is referred to as the structure tag. • The structure tag is followed by a list of data items (called members) and their data types that will comprise the structure (the list is enclosed in braces). • The semicolon at the end closes the structure definition. • It is important to note that the structure definition simply serves as a template that defines the various members of the structure. When the compiler encounters the structure definition - it does NOT allocate any storage nor does it create any structure variable. • To declare a variable(s) to be of this structure type, you would write: • struct student_record student1, student2, student2; Only now is memory allocated!
Structures (continued) • Example: consider the syntax for the structure we showed earlier - • struct student_record • { • char name[25]; • int age; • float gpa; • }; • External and static structure variables can be initialized at the time they are declared: • Example • static struct student_record student1={“Jim”,21,3.6}; • Values are assigned to the individual members in the order in which the value and members appear. • The following demonstrates how to build an array of structures and initialize the elements: • static struct student_record student[3] = { • {“Bob”, 18, 4.0}, • {“Ted”, 22, 3.0} • } The first two members are initialized to the values provided. The last is automatically assigned zero values
Structures (continued) • A special syntax is needed for accessing the members of a structure. • A member is accessed by specifying the name of the structure variable (not the tag) followed by a period (called the structure member of operator) and the member name. • Thus, for the earlier example - • struct student_record • { • char name[STRING_LENGTH]; • int age; • float gpa; • }; • struct student_record student1, student[3]; • The members are accessed as: • student1.name, student1.age, student1.gpa and • student[i].name, student[i].age, student[i].gpa
Structures Example #include <stdio.h> #include <string.h> #define STRING_LEN 25 struct student_record { char name[STRING_LEN]; int age; float gpa; }; int main(void) { struct student_record student; /*assign values to the structure members*/ strcpy(student.name,"John Jones"); student.age = 18; student.gpa = 3.5; /*print the member of the structure */ printf("%s is %d years old and has a %6.2f gpa", student.name, student.age, student.gpa); return 0; }
Structures (continued) • C allows a limited number of operations on structures: • You can initialize static and external structures. • You can access one of the members of a structure. • You can assign one structure, as a whole, to another structure. • You can pass a structure to a function. • You can return a structure from a function. • You can use the address-of operator (&) to determine the address of a structure. • And, at least one other, that will not be useful to us.
Structures (can be nested) #include <stdio.h> #include <string.h> #define STRING_LEN 25 struct name_record { char first_name [20]; char last_name[25]; char middle_initial; }; struct address_record { char city[15]; char state[2]; int zip; }; struct student_record { struct name_record name; struct address_record address; int age; float gpa; }; int main(void) { struct student_record stu; /*assign values to the structure members*/ strcpy(stu.name.first_name,"John"); strcpy(stu.name.last_name,"Smith"); stu.name.middle_initial = 'Q'; strcpy(stu.address.city,"Ft. Worth"); strcpy(stu.address.state,"TX"); stu.address.zip = 76129; stu.age = 18; stu.gpa - 3.5; /*print the member of the structure */ printf("%s lives in %s and is %d years old",stu.name.first_name, stu.address.state, stu.age); return 0; } Especially useful if you wanted to just send stu’s name to a function and not the entire record.
Structures (continued) • The members of a structure can be any valid C data type including arrays. • As seen earlier, arrays of structures can also be created: • struct student_record • { • char name[STRING_LEN]; • int age; • float gpa; • }; • . . . • struct student_record student[100]; • Creates an array of structures, named student, that has 100 elements. • Valid references to the age member would be: • student[5].age or student[99].age or student[i].age Note: the subscript is attached to the array name and not to the member name!
Structures Example #include <stdio.h> #define NUM_STUDENTS 5 #define STRING_LENGTH 10 int main(void) { struct student_record { char name[STRING_LENGTH]; int age; float gpa; }; struct student_record student_info[NUM_STUDENTS]; int i = 0,num = 0; printf("Enter a student's name, age, and gpa\n"); printf("Use a format like: Smith 23 3.4\n\n"); while (scanf("%s%d%f", student_info[num].name, &student_info[num].age, &student_info[num].gpa) != EOF) { num++; } printf("\n\n=========================================================\n"); for (i = 0; i < num; i++) printf("\nThe student %s is %d years old and has a %f gpa\n", student_info[i].name, student_info[i].age, student_info[i].gpa); printf("\n\nTerminating"); return 0; } An array of structures
Structure Initializations • Arrays of structurescan be initialized using a syntax similar to that for other arrays. • Example: • struct student_record • { • char name[STRING_LEN]; • int age; • float gpa; • }; • . . . • static student_record student[3] = • { • {“Bill”, 18, 3.6}, • {“Jill”, 20. 4.0} • } • Note: that the members of student[2] are not assigned any values; thus, they are initialized to the default value of zero.
Declaring Structures • Our earlier examples of creating structures were - • #include <stdio.h> • #include <string.h> • #define STRING_LEN 25 • struct student_record • { • char name[STRING_LEN]; • int age; • float gpa; • }; • void display_student_info(struct student_record); • int main(void) • { • static struct student_record student[2] = { {"Bill", 18, 3.5}; {"Jill", 20, 4.0} • }; • display_student_info(student[0]); • display_student_info(student[1]); • display_student_info(student[1]); • return 0; • } • void display_student_info(struct student_record s) • { • printf("%s is %d years old and has a %6.2f gpa\n",s.name, s.age, s.gpa); • } Note: last value is all zeros since it was not initialized. Very useful because we have a type to give to the corresponding parameter.
Declaring Structures • C will also let you create a structure without specifying a tag - • #include <stdio.h> • #include <string.h> • #define STRING_LEN 25 • struct • { • char name[STRING_LEN]; • int age; • float gpa; • } stu[3]; • void display_student_info(struct student_record); • int main(void) • { • strcpy(stu[0].name,"Bill"); • stu[0].age = 18; • stu[0].gpa = 3.5; • printf("%s is %d years old and has a %6.2f gpa”, • stu[0].name,stu[0].age,stu[0].gpa); • return 0; • } Note: no tag name specified. Problem - there is no tag name to give to a corresponding parameter if you wanted to send the entire array or an element of the array to a function.
strcpy() • Copying struct components to other struct components - • #include <stdio.h> • #include <string.h> • struct student_rec • { • char name[25]; • int age; • char gender; • }; • typedef struct student_rec STUDENT_INFO; • int main(void) • { • STUDENT_INFO data[5] = { • {"James",18,'M'}, • {"Mary",20,'F'} • }; • data[3] = data[0]; /* structure assignment */ • printf("%s %d %c\n",data[3].name,data[3].age,data[3].gender); • strcpy(data[4].name,data[1].name); /* structure component assignment - name field*/ • data[4].age = data[1].age; /* structure component assignment */ • data[4].gender = data[1].gender; /* structure component assignment */ • printf("%s %d %c\n",data[4].name,data[4].age,data[4].gender); • return 0; • }
The typedef Statement • The typedef statement is used to create synonyms for data types. These data types can be the build-in ones (such as char, int, float, etc…) or any other user defined data types. • For example, we could write - • typedef float REAL; • This statement defines the name REAL to be a synonym for the float data type. • We could now use the name REAL in our programs instead of float. • Example: • REAL a, b, c; /* is equivalent to float a, b, c; */ • The general syntax for the typedef statement is: • typedef <datatype> <user provided name>;
Another example #include <stdio.h> typedef int BOOLEAN; typedef BOOLEAN TRUE; typedef BOOLEAN FALSE; typedef float REAL; int main(void) { BOOLEAN TRUE = 1; BOOLEAN FALSE = 0; REAL a = 5.0, b = 10.0, c; BOOLEAN found; if (a < b) found = TRUE; else found = FALSE; if (found) printf("Found\n"); else printf("Not found\n"); c = a + b; printf("c = %f\n",c); return 0; } Makes: BOOLEAN a synonym for int and REAL a synonym for float.
Still Another example #include <stdio.h> #include <string.h> struct stu_rec { char name[20]; int age; float gpa; }; typedef struct stu_rec STUDENT_INFO; int main(void) { STUDENT_INFO student1, student[3]; strcpy(student1.name,"Jim Bob"); student[1].age = 19; printf("Name = %s, age = %d\n", student1.name,student[1].age); return 0; } Makes: STUDENT_INFO a synonym for stu_rec. Makes parameter types shorter and more readable.
Still Another example • #include <stdio.h> • #include <string.h> • struct complex_number • { • float real; • float imaginary; • }; • typedef struct compley_number COMPLEX; • int main(void) • { • COMPLEX num1, num2; • . . . • } Makes: COMPLEX a synonym for complex_number.