What's included in C language

C programming: variables and constants

What are variables?

Next we want to develop a program that does the surface of a cuboid. One denotes the length of the cuboid with , the width with and the height with , then the formula applies

.

Once introduced variable, so here , and also , is fixed in mathematics in the further course of the argument: it changes neither its value nor its meaning.

There are also variables in programming, but they are used differently there than in mathematics: A variable represents a memory location, the content of which can be changed at any time during the entire lifetime of the variable. For example, it is possible to calculate any number of cuboids one after the other without having to introduce new variables each time.

So a variable can have its own during programming value to change. However, it shows bad programming style, in the course of the source code the importance to change a variable. For example, if you have a variable called radius, in which the radius of a circle is stored, one should be careful not to store the area of ​​the same circle or something completely different in it. This would make the source text much less understandable.

You can read more about naming variables in the Naming section.

The program for calculating a cuboid surface could look something like this:

#include intmain (void) {inta, b, c; printf ("Please enter the length of the cuboid: \ n"); scanf ("% d", & a); printf ("Please enter the width of the cuboid : \ n "); scanf ("% d ", & b); printf (" Please enter the height of the cuboid: \ n "); scanf ("% d ", & c); printf (" Cuboid surface: \ n% d \ n ", 2 * (a * b + a * c + b * c)); return0;}
  • Before a variable can be used in C, it must be defined (line 5). That means, Identifier (Name of variable) and (data)Type (here) must be determined by the programmer, then the computer can allocate the appropriate memory space and also address the variable (see later: C programming: pointer). In the sample program, the variables a, b, and c are defined as integers.
  • With the library function we can read in a value from the keyboard and save it in a variable (more on the instruction in the next chapter).
  • This program does not contain any error detection code; d. That is, if you enter something else or nothing at all instead of the whole numbers, very strange things happen. At first it is only a question of getting to know the functions for input and output. When writing your own programs, you should be careful to handle such errors.

Declaration, definition and initialization of variables [edit]

As is well known, all data in the main memory are addressed via addresses. You can think of this like house numbers: Each memory cell has a unique number that is used to find stored data. However, a program would be very confusing if every variable were addressed with the address. Therefore, instead of addresses Identifier (Names) used. The compiler then converts this into the relevant address.

In addition to the identifier of a variable, the Type must be specified with. The compiler can use the type to determine how much memory a variable requires in the main memory.

The type also tells the compiler how to interpret a value in memory. For example, the internal representation of floating point numbers (numbers with decimal places) and integers (numbers without decimal places) usually differs, even if the ANSI-C standard says nothing about how these must be implemented. However, if two numbers are added, for example, this process differs for floating point numbers and integers due to the different internal representation.

Before a variable can be used, the type and identifier must be communicated to the compiler. This process is known as declaration.

In addition, memory space must be reserved for the variables. This happens with the definition the variable. The properties are defined and storage space is reserved. While a declaration can appear several times in the code, a definition can only appear once in the entire program.

Notice
  • declaration is only the assignment of a name and a type for the variable.
  • definition is the reservation of the storage space.
  • initialization is the assignment of a first value.


The literature often does not differentiate between the terms definition and declaration and refers to both as declaration. This is correct in so far as every definition is also a declaration (the reverse is not true, however). Example:

This defines a variable with the identifier and the type (integer). A variable of the type integer and the identifier i is agreed and memory space is reserved. The variable is also declared with the definition. With

a variable is declared. The key word external in the above example means that the definition of the variable a is somewhere in another module of the program. This is how you declare variables that are later resolved when they are linked (left). Since no storage space has been reserved in this case, it is not a definition. The storage space is only about

reserved what has to be done in some other source code module.

Another note: The separation of definition and declaration is mainly used to accommodate source code in different modules. In the case of programs that only consist of one source file, it is usually not necessary to separate definition and declaration from one another. Rather, the variables are defined once before use, as you saw in the example from the last chapter.

You must observe the following rules for declaring variables:
Variables with different names but the same type can be declared on the same line. Example:

Defines the variables, and.

However, it is not permitted to declare variables of different types and names in a statement such as the following:

floata, intb; / * false * /

This example definition generates an error. On the other hand, it is correct to separate the definitions of and with a semicolon, although a new line should be used for each type for better readability:

