Learning the C Programming Language as a Classical Musician [11]

Episode 11 – Types (Part 3: Practical Examples)

Welcome back!

After the struggle that the last two episodes have been, full of theoretical concepts, some of them obscure and even unused in today’s programming, we have finally come to part where I will show you these types in practice. We watched at type classification in Episode 9, we tried to understand something of compatible and composite types in Episode 10, now we are going to check each of the most used data types in C and provide some examples, both in sheer programming style and, what this series is all about, in classical music style.

Let’s get started!

Arithmetic types (Part 1)

Let’s start with reviewing what arithmetic is: it is the branch of mathematics dealing with the properties and manipulation of numbers. With this out of the door, we can deal with what are the most basic types in C, arithmetic types. I do not say basic because they are simple, but because they are the base upon which other types can be built. For example, we cannot have a function that returns an integer and accepts two decimal numbers without first knowing what these types are, exactly as we cannot write a full-fledged composition without first knowing what a musical period is, or what a bar of music can be made of. I love this kind of comparisons because they even out your level, making you realise that, regardless of what you learn, the process is always the same.

These types are classified into several families: Boolean types, character types, integer types, and floating types, these last ones subdivided into real, complex, and imaginary. It is clear that, when studying programming, a solid knowledge of mathematic helps, so a computer scientist will always start with a good advantage over a regular learner as I am, but, in the end, it is always the amount of effort you put into things that counts.

Boolean type

A Boolean type is the computer representation of the true and false value. It comes from the British mathematician, philosopher, and logician George Boole (1815–1864) who, in 1854, introduced the concept of Boolean algebra in his book ”The Laws of Thought”. This concept is something that every college student of mathematics or engineering must have grasped before attending their first semester. I know, I did not study mathematics, nor engineering, rather cello and its classical music application, but mathematics has been my passion ever since, as a 4-year-old boy, I was playing with the calculator instead of playing soccer. When I completed scientific high school I had a choice, mathematics or music, and I chose music. I think that was the best choice I could have done at the time and, think about it, you would not be reading this had I decided differently, what a loss!

So, how do we express the true and false statements in a computer? If you think of the tiny transistors that populate a computer’s processor, they are actually smallest, tiniest lamps sending an on or off signal or state, and they express it through the binary values 1 for on, and 0 for off. This logic provides the same balance that, in music, is created by the alternation of sound and silence, which are equally important and have to coexist to produce something coherent and nice to listen.

Until the C23 revision of the C programming language comes out in 2023, the boolean value of true expands to the integer constant 1, while the boolean value of false expands to the integer constant 0. Having studied Swift, I know that true and false values can come baked into the programming language without needed too many translations in front of the user, so it is just normal that also the C programming language wants to join the family of modern languages with something similar. Here is a couple of examples I have prepared:

bool celloIsBeautiful = true;
_Bool playViolin = false; 
printf("%d %d\n", celloIsBeautiful, playViolin);

The type can be expressed with bool or _Bool, but to get the first one, you need to import a library, known as a header file, called stdbool.h, at the top of the file, after #include <stdio.h>. When we build and run this, we get simply this output:

1 0
Program ended with exit code: 0

And that’s it. When we go out in Swift to print the value of a Boolean variable or constant, we get true or false printed out, while here we only get their converted number.

Logical Operators

I would like to make a short digression now to introduce you to two logical operators, and and or. This will work wonders when dealing with conditional code, so it is better to get a grasp on them as early as possible.

The logical and operator is written as two ampersand characters, one next to the other && and returns true if both the statement to its left and the one to its right evaluate as true. For example:

_Bool celloRocks = true;
printf("%d\n", celloRocks && celloIsBeautiful);

Prints 1 in the console, that is true. If we had substituted playViolin to any of the two statements it would have returned 0, that is false, after all you cannot play violin if you are totally mesmerised by your cello.

The logical or operator is written as two pipe characters ||, which, on the Italian keyboard, are obtained via holding down Shift and pressing \, the key next to the 1 in the numbers row. This expression will evaluate to true if either of the two statements around it is true. So, the following would evaluate as true:

_Bool playBeethoven9 = true;
_Bool playBeethoven8 = false;
_Bool listeningPlan = playBeethoven9 || playBeethoven8;
printf("%d\n", listeningPlan);

Here we created two statements, showing that we want to listen to the 9th Beethoven symphony but not to its 8th one (as beautiful as it can be). We then create a listeningPlan object holding the result of the or logical operation.

