b3b36prg Lec05 Handout
b3b36prg Lec05 Handout
Jan Faigl
Lecture 05
B3B36PRG – Programming in C
Part I
Data types – Struct, Union, Enum and Bit Fields
struct
■ Structure struct is a finite set of data field members that can be of different type.
■ Structure is defined by the programmer as a new data type.
■ It allows storing a collection of the related data fields.
■ The size of each data field has to be known at the compile time.
■ Each structure has a separate name space for its members.
■ Definition of the compound type (struct) variable user_account.
#define USERNAME_LEN 8 Using anonymous structure type definition.
struct {
int login_count;
char username[USERNAME_LEN + 1]; // compile time array size definition!
int last_login; // date as the number of seconds
// from 1.1.1970 (unix time)
} user_account; // variable of the struct defined type
■ The definition is like other variable definition, where struct {...} specifies the type and
user_account the variable name.
■ We access the struct’s variable members using the . operator, e.g.,
user_account.login_count = 0;
Jan Faigl, 2024 B3B36PRG – Lecture 05: Data types 6 / 68
Structures – struct Unions Type definition – typedef Enumerations – enum Bit-Fields
Structure Tag
■ Declaring a structure tag allows to identify a particular structure and avoids repeating
all the data fields in the structure variable.
struct user_account {
int login_count;
char username[USERNAME_LEN + 1];
int last_login;
}; Notice VLA is not allowed in structure type because the size of the structure needs to be known and determined.
■ The defined tag is not a type name, therefore it has to be used with the struct keyword.
■ The new type can be defined using the typedef keyword.
typedef struct { ... } new_type_name;
■ The address alignment provides better performance for addressing the particular mem-
bers at the cost of higher memory requirements.
Eric S. Raymond: The Lost Art of Structure Packing - http://www.catb.org/esr/structure-packing.
■ The operator –> can be used to access structure members using a pointer.
typedef struct {
int number;
double value;
} record_s;
5 numbers.i = 5;
6 printf("\nSet the numbers.i to 5\n");
7 printf("Numbers c: %d i: %d d: %lf\n", numbers.c, numbers.i, numbers.d);
9 numbers.d = 3.14;
10 printf("\nSet the numbers.d to 3.14\n");
11 printf("Numbers c: %d i: %d d: %lf\n", numbers.c, numbers.i, numbers.d);
■ Example output:
Set the numbers.c to ’a’
Numbers c: 97 i: 1374389601 d: 3.140000
Initialization of Unions
■ The union variable can be initialized in the declaration.
1 union {
2 char c;
3 int i;
4 double d;
5 } numbers = { ’a’ };
Only the first member can be initialized
■ In C99, we can use the designated initializers.
1 union {
2 char c;
3 int i;
4 double d;
5 } numbers = { .d = 10.3 };
7 typedef struct {
8 char *name;
9 char *abbr; // abbreviation
10 } week_day_s;
45 printf("%d %s %s\n",
46 day_of_week,
47 days[day_of_week].name,
48 days[day_of_week].abbr);
49 return EXIT_OK;
50 } lec05/demo-struct.c
Jan Faigl, 2024 B3B36PRG – Lecture 05: Data types 29 / 68
Structures – struct Unions Type definition – typedef Enumerations – enum Bit-Fields
$ ./demo-struct
0 Monday mon
$ ./demo-struct 3
2 Wednesday wed
$ LC_CTYPE=cs ./demo-struct 3
2 Středa st
Bitwise Operators
■ In low-level programming, such as programs for MCU (micro controller units), we may
need to store information as single bits or collection of bits.
■ We can use bitwise operators to set or extract particular bit, e.g., a 16-bit unsigned
integer variable uint16_t i.
■ Set the 4 bit of i.
if ( i & 0x0010) ...
■ Clear the 4 bit of i.
i &= ∼0x0010;
■ We can give names to particular bits.
35 #define RED 1
36 #define GREEN 2
37 #define BLUE 3
Bit-Fields in Structures
■ In addition to bitwise operators, we can declare structures whose members represent
bit-fields, e.g., time stored in 16 bits.
typedef struct {
uint16_t seconds: 5; // use 5 bits to store seconds
uint16_t minutes: 6; // use 6 bits to store minutes
uint16_t hours: 5; //use 5 bits to store hours
} file_time_t;
file_time_t time;
■ We can access the members as a regular structure variable.
time.seconds = 10;
■ The only restriction is that the bit-fields do not have address in the usual sense, and
therefore, using address operator & is not allowed.
scanf("%d", &time.hours); // NOT ALLOWED!
Jan Faigl, 2024 B3B36PRG – Lecture 05: Data types 33 / 68
Structures – struct Unions Type definition – typedef Enumerations – enum Bit-Fields
Bit-Fields Example
typedef struct {
unsigned int seconds: 5;
unsigned int minutes: 6;
unsigned int hours: 5;
} file_time_int_s;
int main(void)
{
file_time_s time = { // designated initializers
.hours = 23, .minutes = 7, .seconds = 10 };
print_time(&time);
time.minutes += 30;
print_time(&time);
■ Assignment: https://cw.fel.cvut.cz/wiki/courses/b3b36prg/hw/hw05
■ Read matrix expression – matrices and operators (+, -, and *) from standard input (di-
mensions of the matrices are provided).
■ Compute the result of the matrix expression or report an error . Dynamic allocation is not needed!
Functions for implementing +, *, and - operators are highly recommended!
■ Optional assignment – compute the matrix expression with respect to the priority of *
operator over + and - operators. Dynamic allocation is not need, but it can be helpful.
■ Bonus assignment – Read declaration of matrices prior the matrix expression.
Dynamic allocation can be helpful, structures are not needed but can be helpful.
Part III
Part 3 – Coding Examples
(optional)
■ Use the function name as the pointer to the ■ Compile and run if the compilation is suc-
function. cessfull using shell logical and operator &&.
int compare(const void *, const void *); $ clang sort.c -o sort && ./sort
Array random: 13 17 18 15 12
int main(void) Array sorted: 12 13 15 17 18
{
int a[LEN]; // do not initialize ■ Use compiler flag -DLEN=10 to define the array
fill_random(LEN, a); length 10.
print("Array random: ", LEN, a);
qsort(a, LEN, sizeof(int), compare); $ clang -DLEN=10 sort.c -o sort && ./sort
print("Array sorted: ", LEN, a); Array random: 13 17 18 15 12 3 7 8 18 10
return 0; Array sorted: 3 7 8 10 12 13 15 17 18 18
}
■ Allocate array of the size ROWS × COLS and fill void print(int rows, int cols, int m[][cols])
it with random integer values with up to two {
digits, and print the values are an array. for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c) {
■ Implement fill and print functions. printf("%3i", m[r][c]);
}
■ Implement print function to print matrix of the putchar(’\n’);
size rows × cols. }
■ Cast the array of int values into m - a pointer }
of arrays of the size cols. ■ The number of columns is mandatory to deter-
■ Pass m to the function that prints the 2D array mine the address of the cell m[r][c] in the 2D
(matrix) with cols columns. array (matrix) m.
■ The pointer m can refer to arbitrary number of
rows.
Topics Discussed
■ Data types
■ Structure variables
■ Unions
■ Enumeration
■ Type definition
■ Bit-Fields