C also distinguishes between upper and lower case letters when it comes to identifiers. The identifiers, and can stand for different variables or functions. Variable identifiers are usually written in lower case, which is also what this wiki book adheres to.

The following rules also apply to identifiers agreed by the programmer:

  • They must start with a letter or an underscore; would be wrong z. B.
  • They may only contain letters from the English alphabet (i.e. no umlauts or 'ß'), numbers and the underscore.
  • You cannot use a C keyword such as B. or correspond.

After a variable has been defined, it has no specific value (except for global variables or variables with a memory class), but only has the content that happened to be in the memory cell (also known as "garbage"). It only receives a value when this is assigned to it, e.g. B: with the input statement. You can also assign a value to the variable directly. Example:

or

Don't confuse the assignment operator in C with the equal sign in math. The equal sign means that the same is on the right side as on the left. The assignment operator, on the other hand, is used to assign the value of the expression on the right to the variable on the left.

The second assignment can also be written much shorter as follows:

This notation can also be applied to subtraction (- =), multiplication (* =), division (/ =) and the modulo operator (% =) and other operators.

A value can also be assigned to a variable when it is defined. This is known as initialization. In the following example, a variable is declared with the identifier of the type (character) and assigned the value 'b':

Integers [edit]

Integers are numbers without decimal places. There are the following types of integers in C:

  • (character): 1 byte [1] or 1 character (can be used to represent integers or characters)
  • (integer): integer value
  • (integer): integer value
  • (integer): integer value
  • (integer): integer value, from C99

If a type specifier (or) is present, the type specification is redundant, i.e.

is equivalent to

The declaration also specifies whether an integer variable should be signed. If a variable is to be declared unsigned, it must be preceded by the keyword. For example, about

defines an unsigned variable of the type. The type returns values ​​from at least -32,768 to 32,767. Variables of the type can only store non-negative values. Of course, the range of values ​​does not increase, but rather it shifts and lies in the range from 0 to 65,535. [2]

If an integer variable was not explicitly declared as signed or unsigned, it is always signed. For example,

the definition

Unfortunately, the sign rule for the data type is a bit more complicated:

  • If a numerical value is used to store the variable and the variable is not explicitly declared as signed or unsigned, it depends on the implementation whether it is signed or not.
  • When a character is stored, the standard guarantees that the stored value corresponds to the nonnegative coding in the character set.

What is the last point? A character set has the task of assigning a certain value to a character, since the computer itself is only able to store binary numbers. In the ASCII character set, for example, the character 'M' is stored as 77 decimal or 1001101 dual. You could also get the idea instead of

better

to use. However, the C standard says nothing about the character set used. If, for example, the EBCDIC character set is used, then 'M' suddenly becomes an opening bracket (see excerpt from the ASCII and EBCDIC character set table on the right).