These two logical operators complete and complement the equal to == and not equal to != operators in the management of conditional code. In case you wondered, the single equal sign = is called the assignment operator, and it assigns the value to the right of the equal sign to the object position to the left of the equal sign, effectively storing it inside the object.

Characters

We touched on the concept of characters during Episode 4, where we printed onscreen the values of each of the ASCII characters available using a loop.

Characters are the symbols we can find on our keyboard. They use the char type specifier, and they hold a small number range, namely as we say 0 to 127. To assign a letter to an object, we need to enclose it within two quote characters '. The interesting aspect of all this is that what we write is not actually a character, rather a specific number, as we saw in the ASCII table. Let’s see this is practice:

char c;
c = 'm';
printf("The letter %c has a value of %d\n", c, c);

We start by declaring a character variable (variable meaning that we can change its stored value afterwards, and it distinguishes itself from its opposite, the constant, for which we would need to add the const type qualifier) called c; on the next line we initialise it with the value of 'm'. Now for the funny part: we ask the compiler to print the value as character (using the %c conversion specifier) and as integer (using the %d conversion specifier) of our c object. The return will be:

The letter m has a value of 109

But we can do better, try this:

printf("The lowercase letter %c has a value of %d\nUppercase letter %c has a value of %d\n", c, c, c-32, c-32);

It will print out this:

The lowercase letter m has a value of 109
Uppercase letter M has a value of 77

Here we learn that an uppercase letter character precedes its lowercase equivalent in the ASCII table by 32 units.

There are times when we would need to use the signed char and unsigned char types, which are character that can hold negative value (< 0) and characters which can’t. The reason they exist and what we should do when we encounter them is both too complicated for now and not really useful for your understanding of characters. The type you need to worry about and be aware of is char, which is the type used for character representation. According to the language implementation—that is, the rules that make up the programming language—char is equivalent to either signed char or unsigned char, but, watch out, it is a distinc type in its own, different from both signed char and unsigned char. This is not too complex to understand, and also relieves us from the burden of having to think of three different types of characters. For what is important to us, char is the type we want to know of.

The last essential thing to keep in mind is that those 128 slots are not enough to hold all possible characters used by human languages, or to represent emojis. In Episode 6 we looked at identifiers, where we used a Unicode point to represent the violin’s emoji. This is done with a sequence of characters preceded by the \U escape sequence (any single character preceded by a backslash is part of an escape sequence, more on this in the future). To our rescue come several evolutions of the character type which, in its base form, is also known as single-byte character constant, having a size of 1 byte (8-bit). For example, we have 16-bit (2-byte) wide character constants to hold Chinese characters, or 32-bit (4-byte) wide character constants to hold emojis, or even multi character constants, which are used to initialise and occupy successive bytes of memory.

What comparison can we find between characters in programming and music? For sure, we cannot look at what a character represents in music because when you find it, it is almost always part of a longer string, e.g., “Allegro moderato”, or of a character sequence such as the one used for rehearsal marks (A, B, C, …). Characters being the smallest form of letter expression, we could approach them to some foundational elements of music notation, such as noteheads, or stems, or flags, elements which, on their own, mean little, but are part of a truly bigger picture.

What’s next?

In the next episode, we will continue our journey through C types, tackling integer types for sure, and possibly introducing floating-point types.

Bottom Line

Thank you for reading today’s article.

If you have any question or suggestion, please leave a comment below or contact me using the dedicated contact form. Assuming you do not already do so, please subscribe to my newsletter on Gumroad, to receive exclusive discounts and free products.

I hope you found this article helpful, if you did, please like it and share it with your friends and peers. Don’t forget to follow me on this blog and to let me know what you think.

If you are interested in my music engraving services and publications don’t forget to visit my Facebook page and the pages where I publish my scores (Gumroad, SheetMusicPlus, ScoreExchange and on Apple Books).

You can also support me by buying Paul Hudson’s Swift programming books from this Affiliate Link or BigMountainStudio’s books from this Affiliate Link.

Thank you so much for reading!

Until the next one, this is Michele, the Music Designer.

Published by Michele Galvagno

Professional Musical Scores Designer and Engraver Graduated Classical Musician (cello) and Teacher Tech Enthusiast and Apprentice iOS / macOS Developer Grafico di Partiture Musicali Professionista Musicista classico diplomato (violoncello) ed insegnante Appassionato di tecnologia ed apprendista Sviluppatore iOS / macOS

One thought on “Learning the C Programming Language as a Classical Musician [11]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: