Lesson 13 - Structures in the C language
In the previous exercise, Solved tasks for C lesson 12, we've practiced our knowledge from previous lessons.
Lesson highlights
Are you looking for a quick reference on C structures instead of a thorough-full lesson? Here it is:
Declaring a structure:
typedef struct { char name[51]; int age; char street[51]; } USER;
Creating and printing structures using loops:
#include <stdio.h>
#include <string.h>
typedef struct {
char name[51];
int age;
char street[51];
} USER;
int main(int argc, char** argv) {
USER users[10];
strcpy(users[0].name, "John Smith");
users[0].age = 33;
strcpy(users[0].street, "Skew street 5");
strcpy(users[1].name, "Jack Brown");
users[1].age = 28;
strcpy(users[1].street, "Sunnyvale 8");
int i;
for (i = 0; i < 2; i++)
{
printf("The user at the index %d\n", i);
printf("Name: %s\n", users[i].name);
printf("Age: %d\n", users[i].age);
printf("Street: %s\n\n", users[i].street);
}
return 0;
}
Would you like to learn more? A complete lesson on this topic follows.
In the previous lesson, Solved tasks for C lesson 12, we learned how to declare custom functions in the C language. In today's tutorial, we'll learn to use another important feature of the C language which is structures. Since we're only going to create a simple program, we won't use custom functions today. Just remember if it was just a little bit longer, we really would need to split it into separate functions.
Storing complex items
Consider that we want to store data for a single user. He/she has a name, an age, and lives on a certain street. Using our current knowledge, we'd create multiple variables:
int main(int argc, char** argv) { char name[] = "John Smith"; int age = 33; char street[] = "Skew street 5"; return (EXIT_SUCCESS); }
However, we usually don't store a single user in a program. As we already
know, we use arrays to store multiple items of the same type. However, since the
user contains values of 3 different types, we'd have to create 3 different
arrays. One for names, the second one for ages, and the third one for streets.
Let's create several arrays which are 10
elements long (for storing
a maximum of ten users). We'll demonstrate their functionality by storing 2
users and printing them to the console using a for
loop.
#include <stdio.h>
#include <string.h>
int main(void)
{
char names[10][51];
int ages[10];
char streets[10][51];
strcpy(names[0], "John Smith");
ages[0] = 33;
strcpy(streets[0], "Skew street 5");
strcpy(names[1], "Jack Brown");
ages[1] = 28;
strcpy(streets[1], "Sunnyvale 8");
int i;
for (i = 0; i < 2; i++)
{
printf("The user at the index %d\n", i);
printf("Name: %s\n", names[i]);
printf("Age: %d\n", ages[i]);
printf("Street: %s\n\n", streets[i]);
}
return 0;
}
The result:
Console application
The user at the index 0
Name: John Smith
Age: 33
Street: Skew street 5
The user at the index 1
Name: Jack Brown
Age: 28
Street: Sunnyvale 8
The program looks pretty impressive considering our skills at this point. Once we learn to store data to files, we could program e.g. a phone book like this. Despite all that, the code above isn't ideal. Let's take note of several things here.
The definition of the names
and streets
arrays is
interesting. Since we need to have a char array (name) in every item of the
names
array, we have to create a variable which is technically an
array of arrays. Therefore, there are two pairs of brackets. In the first
brackets, we have specified the number of items of the outer array, i.e. the
number of names. In the second pair of brackets, we have the number of
characters in each name. In our case it's 50
characters (+1 for
\0
).
As we already know, we can't assign string constants in the C language in any
different way other than during the initialization. This is why we have to use
the strcpy()
function which copies a string into an existing
variable. Printing using a loop should be clear, we're simply working with
indexes < 2
since we don't have any more people at the
moment.
Structures
To avoid declaring so many confusing arrays, the C language allows us to
declare a structure. Simply put, it's a data type which is represented by a
single variable, but contains multiple values (it's sometimes called a record
type). It may remind you of an array, but it's items don't have to all be of the
same type and they're not accessed by numbers. Instead, they're accused by their
names. The best decision we could currently make is to create a
USER
structure in order to store users. Add the following
definition somewhere into the global scope above the main()
function:
typedef struct { char name[51]; int age; char street[51]; } USER;
Although there are multiple ways to declare structures, as it often happens
in the C language, we'll stick strictly with this one. We'll define structures
as new data types using the typedef
keyword which will help us with
declaring variables of that type (USER
) later on. Then the
struct
keyword follows. We declare items for the structure in the
curly brackets block as ordinary variables. We name structures with
UPPERCASE_LETTERS and end the whole declaration with a semicolon.
Now, let's rewrite the main()
function to the following
form:
#include <stdio.h>
#include <string.h>
typedef struct {
char name[51];
int age;
char street[51];
} USER;
int main(int argc, char** argv) {
USER users[10];
strcpy(users[0].name, "John Smith");
users[0].age = 33;
strcpy(users[0].street, "Skew street 5");
strcpy(users[1].name, "Jack Brown");
users[1].age = 28;
strcpy(users[1].street, "Sunnyvale 8");
int i;
for (i = 0; i < 2; i++)
{
printf("The user at the index %d\n", i);
printf("Name: %s\n", users[i].name);
printf("Age: %d\n", users[i].age);
printf("Street: %s\n\n", users[i].street);
}
return 0;
}
The whole application is way more readable now. It simply contains a single
array of the USER
type instead of 3 arrays as before. We use the
.
(dot) operator to access structure items. If we used structures
dynamically (which we can't quite yet), we would use the arrow operator
(->
). We'll explain all of this further along in the course.
Alternative structure definitions
Just for completeness' sake, let's go over other ways to create structures.
Mainly, to enable you all to read programs by other programmers. If we created a
structure without the typedef
keyword, we'd name it as a
lowercase_name:
struct user { char name[51]; int age; char street[51]; };
We'd have to provide the struct
keyword for declaring variables
of this type from then on:
struct user users[10];
Sometimes, a structure is even defined directly with a variable:
struct { char name[51]; int age; char street[51]; } users[10];
Consider this last example as a rather deterrent code. Just because it's a little bit shorter doesn't always mean it's clearer. Furthermore, we can't use this sort of structure at multiple places in our program.
Note: Of course, we don't have to use structures all as arrays. They're
an ordinary data type just like int
. However, they increase
readability, so be sure to use it everywhere where you need to store multiple
values which are related to each other.
Note: Aside from structures, we can also declare so-called
union
s in the C language. Unions look the same as structures but
variables of the union
type can only have one of their items
(values) initialized. Meaning that each user could only have either a name, an
age, or a street address. This doesn't make much sense with users, however, it
may sometimes happen that we need to store items and each item is a bit
different. However, union
s didn't become very popular because it
gets troublesome to determine which of the values is initialized (therefore,
they're often wrapped in structures). All in all, we won't deal with unions
here.
We'll get back to structures once more throughout our courses. The source code for today's application is available for download below the article.
At this point, you have now finished the introductory course into the C
language. Congratulations, you're now aware of most of its constructs! Of course, we'll continue, there
are more exercises for you to practice, and then your journey shall continue in
the Dynamic memory management in the C language course. There, you'll learn how
to allocate memory dynamically, and no longer be limited by the lengths of
static arrays. Since these matters are a bit complicated, the whole basics
course avoided said constructs so you could try different, simpler C constructs
while you get warmed up. I look forward to seeing you all soon. There, we'll
create real-world applications!
In the following exercise, Solved tasks for C lesson 13, we're gonna practice our knowledge from previous lessons.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 1x (71.72 kB)
Application includes source codes in language C