ASCIIEBCDICDecimalBinary
L.<761001100
M.(771001101
N+781001110

One might counter that today mainly the ASCII character set is used. However, most programmers will still regard it as bad style to assign the coded value to the variable instead of the character, since it is not clear which character it is, and it is assumed that the variable is to be used for calculations in the subsequent program.

Variables of the character type are rarely used for calculations anyway, because they only have a very small range of values: It can only accept values ​​between -128 and +127 (signed) or 0 to 255 (unsigned) (but also larger on some implementations Values). The Integer type is therefore used to store whole numbers. There are two variants of this type: The type is at least 16 bits wide, the type is at least 32 bits. A variable can also be declared as (i.e. without a preceding or). In this case, the standard stipulates that the type should have a "natural size". Such a natural size is for example an IA-32 PC (Intel architecture with 32 bit) with Windows XP or Linux 32 bit. On a 16-bit operating system such as MS-DOS, the size is 16 bits. However, it can also assume a different size on other systems. The keyword here is word length.

The type was also introduced with the C99 standard. It is at least 64 bits wide. However, it is not yet supported by all compilers.

An overview of the data types can be found in: C programming: Data types

Extended character sets [edit]

As you can easily imagine, the "space" for different characters with a single byte is very limited, considering that the character sets of different languages ​​differ. If there is still enough space for the European fonts, there is no longer any possibility for Asian fonts such as Chinese or Japanese to represent the many characters with one byte. When the C-Standard was revised in 1994, the concept of a wide character (wide character) introduced, which can also accept character sets that require more than 1 byte to encode a character (e.g. Unicode characters). Such a "wide character" is stored in a variable of the type.

If a character or a character string (which we will deal with in more detail later) should be assigned to a variable of the type, it looks like this:

charc = 'M'; chars [] = "A short string";

However, if we want to assign or initialize a character or a character string that consists of wide characters, we have to inform the compiler of this by using the prefix:

wchar_tc = L'M '; wchar_ts [] = L "A short string";

Unfortunately, the use of has another catch: All library functions that work with character strings can no longer be used. However, the standard library has corresponding equivalent functions for each character string function that work together with: In the case of, this is, for example.

Coding of strings [edit]

A character string can be filled with normal ASCII characters from the editor. E.g. Often one would like to insert characters into the character string that cannot be displayed with the editor. Most often this is probably the next line (linefeed) and the carriage return. There are no letters for these characters, but there are ASCII codes. There are special notations for this in C compilers:

NotationASCII no.description
\ n 10 New line
\ r 13 Carriage return
\ t 09 tab
\ b 08 Backspace
\ a 07 Alarm tone
\' 39 apostrophe
\" 34 quotation marks
\\ 92 Backslash sign
\ nnn 1..3 characters with octal code (0..7)
\ xhh 1..2 characters in hexadecimal code with (0..9A..F)

Floating point numbers [edit]

Floating point numbers (also known as floating point or floating point numbers) are numbers with decimal places. The C standard recognizes the following three floating point types:

  • The type for single precision numbers.
  • The type for double-precision floating point numbers.
  • The type for extra accuracy.

The C standard says nothing about how the floating point numbers are represented internally in the computer. The range of values ​​a floating point number type has on an implementation can, however, be determined from the header file.

In contrast to integers, there is no difference between signed and unsigned numbers with floating point numbers. All floating point numbers are always signed in C.

Note that numbers with decimal places must be represented in US notation. For example, the notation must be used for the number.

Determine the memory requirement of a variable [edit]

The operator can be used to determine the length of a type on a system. In the following example, the memory requirement is to be output in bytes of the type:

#include intmain (void) {intx; printf ("The type int has the size% lu bytes on this system. \ n", (unsignedlong) sizeof (int)); printf ("The variable x has on this system the size% lu bytes. \ n ", (unsignedlong) sizeofx); return0;}

After running the program you will get the following output:

The type int has a size of 4 bytes on this system. The variable x on this system is 4 bytes.

The output may be different on a different system depending on how wide the type is. In this case the type is 4 bytes long. How much storage space a variable type has depends on the implementation. The standard only stipulates that the value must always be 1.

Note that this is not a function, it is actually an operator. Among other things, this means that a header file does not have to be integrated, as would be the case with a function. The header file integrated in the sample program is only required for the library function.

The operator is often used to write programs that are portable to other platforms. You will get to know some examples in this wiki book.

The result of the operator is a value of the data type. It is an unsigned integer data type; its bit width depends on the implementation. The C standard does not prescribe a fixed assignment or any other data type.

If you want to output a value with a function of the family, you should explicitly convert the value to the unsigned integer data type that corresponds to the placeholder used.

Constants [edit]

Symbolic constants [edit]

In contrast to variables, constant values ​​cannot change during their entire lifespan. This can be useful, for example, when constants are defined at the beginning of the program so that they only have to be adjusted at one point in the source code.

One example of this is value added tax. If it is increased or decreased, it only needs to be changed at one point in the program. In order to avoid a conscious or unconscious error on the part of the programmer, the compiler prevents the constant from being assigned a new value.

In the original language definition by Dennis Ritchie and Brian Kernighan (K&R) there was only the possibility of defining symbolic constants with the help of the preprocessor. The preprocessor instruction is used for this. It has the following syntax:

#define IDENTIFIER token-sequence

Please note that preprocessor instructions are not terminated with a semicolon.

By the instruction

every occurring VAT string is replaced by the number 19. The only exception is for character strings that are enclosed in quotation marks or single quotes, such as the expression

"The current VAT"

The string VAT Not replaced.

Capitalization is not required by the standard. It is not a mistake to name the constant or instead. However, most programmers use capital letters for symbolic constants. This wiki book also adheres to this convention (the symbolic constants of the standard library are also written in capital letters).

DANGER: Working with can also fail: Since only a simple search-and-replace by the preprocessor does the following, the following code will not deliver the desired result:

#include #define square (x) x * x // incorrect square implemented intmain (intargc, char * argv []) {printf ("The square of 2 + 3 is% d \ n", quadrat (2 +3)); return0;}

When you run this program it will tell you that the square of 2 + 3 = 11. The reason for this is that the preprocessor is replaced by.

Since the compiler adheres to the dot-before-line calculation rule, the result is incorrect. In this case you can modify the program as follows so that it calculates correctly:

#include #define square (x) ((x) * (x)) // correct square implementationintmain (intargc, char * argv []) {printf ("The square of 2 + 3 is% d \ n ", square (2 + 3)); return0;}

Define constants with [edit]

The disadvantage of defining constants with is that the compiler does not know the type of the constant. This can lead to errors that are only discovered when the program is running. With the ANSI standard, C ++ has therefore adopted the option of declaring a constant with the keyword. In contrast to a constant that was defined via, a constant that was also declared can use up memory space like variables in older compilers. With newer compilers such as GCC 4.3, the variant is always preferable because it allows the compiler to optimize the code better and increases the compilation speed. Example:

#include intmain () {constdoublepi = 3.14159; doubled; printf ("Please enter the diameter: \ n"); scanf ("% lf", & d); printf ("Circumference of the circle:% lf \ n ", d * pi); pi = 5; / * error! * / return0;}

The constant is declared in line 5. It must be assigned a value immediately, otherwise the compiler will output an error message.

In order for the program to be translated correctly, line 11 must be removed, as an attempt is made there to assign a new value to the constant. The keyword, however, instructs the compiler to prevent this from happening.

Visibility and lifetime of variables [edit]

In earlier C standards, a variable always had to be declared at the beginning of a statement block. Since the C99 standard, this is no longer absolutely necessary: ​​it is sufficient to define the variable immediately before using it for the first time.[3]

An instruction block can be a function, a loop, or just a block of instructions delimited by curly braces. A variable always lives until the end of the statement block in which it was declared.

If a variable / constant is e.g. B. agreed in the head of a loop, according to the C99 standard it belongs to the block in which the code of the loop is also located. The following code snippet should clarify this:

for (inti = 0; i <10; i ++) {printf ("i:% d \ n", i); // output of locally declared loop variable} printf ("i:% d \ n", i); / / Compiler error: i is no longer valid here!

If there is a variable in a block with a name that is also used in the surrounding block, then in the inner block the name of the variable of the inner block is used, which becomes the outer one covered.

#include intmain () {intv = 1; intw = 5; {intv; v = 2; printf ("% d \ n", v); printf ("% d \ n", w); } printf ("% d \ n", v); return0;}

After compiling and running the program, you get the following output:

2 5 1

Explanation: At the beginning of the new statement block in line 8, a new variable is defined and assigned the value 2. The inner variable "covers" the value of the variable of the outer block. For this reason, the value 2 is also output in line 10. After the scope of the inner variable was left in line 12, it no longer exists, so that it can no longer cover the outer variable. The value 1 is therefore output in line 13.

If there is no such overlapping of names in nested instruction blocks, the variables of the outer can be accessed in an inner block. The number defined in line 6 can therefore be output in line 11.


  1. ↑ The C standard defines the width of a byte via the constant CHAR_BIT as implementation-dependent, which defines the number of bits. > = 8 is mandatory, CHAR_BIT == 8 is usual. However, this is only of interest if you want to develop programs that really should run on every computer, no matter how exotic.
  2. ↑ If you've done the math, you've probably noticed that 32,768 + 32,767 is only 65,534, and not 65,535, as you might guess. This is because the standard says nothing about how negative numbers are represented internally in the computer. For example, if negative numbers are stored in one's complement, there are two ways to represent the 0, and the range of values ​​is thus reduced by one. If the machine (e.g. the PC) uses the two's complement to represent negative numbers, the value range is between -32,768 and +32,767.
  3. ↑ With the popular GCC compiler you have to explicitly pass parameters for this