class: center, middle ### COMP26020 Programming Languages and Paradigms Part 1: C Programming *** # Custom Types and Data Structures in C ??? - Hello everyone - In this video we will see how to create and use custom data types and structures in C --- # Custom Types - Use `typedef` to alias a type ```c #include
// 'my_int' is now equivalent to 'long long unsigned int' typedef long long unsigned int my_int; int main(int argc, char **argv) { my_int x = 12; printf("x is: %llu\n", x); return 0; } ``` .codelink[
`08-c-custom-types/typedef.c`
] ??? - To create a custom alias for a type, use the typedef keyword as follows - typedef, followed by the type you want to alias, here long long unsigned in, followed by the name of your alias, here my_int - Following that, you can use my_int to refer to long long unsigned int -- which is much shorter --- # Custom Data Structures - Use `struct` to define a data structure with named fields - Use `struct
` to refer to it as a type - Access the fields of a variable with `
.
` .leftcol[ ```c #include
#include
// needed for strcpy // Definition of the struct: struct person { char name[10]; float size_in_meters; int weight_in_grams; }; void print_person(struct person p) { /* Access fields with '.' */ printf("%s has a size of %f meters and " "weights %d grams\n", p.name, p.size_in_meters, p.weight_in_grams); } ``` ] .rightcol[ ```c int main(int argc, char **argv) { // declare a variable of the struct type: struct person p1; // sets the variable field p1.size_in_meters = 1.6; p1.weight_in_grams = 60000; strcpy(p1.name, "Julie"); struct person p2 = {"George", 1.8, 70000}; print_person(p1); print_person(p2); return 0; } ``` .codelink[
`08-c-custom-types/struct.c`
] ] ??? - Custom data structures are extremely useful in C - They aggregate several fields of various types - They are created and manipulated with the struct keyword - On the example on the slide we define a struct person - It has a name, which is a character array of length 10 - A size_in_meter which is a float - And a weight in grams which is an int - Looking at the main function on the right we declares a struct person variable p1 - We can set values in the fields with the dot - Don't worry about the strcpy now, just know that it sets Julie in the name field of p1 - We can also do static initialisation with braces followed by the fields value in order. - We have a print person function that takes a struct person as parameter and prints its field value - We can try it out, we see the two persons being printed --- # Custom Data Structures ```c struct person { char name[10]; float size_in_meters; int weight_in_grams; }; struct person p1; ``` - Fields are place consecutively in memory (compiler may insert padding):
??? - In memory, the fields of a struct are placed contiguously - A char is one byte so the array is 10 bytes in total - Followed by a float which is 4 bytes - Followed by an int which is also 4 bytes - Note that the compiler may insert some padding for performance reasons --- # Custom Data Structures - Structures can be typedef'd ```c #include
#include
// needed for strcpy struct s_person { /* fields declaration ... */ }; *typedef struct s_person person; void print_person(person p) { /* ... */} int main(int argc, char **argv) { person p1; person p2 = {"George", 1.8, 70000}; /* ... */ } ``` .leftcol[ - Faster: ] .rightcol[ ```c typedef struct { /* fields declaration ... */ } person; ``` ] ??? - To avoid using the struct keyword each time you refer to a structure, you can typedef the struct - After the struct declaration, use typedef followed by the name of the struct, here s_person, followed by the name of the alias, here person. - And now you can just use person - A faster method to do so is to typedef during the struct declaration --- # Enumeration - User defined type for assigning textual names to integer constants .leftcol[ ```c enum color { RED, BLUE, GREEN }; int main(int argc, char **argv) { enum color c1 = BLUE; switch(c1) { case RED: printf("c1 is red\n"); break; case BLUE: printf("c1 is blue\n"); break; case GREEN: printf("c1 is green\n"); break; default: printf("Unknown color\n"); } return 0; } ``` .codelink[
`08-c-custom-types/enum.c`
] ] .rightcol[ - Under the hood the compiler assigns an integer constant to each value of an enum: ```c printf("BLUE was assigned: %d\n", BLUE); printf("GREEN was assigned: %d\n", GREEN); printf("RED was assigned: %d\n", RED); ``` ] ??? - A last thing I want to talk about are enumerations - They are textual names that are mapped by the compiler to integer constants under the hood - They are useful in situation where integers are required -- for example a switch -- but when textual names are more meaningful - Here is an example, we define a color enum with 3 values: RED, BLUE, and GREEN - We declare an enum color variable c1 and sets it to blue - Then we can use it as the condition of a switch - Note that by convention constants are often in capital letters in C. --- # Enumeration - Enumerations can be typedef'd ```c enum e_color { BLUE, /* ,,, */ }; enum e_color c1 = BLUE; // without typedef typedef enum e_color color; color c2 = RED; ``` - All in once: ```c typedef enum { BLUE, /* ... */ } color; ``` .codelink[
`08-c-custom-types/enum-color.c`
] ??? - Same as for structs, enums can be typdefed to avoid using the enum keyword - So for example we simply use color to declare c2 --- # Summary - Typedef - Structs - Enum ---- .center[Feedback form: https://bit.ly/3iwfECU]
??? - So let's recap - We saw typedefs that are aliases for types - We also look at structs that aggregate inside a data structure several fields that can be of various types - Finally, we saw enumerations that map integer values to textual names - In the next video, we will talk about something fundamental in C, pointers