Declaring and initializing variables

Declaring variables

In C, we always declare a variable by stating the data type and the name of the variable using syntax data_type variable_name; .

When multiple variables of the same data type are declared, they are separated by commas using syntax data_type variable_name_1, variable_name_2;. Any number of variables can be declared this way, but the greater the amount, the more unreadable the code gets!

Initializing variables

Any variable can be initialized when declared by assigning it a value following data_type variable_name = initial_value;  syntax. As  highlighted by the coding style document, only one variable should be declared per line when initializing variables! This is important for code readability.

Data types

C leaves a lot of uncertainty to variable types. The C standard only specifies the minimum size and  relationship between types. This is important to keep in mind, whenever a size is listed as a fixed number with confidence!

The following table only lists the most basic types and formats as a basic reference. For a more complete overview, see https://en.wikipedia.org/wiki/C_data_types or https://www.tutorialspoint.com/cprogramming/c_data_types.htm

 
Data type Minimum size (bytes) Use case Format Comments
char 1 character %c ASCII encoding
char [] ? string %s Zero-terminated array of ASCII characters
int 2 smaller integers %d %i Size varies by platform
long 4 larger integers %ld %li Size varies by platform. Recommend using bit-width integers instead
float 4 real numbers, floating point %f low precision, avoid for monetary values etc.
double 8 real numbers, double precision floating point %lf better precision, still unsuitable when precision is required

Comment: the minimum size and relationship is very noticeable when programming microcontrollers. E.g. a typical desktop, laptop or a server will have int  as 4 bytes, but most commonly used Arduinos have int  as 2 bytes. Similarly long  data type has to be 2x bigger compared to int , so on a desktop, it’s likely 8 bytes and on an Arduino it’s likely 4 bytes. This is also varies based on which processor the Arduino microcontroller uses.

For bit-width integer data types, see inttypes.h  library. This is covered in Programming 1.

Declaring arrays

Declaring arrays follows the same syntax as variables, but adds the size of the array to the declaration, i.e. data_type array_name[array_size];  . Specifying size is mandatory for static arrays.

To avoid magical numbers, either a macro ( #define ) or const  variable often is used.

Initializing arrays

Arrays can be initialized during declaration, by assigning either all values or a subset of values, that are listed between the { }  brackets, i.e. data_type array_name[array_size] = {val_1, val_2, ..., val_n-1}; .

When an array is initialized, the array_size  can be omitted, allowing the compiler to calculate the array size based on the number of initialized values.

Zero-initializing an array

Arrays can be zero-initialized by using syntax data_type array_name[array_size] = {0};. Note that if you omit the array size while zero-initializing, the array size becomes 1!

Declaring and initializing multidimensional arrays

All array dimensions must be specified during declaration. To declare a 2-dimensional array, we would typically use data_type array_name[row_cnt][col_cnt]; notation. Use of rows and cols is illustrative (think of an excel spreadsheet), but also a very common in practice.

When initializing a 2-D array, we use nested brackets to identify rows. Alignment of values is optional, but helpful for maintainability.

Note, that you can omit the first dimension (i.e. row count) in any multidimensional array, however it would need to be calculated later on to iterate over the array.

Declaring strings

Strings are handled as zero-terminated arrays in C. Each array member is a character represented in ASCII code, taking up 1 byte. Strings always need to have one extra character in reserve for the zero terminator.

Note:  This way of reading strings is discouraged in C, but was left as a illustration to keep it simple and short. Proper ways to read strings will be introduced in the appropriate lesson.

Initializing strings

Strings are often initialized as string literals, omitting the array length – this allows the compiler to identify the size. Strings are always surrounded by double quotes, while single characters are between single quotes.

In the following example, the string will contain 13 characters, however the array will be declared for 14 bytes to allow for the terminating NUL character. The phrase zero-terminated comes from the ASCII symbol NUL having integer value 0 (zero).

Most of the time, an asterisk before the variable name is used instead of the empty square brackets. This has the exact same effect.

Initializing an empty string

To initialize an empty string, we need to make sure that the string has an appropriate length for the use case we are planning for it.

DO NOT use char *string = "";  or char string[] = ""; . The compiler will calculate the size based on the initialization – these are empty strings containing only the NUL byte string terminator, resulting them being 1 byte long and thus not fitting any characters.

Declaring an array of strings

Arrays of strings are handled similarly to two-dimensional arrays, with a few exceptions depending on how the declaration was created.

The declaration char strings[num_of_strings][string_length]; allows to create a fixed number of strings indicated by the first dimension (i.e. num_of_string ), where each string can be up to string_length - 1  characters. All strings will take up the same amount of memory regardless of actual length.

This type of declaration is uncommon and largely impractical. A more common example is listed under the next chapter.

Initializing an array of strings

An array of strings is typically declared as an array of pointers to strings using the following syntax:

char *strings[] = {"string1", "string2", ..., "string_n-1"};

This has the benefit of having the compiler figure out the sizes for both the array and for each initialized string. This is also the structure for command line arguments.