Can you know C ++ without knowing C.

day 2





week 1

Each C program consists of various components that are combined in a certain way. Most of this book deals with explaining these program components and showing how they are used. For the overall picture, it is helpful if you first look at a complete - albeit small - C program in which all components are identified. Today you will learn:

  • Know the purpose of the various program components
  • how to compile and run a sample program
  • how a program stores data
  • know the difference between a variable and a constant

A short C program

Listing 2.1 shows the source code for the program. This very simple program takes two numbers that the user enters on the keyboard and calculates the product of the two numbers. At the moment you don't need to worry about how the program works in detail. It's just a matter of getting to know the parts of a C program so that you can better understand the listings presented later in this book.

Before looking at the sample program, you need to know what a function is, since functions play a central role in C programming. A function is an independent section of code that performs a specific task and is assigned a name. A program references the function name to execute the code in the function. The program can also pass information - called arguments - to the function, and the function can return information to the body of the program. In C, a distinction is made between library functions that are part of the operating system under Linux and user-defined functions that are created by the programmer. You will learn more about both types of functions later in this book.

Note that the line numbers in Listing 2.1, as with all listings in this book, are not part of the program and are only intended for references in the running text. So do not include the line numbers.

Listing 2.1: Multiply the program. C multiplies two numbers.

1: / * Calculates the product of two numbers. * /
2: #include
3:
4: int a, b, c;
5:
6: int product (int x, int y);
7:
8: int main ()
9: {
10: / * Read in first number * /
11: printf ("Enter a number between 1 and 100:");
12: scanf ("% d", & a);
13:
14: / * Read in second number * /
15: printf ("Enter another number between 1 and 100:");
16: scanf ("% d", & b);
17:
18: / * Calculate and display product * /
19: c = product (a, b);
20: printf ("% d times% d =% d \ n", a, b, c);
21:
22: return 0;
23: }
24:
25: / * function returns the product of the two provided values ​​* /
26: int product (int x, int y)
27: {
28: return (x * y);
29: }

Enter a number between 1 and 100: 35
Enter another number between 1 and 100: 23
35 times 23 = 805

The components of a program

The following sections describe the various components of the example program from Listing 2.1. You can find the relevant positions quickly using the line numbers given.

The main () function (lines 8 through 23)

The only component that is required in every executable C program, but may only be present once, is the function. In its simplest form, this function just consists of the name followed by a pair of empty brackets () and a pair of curly braces (). Inside the curly brackets are the instructions that make up the main body of the program. Under normal circumstances, program execution begins with the first statement in and ends with the last statement in that function.

The #include directive (line 2)

The directive instructs the C compiler to include the content of a so-called include file in the program during compilation. An include file is a separate file with information that the program or the compiler needs. Several of these files are included in the scope of delivery of the compiler (one also speaks of header files). You never have to modify these files. For this reason, they are kept separate from the source code. Include files should have the extension (for example).

In Listing 2.1, the directive means: "Add the contents of the file to the program." Most C programs require one or more include files. More information on this can be found on Day 20, "Advanced Compilers".

The variable definition (line 4)

A variable is a name that refers to a specific storage location for data. A program uses variables to store various types of data during program execution. In C you have to define a variable first before you can use it. The variable definition informs the compiler of the name of the variable and the type of data that the variable can hold. The example program from Listing 2.1 defines in line 4 with the instruction

int a, b, c;

three variables named, and, each of which holds an integer value. You can find out more about variables and variable definitions in the section "Saving data: Variables and constants" later in this chapter.

The functional prototype (line 6)

Function prototypes inform the C compiler of the names and arguments of the functions occurring in the program. Before a function can be used in the program, the function prototype must have been made known in the program. A function prototype should not be confused with the function definition. The function definition contains the actual statements that make up the function. (Today's lesson covers function definitions later.)

Program instructions (lines 11, 12, 15, 16, 19, 20, 22 and 28)

The instructions do the real work of a C program. C statements are used to display information on the screen, read keystrokes, perform math operations, call functions, read files - in short, the statements perform all the operations a program has to perform. Most of this book explains the various C statements to you. For now you should keep in mind that you usually write one statement per line in the source code and that each statement must always end with a semicolon. The following sections briefly explain the instructions in the program.

The statement printf ()

The instruction on lines 11, 15 and 20 is a library function that displays information on the screen. As lines 11 and 15 show, the instruction can output a simple text message or - as in line 20 - the values ​​of program variables together with text.

The scanf () instruction

The instruction on lines 12 and 16 is another library function. It reads in data from the keyboard and assigns this data to one or more program variables.

The instruction in line 19 calls the function, i.e. it executes the program instructions contained in the function. It also passes the arguments and to the function. After the instructions in the function have been processed, it returns a value to the program. The program saves this value in the variable.

The return statement

Lines 22 and 28 contain statements. The statement on line 28 belongs to the function. The expression in the statement calculates the product of the values ​​in the variables and and returns the result to the program that called the function. Immediately before the program ends, the statement in line 22 returns the value 0 to the operating system.

The function definition (lines 26 to 29)

A function is an independent and self-contained section of code that is dedicated to a specific task. Every function has a name. To execute the code in a function, you specify the name of the function in a program statement. This execution is known as calling the function.

The function named on lines 26-29 is a user-defined function that the programmer (i.e., the C language user) creates during program development. The simple function on lines 26-29 just multiplies two values ​​and returns the result to the program that called the function. On Day 4, Functions, you will learn that using functions correctly is an important part of C programming.

In a "real" C program you will hardly set up a function for such a simple task as the multiplication of two numbers. The example program is only intended to illustrate the principle.

C also includes library functions that are part of the operating system or the C compiler package. Library functions mainly perform the general tasks (such as input / output with screen, keyboard and hard disk) that a program needs. In the example program, and are library functions.

Program comments (lines 1, 10, 14, 18 and 25)

Any part of a program that begins with the characters and ends with the characters is a comment. Since the compiler ignores all comments, they have no influence on the way the program works. You can write anything in comments without it being noticed in any way in the program. A comment can only cover part of a line, an entire line or several lines. Here are three examples:

/ * A single line comment * /

int a, b, c; / * A comment that only affects part of the line * /

/* A comment,
which extends over several
Lines extends. * /

Be careful not to use nested comments. A nested comment is a comment that appears within the delimiters of another comment. Most compilers don't accept constructions like:

/*
/ * Nested comment * /
*/

Some compilers allow nested comments. Although it seems tempting, you should generally avoid nested comments. One of the advantages of C is known to be portability, and constructions such as nested comments can limit the portability of your code. In addition, such comment constructions often lead to problems that are difficult to find.

Many novice programmers consider comments unnecessary and a waste of time. That is a big mistake! The way a program works may be perfectly clear by the time you write the code. But as soon as your program becomes larger and more complex or if you have to change your program after six months, comments are an invaluable help. At the latest then you should realize that comments should be used generously in order to document all program structures and processes.

Many programmers have adopted a newer style of comment in their C programs. In C ++ and Java you can mark comments with double slashes, as the following examples show:

The slashes indicate that the rest of the line is a comment. Although many C compilers support this form of comment, it should be avoided if the portability of the program is to be preserved.

What you should be doing

What not

Be generous with comments in the source code of your program, especially for instructions or functions that may later appear unclear to you or to another programmer who may need to modify the code.

Don't add unnecessary comments for instructions that are already clear. For example, the following comment is excessive and redundant, at least after you are familiar with the statement:

Develop a style that is useful. Too frugal or cryptic comments are useless. On the other hand, if the comments are too extensive, you spend more time commenting than programming.

/ * The following statement returns the string Hello World! on the screen from * /
printf ("Hello world! \ n");

Curly braces (lines 9, 23, 27 and 29)

With the curly brackets and you enclose program lines that form a C function - this also applies to the function. A group of one or more statements within curly brackets is called a block. In the following lessons you will get to know many other uses for blocks.

Run the program

Take the time to enter, compile, and run the program. It brings you a little more practice in using the editor and compiler. To repeat, the steps analogous to Lesson 1, "Introduction to Linux and the C programming language," should be mentioned here:

  1. Make your programming directory the current directory.
  2. Start the editor.
  3. Enter the source code for exactly as shown in Listing 2.1 (except for the line numbers with a colon).
  4. Save the program file.
  5. Compile and link the program with the corresponding command of your compiler. If no error messages appear, you can run the program by typing at the command prompt.
  6. If the compiler displays error messages, go back to step 2 and correct the errors.

A note on accuracy

A computer works quickly and accurately. However, he takes everything literally and he cannot even correct the simplest mistakes. It therefore takes over everything exactly as you entered it and not as you meant it!

This also applies to your C source code. A simple spelling mistake in the program - the C compiler complains and aborts the compilation. Fortunately, even if the compiler cannot correct your mistakes (which you will inevitably too), it is fortunately intelligent enough to recognize and report errors. (How the compiler reports errors and how to interpret them was the subject of yesterday's lesson.)

The parts of a program at a glance

After this lesson has explained all the parts of a program, you should be able to look at any program and find some similarities. Try to see the different parts in Listing 2.2.

Listing 2.2: List the program. C lists code listings

1: / * list.c Displays a listing with line numbers * /
2: #include
3: #include
4:
5: void display_use (void);
6: int line;
7:
8: int main (int argc, char * argv [])
9: {
10: char buffer [256];
11: FILE * fp;
12:
13: if (argc <2)
14: {
15: show_use ();
16: return 1;
17: }
18:
19: if ((fp = fopen (argv [1], "r")) == NULL)
20: {
21: fprintf (stderr, "Error opening file,% s!", Argv [1]);
22: return 1;
23: }
24:
25: line = 1;
26:
27: while (fgets (buffer, 256, fp)! = NULL)
28: fprintf (stdout, "% 4d: \ t% s", line ++, buffer);
29:
30: fclose (fp);
31: return 0;
32: }
33:
34: void display_use (void)
35: {
36: fprintf (stderr, "\ nstart the program as follows:");
37: fprintf (stderr, "\ n \ nlist filename.ext \ n");
38: }

./list list.c
1: / * list.c Displays a listing with line numbers * /
2: #include
3: #include
4:
5: void display_use (void);
6: int line;
7:
8: int main (int argc, char * argv [])
9: {
10: char buffer [256];
11: FILE * fp;
12:
13: if (argc <2)
14: {
15: show_use ();
16: return;
17: }
18:
19: if ((fp = fopen (argv [1], "r")) == NULL)
20: {
21: fprintf (stderr, "Error opening file,% s!", Argv [1]);
22: return;
23: }
24:
25: line = 1;
26:
27: while (fgets (buffer, 256, fp)! = NULL)
28: fprintf (stdout, "% 4d: \ t% s", line ++, buffer);
29:
30: fclose (fp);
31: return 0;
32: }
33:
34: void display_use (void)
35: {
36: fprintf (stderr, "\ nstart the program as follows:");
37: fprintf (stderr, "\ n \ nlist filename.ext \ n");
38: }

The program in Listing 2.2 displays C program listings that you have saved. The listings are displayed on the screen with line numbers.

You will certainly be able to recognize the various parts of the program in Listing 2.2. The mandatory function is in lines 8 to 32. Lines 2 and 3 contain directives. In lines 6, 10 and 11 you will find variable definitions. Line 5 contains the function prototype. The program also includes several instructions on lines 13, 15, 16, 19, 21, 22, 25, 27, 28, 30, 31, 36 and 37. The function definition for extends from lines 34 to 38. Throughout the program, blocks are enclosed in curly brackets. Finally, a comment is given in line 1. Most programs are likely to have far more comments.

The program calls several functions. It only contains one user-defined function -. The functions in line 19, in lines 21, 28, 36 and 37, in line 27 and in line 30 are library functions. The remaining lessons cover these library functions in more detail.

Saving data: variables and constants

As you can see in Listing 2.1, three variables have been defined in line 4. Computer programs usually work with different types of data and need a way to store the values ​​they use. These values ​​can be numbers or characters. There are two ways of storing numeric values ​​in C - variables and constants. And both options have a multitude of options. A variable is a memory location with a value that can change in the course of program execution. A constant, on the other hand, has a fixed value that is not changed. Before we get into variables, though, it's a good idea to learn a little bit about how memory works in your computer.

If you already know how a computer's memory works, you can skip this section. If you are unsure, just read on. The knowledge imparted here will help you to better understand certain aspects of C programming.

A computer stores information in random access memory (RAM). The RAM - or main memory - is implemented in the form of so-called chips. The content of these chips is volatile, i.e. the information is deleted as required and replaced by new ones. But it also means that the RAM only "remembers" this information as long as the computer is running. If you switch off the computer, the stored information is also lost.

RAM is built into every computer. The amount of installed memory is given in megabytes (Mbytes), such as 1 Mbyte, 8 Mbyte, 32 Mbyte, 64 Mbyte or more. A megabyte is 1024 kilobytes (Kbytes) and a kilobyte is 1024 bytes. A system with 4 Mbytes of RAM actually has a size of 4 * 1024 kilobytes or 4096 Kbytes. That is 4096 * 1024 bytes or 4 194 304 bytes of RAM.

A byte is the basic unit of storage in a computer. For more information about bytes, see Lesson 18, "Using Memory". Table 2.1 gives an overview of the number of bytes required to store certain types of data.

Data

Number of bytes

The letter x

1

The number 500

2

The number 241105

4

The text C in 21 days

14

A typewriter page

about 3000

Table 2.1: Storage requirements for different types of data

The main memory is organized continuously, one byte follows another. Each byte in the memory can be addressed by a unique address - an address that also distinguishes a byte from every other byte. The addresses are assigned to the memory locations in consecutive order, starting with 0 and increasing up to the maximum size of the system. At the moment you don't have to worry about addresses, the C compiler will take care of it for you.

The RAM in the computer is used for several purposes. As a programmer, however, you are primarily concerned with data storage. Data is the information with which a C program works. Whether a program maintains a mailing list, monitors the stock market, runs a budget, or tracks pork prices, the information (names, stock prices, expenses, or future pork prices) is held in RAM while the program is running.

After this brief excursion into the hardware world of computer memory, it goes back to C programming and the way in which C stores information in main memory.

variables

A variable is a named storage location for data in the main memory of the computer. If you use the variable name in a program, you are referring to the data that is stored under this name.

Variable names

To use variables in C programs, you have to know how to create variable names. In C, variable names must meet the following rules:

  • The name can contain characters, numbers, and the underscore ().
  • The first character of a name must be a letter. The underscore is also permitted as the first character, but this option should not be used.
  • C is case-sensitive in names, i.e. the variable names, and denotes two completely different variables.
  • C keywords are not allowed as variable names. A keyword is a word that is part of the C language. (For a full list of C Keywords, see Appendix B.)

Here are some examples of allowed and not allowed C variable names:

Variable name

admissibility

allowed

allowed

allowed

allowed but not recommended

not allowed: contains the character #

not allowed: is a C keyword

not allowed: first character is a digit

Because C names are case sensitive,, and are three different variable names. C programmers often only use lowercase letters in variable names, although this is by no means required. On the other hand, all capitalization is usually used for constants (see later in this lesson).

With many compilers, a variable name can be up to 31 characters long. (In fact, it can be longer, but the compiler only looks at the first 31 characters of the name.) This can be used to generate names that say something about the stored data. For example, if a program is calculating loan payments, it might store the value of the initial interest rate in a variable called. The usage is clear from the variable name. You could also have created a variable named or even, it doesn't matter to the compiler. But if another programmer looks at your source code, the meaning of such variables remains completely in the dark. Even if it means a little more effort to type meaningful variable names, the more understandable source code is definitely worth the effort.

There are numerous naming conventions for variable names made up of several words. You have already seen an example:. If you separate the words from each other with an underscore, the variable name can be easily interpreted. The second style is called camel notation. Instead of spaces (which the underscore should represent), the first letter of each word is capitalized and all words together. The above variable would then have the name. The camel notation is gaining more and more supporters because a capital letter is easier to enter than the underscore. However, the book uses underscored variable names because such names are easier to recognize. Decide for yourself which style you want to join or whether you want to develop your own.

What you should be doing

What not

Use variable names that are meaningful.

Decide on a spelling for the variable names and then keep this style throughout.

Do not start variable names with an underscore unless required.

Avoid the continuous capitalization of variable names. This notation has become common for constants.

Numeric variable types

C offers several data types for numeric variables. These different variable types are necessary because, on the one hand, the different types of numerical values ​​have different memory requirements and, on the other hand, the mathematical operations that can be carried out are not the same for all types. Small integers (for example,, and) require less memory and the computer can perform math operations on such numbers very quickly. In contrast, large integers and floating point numbers (such as, and) require more storage space and significantly more time in math operations. If you choose the right types of variables, you can make a program more efficient.

The numeric C variables can be divided into two categories:

  • Integer variables accept values ​​that do not have a fraction (i.e. only whole numbers). This data type has two forms: signed integer variables can store both positive and negative values ​​(and 0), while unsigned integer variables can only store positive values ​​(and 0).
  • Floating point variables store values ​​that can also have a fractional part (i.e. real numbers).

There are two or more types of variables within these categories.

You can use the program shown in Listing 2.3 to determine the size of the variables for your computer. It also gives the maximum and minimum values ​​of the integer variable types. Why should you get this kind of information with a program? As was briefly mentioned on day 1, Linux runs on many computers. The size of some variable types on a Linux computer with an Intel Pentium processor (part of the Intel IA32 family) is not the same as on a Linux computer running with a DEC / Compaq Alpha processor.

Listing 2.3: groessevon.c - A program that shows the size of some types of variables on your computer in bytes.

1: / * A program that takes the size of the different * /
2: / * Outputs C variables on your computer. * /
3: #include
4: #include
5 :
6: int main (void)
7 : {
8: printf ("Signed: Size% 20s% 22s \ n", "Min", "Max");
9: printf ("char:% d% 22d% 22d \ n",
10: (int) sizeof (char), CHAR_MIN, CHAR_MAX);
11: printf ("short:% d% 22d% 22d \ n",
12: (int) sizeof (short), SHRT_MIN, SHRT_MAX);
13: printf ("int:% d% 22d% 22d \ n",
14: (int) sizeof (int), INT_MIN, INT_MAX);
15: printf ("long:% d% 22ld% 22ld \ n",
16: (int) sizeof (long), LONG_MIN, LONG_MAX);
17: printf ("\ n");
18:
19: printf ("Unsigned: size% 20s% 22s \ n", "Min", "Max");
20: printf ("char:% d% 22d% 22u \ n",
21: (int) sizeof (unsigned char), 0, UCHAR_MAX);
22: printf ("short:% d% 22d% 22u \ n",
23: (int) sizeof (unsigned short), 0, USHRT_MAX);
24: printf ("int:% d% 22d% 22u \ n",
25: (int) sizeof (unsigned int), 0, UINT_MAX);
26: printf ("long:% d% 22d% 22lu \ n",
27: (int) sizeof (unsigned long), 0, ULONG_MAX);
28: printf ("\ n");
29:
30: printf ("single prec. Float:% d \ n", (int) sizeof (float));
31: printf ("double prec. Float:% d \ n", (int) sizeof (double));
32:
33: return 0;
34: }

Don't be concerned that you don't understand how the program works. Even if some items are new, such as new, you are sure to be familiar with others. Lines 1 and 2 are comments that contain the name of the program and a brief description. Lines 3 and 4 include two header files that are understood by all ANSI / ISO-C compilers by default. In this simple example program there is only one function, namely in lines 6 to 34. Lines 9 to 31 form the core of the program. Each of these lines outputs a verbal description with the size of each variable type, whereby the program determines the size of the variable with the operator. See Chapter 17, "The Library of C Functions," for more information on this operator. Line 33 returns the value 0 to the operating system before the program ends.

And this is what the output of the program looks like, which was compiled and executed on a Linux computer with an Intel x86 processor.

./size of
Signed: size min max
char: 1 -128 127
short: 2 -32768 32767
int: 4 -2147483648 2147483647
long: 4 -2147483648 2147483647
Unsigned: size min max
char: 1 0 255
short: 2 0 65535
int: 4 0 4294967295
long: 4 0 4294967295
single prec. float: 4
double prec. float: 8

And this is what the output of the program looks like, which was compiled and executed on a Linux computer with a DEC / Compaq Alpha processor.

output

./size of
Signed: size min max
char: 1 -128 127
short: 2 -32768 32767
int: 4 -2147483648 2147483647
long: 8 -9223372036854775808 9223372036854775807
Unsigned: size min max
char: 1 0 255
short: 2 0 65535
int: 4 0 4294967295
long: 8 0 18446744073709551615
single prec. float: 4
double prec. float: 8

Note that integer variables are signed () by default, meaning that no special keyword is required to sign integer variables. You should also notice that the results for both processors are identical for, and, but differ greatly for the larger data types. This is because the Alpha processor is a 64-bit processor and can represent integer values ​​up to 2 ^ 64-1, while processors of the Intel Pentium family are 32-bit processors and only numbers up to 2 ^ 32 -1 can represent. Programmers whose code should be portable between Alpha and Pentium processors should keep this difference in mind.

Although the size of data types can differ depending on the computer platform, C gives some guarantees thanks to the ANSI standard. There are five things you can count on:

  • The size of one is one byte.
  • The size of one is less than or equal to the size of one.
  • The size of one is less than or equal to the size of one.
  • The size of one is equal to the size of one.
  • The size of one is less than or equal to the size of one.

The values ​​in floating point variables correspond to the scientific notation that you should be familiar with from school. Floating point numbers consist of three parts: a sign (+ or - to represent positive and negative numbers), a mantissa (a value between 0 and 1) and an exponent. Using this notation as a basis, a number like 23.85 would be represented as + 0.2385E2: a positive number equal to 0.2385 times 10 to the power of 2 (that is, times 100). The exponent can be positive as well as negative, so that very large as well as very small numbers can be represented with it.

However, this representation of floating point numbers is not absolutely accurate for all numbers. Many numbers, such as 1/3, can only be approximately described with floating point numbers. 1/3 is correctly represented as 0.333333 ..... with an infinite sequence of three. However, floating point numbers can only store a limited number of these repeating threes. In the case of a representation of 1/3 with single precision, seven of these three are stored, and in the case of a representation with double precision, 19 of these three are stored.

The representations of the floating point numbers in single and double precision also differ in the range of values ​​that they can store. Double precision variables can be much larger and much smaller than single precision variables. This is because the double-precision exponent has a larger range of numbers than the single-precision exponent. Table 2.2 compares the range of values ​​and the precision of the floating point numbers with double and single precision.

Range of values

accuracy

simple accuracy

1. 2E-38 to 3.4E38

7 digits

double precision

2.2E-308 to 1.8E308

19 digits

Table 2.2: Range of values ​​and precision of floating point numbers

Variable declarations

Before you can use a variable in a C program, you have to declare it. A variable declaration tells the compiler the name and type of the variable. The declaration can also initialize the variable with a specific value. If a program tries to use a previously undeclared variable, the compiler returns an error message. A variable declaration has the following form:

type identifier variable-name;

The type identifier indicates the variable type and must correspond to one of the keywords used in Listing 2.3. The variable name specifies the name of the variable and must comply with the rules given above. Several variables of the same type can be declared in one and the same line, whereby the individual variable names must be separated by commas:

int counter, number, start; / * Three integer variables * /
float percent, total; / * Two floating point variables * /

As Day 11, "Scopes of Variables," will show, the location of the variable declaration in the source code is important because it affects the way a program can use the variables. For now, however, you can put all the variable declarations together just before the function.

The typedef keyword

The keyword can be used to create a new name for an existing data type. Basically creates a synonym. For example, defines the statement

typedef int integer;

the identifier as a synonym for. From now on you can define variables of the type with the synonym as in the following example:

integer counter;

Note that it does not create a new data type, it only allows a different name to be used for a predefined data type. The keyword is mainly used in connection with compound data types, as explained on day 10 on the topic of structures. A compound data type is a combination of the data types presented in today's lesson.

Initialize variables

When you declare a variable, you tell the compiler to reserve a certain amount of memory for the variable. However, you do not specify which value - i.e. the value of the variable - is to be saved in this area. This can be the value 0, but also any random value. Before using a variable, you should always assign it a known initial value. You can achieve this independently of the variable declaration with an assignment as in the following example:

int counter; / * Reserve memory area for the variable counter * /
counter = 0; / * Save the value 0 in the variable counter * /

The equal sign in this statement is the C language assignment operator. I'll cover these and other operators on Day 3, "Statements, Expressions, and Operators." It should only be mentioned here that the equal sign in programming does not have the same meaning as in mathematics. For example if you

x = 12

viewed as an algebraic expression, this means: "x is equal to 12". In C, however, the equal sign expresses the following fact: "Assign the value 12 to the variable x."

Variables can also be initialized in the course of the declaration. To do this, write an equal sign and the desired initial value after the variable name in the declaration statement:

int counter = 0;
double percent = 0.01, tax rate = 28.5;

Be careful not to initialize a variable with a value out of range. For example, the following initializations are incorrect:

int weight = 10000000000000;
unsigned int value = -2500;

Fortunately, the GNU C compiler issues a warning when trying to compile such code. However, it is only a warning. You can still compile and link the program, but you will get unexpected results when the program is running.

What you should be doing

What not

Determine how many bytes each variable type occupies on your computer.

Use to make your programs more understandable.

If possible, initialize variables when they are declared.

Do not use a variable that has not yet been initialized. The results are unpredictable.

Do not use variables of the types or when you are only storing integers. It works, but it's not efficient.

Do not try to store numbers in variables that are of insufficient type for the size of the number.

Don't write negative numbers in variables that have a type.

Constants

Like a variable, a constant is an area of ​​memory for data that a program can work with. In contrast to a variable, the value stored in a constant cannot be changed during program execution. C knows two types of constants for different areas of application:

  • Literal constants
  • Symbolic constants

Literal constants

A literal constant is a value that is specified directly in the source code. This means that the value is written out "literally" in all places where it occurs:

int count = 20;
float tax_rate = 0.28;

The numbers and are literal constants. The above instructions store these values ​​in the variables and. One of the two constants contains a decimal point, the other does not. An existing or non-existent decimal point distinguishes floating point constants from integer constants.

In C, floating point numbers are to be written with a point, i.e. not with a comma, as is common in German-speaking countries.

If a literal constant contains a decimal point, it is considered a floating point constant, which the C compiler interprets as a number of the type. Floating point constants can be written in the usual decimal notation as in the following examples:

123.456
0.019
100.

Note that there is a decimal point in the third constant after the number, even if it is an integer (i.e. a number without a fraction). The decimal point causes the C compiler to treat the constant like a double-precision floating point number. Without the decimal point, the compiler assumes an integer constant.

You can also specify floating point constants in scientific notation. You may remember from school days that scientific notation represents a number as the decimal part times 10 to the power of a positive or negative number. This notation is particularly useful for very large and very small numbers. In C one writes numbers in scientific notation as a decimal number with a subsequent or and the exponent:

Number in scientific notation

To be read as

1.23E2

1.23 times 10 to the power of 2 or 123

4.08e6

4.08 times 10 to the power of 6 or 4080000

0.85e-4

0.85 times 10 to the power of minus 4 or 0.000085

The compiler interprets a constant without a decimal point as an integer number. Integer numbers can be written in three different notations:

  • A constant that begins with a digit (except 0) is considered a decimal number (i.e. a number in the usual decimal system, the number system based on base 10). Decimal constants can contain the digits 0 to 9 and a leading minus or plus sign. (Numbers without a preceding minus or plus sign are positive as usual.)
  • The compiler interprets a constant that begins with the digit 0 as an octal integer (i.e. a number in the base 8 number system). Octal constants can contain the digits 0 to 7 and a leading minus or plus sign.
  • A constant that begins with 0x or 0X is a hexadecimal constant (i.e. a number in the base 16 number system). Hexadecimal constants can contain the digits 0 through 9, the letters A through F, and a leading minus or plus sign.

Symbolic constants

A symbolic constant is a constant that is represented by a name (symbol) in the program. Like literal constants, the value of symbolic constants cannot change. If you want to access the value of a symbolic constant in a program, use the name of this constant as you would with a variable. You only have to enter the actual value of the symbolic constant once when you define the constant.

Symbolic constants have two major advantages over literal constants, as the following examples illustrate. Let's say you do a lot of geometric calculations in a program. For this, the program often needs the value for the circle number (~ 3.14). For example, to calculate the circumference and the area of ​​a circle for a given radius, one writes:

circumference = 3.14 * (2 * radius);
area = 3.14 * (radius) * (radius);

The asterisk () represents the multiplication operator of C. (Operators are the subject of Day 3.) The first statement means: »Multiply the value stored in the variable by and then multiply this result by. Then assign the result to the variable. "

However, if you define a symbolic constant with the name and value, you can formulate the above statements as follows:

circumference = PI * (2 * radius);
area = PI * (radius) * (radius);

This makes the code easier to understand. Instead of pondering whether the circle number is actually meant, one recognizes this fact directly from the name of the symbolic constants.

The second advantage of symbolic constants is when you have to change a constant. Suppose you want to calculate with greater precision in the above examples. To do this, enter the value with more decimal places: instead of. If you have written literal constants in the source code, you must search through the entire code and change each occurrence of the value to. With a symbolic constant, this change is only necessary once, namely in the definition of the constant.

Define symbolic constants

There are two ways to define symbolic constants in C: with the directive and with the keyword. The directive is used as follows:

#define CONSTANT NAME value

This creates a constant with the name and a value that is specified in as a literal constant. The identifier follows the same rules as mentioned above for variable names. By convention, names of constants are always written in capital letters. This makes it easy to distinguish them from variables whose names are written in lowercase letters or mixed spelling by convention. For the example above, the directive for a constant looks like this:

#define PI 3.14159

Note that lines with directives do not end with a semicolon. You can specify directives anywhere in the source code, but they only affect the parts of the source code that are under the directive. As a rule, all directives are grouped in a central location at the beginning of the file and before the start of the function.

How #define works

A directive tells the compiler the following: "Replace the character string in the source code with." The effect is exactly the same as if you search through the source code with the editor and make every replacement manually. Note that no string is substituted if it is part of a longer name, part of a comment, or enclosed in quotation marks. For example, the occurrence of in the second and third lines is not replaced:

#define PI 3.14159
/ * You have defined a constant for PI. * /
#define PIPETTE 100

The directive is one of the C preprocessor instructions that are covered in detail on Day 20, "Advanced Compilers."

Define constants with the const keyword

A symbolic constant can also be defined with the keyword. The keyword is a modifier that can be applied to any variable declaration. A variable declared as a variable cannot be modified during program execution; it can only be initialized at the time of declaration. Here are a few examples:

const int count = 100;
const float pi = 3.14159;
const long debt = 12000000, float tax_rate = 0.21;

The keyword refers to all variables of the declaration line. In the last line, and are symbolic constants. If a program tries to change a declared variable, the compiler generates an error message, as is the case, for example, with the following code:

const int count = 100;
counter = 200; / * Will not be compiled! The value of constants can be * /
/ * cannot be reassigned or changed. * /

What are the practical differences between symbolic constants created with the directive and those created with the keyword? It all has to do with pointers and the scope of variables. These are two very important aspects of C programming that we'll cover in more detail on Days 8, "Pointers," and 11, "Scopes of Variables."

Now, look at a program that demonstrates how to declare variables and use literal and symbolic constants. The program shown in Listing 2.4 asks the user for their weight and year of birth. Then it converts the weight into grams and calculates the age for the year 2010. You can enter, compile and run the program according to the steps presented in Chapter 1.

Listing 2.4. A program that shows how to use variables and constants.

1: / * Demonstrates the use of variables and constants * /
2: #include
3:
4: / * Define constant for converting pounds to grams * /
5: #define GRAMM_PRO_PFUND 500
6:
7: / * Define constant for the beginning of the next decade * /
8: const int ZIEL_JAHR = 2010;
9:
10: / * Declare required variables * /
11: int weight_in_gram, weight_in_pound;
12 int year_of_birth, age_in_2010;
13:
14: int main ()
15: {
16: / * Read data from user * /
17:
18: printf ("Please enter your weight in pounds:");
19: scanf ("% d", & weight_in_pounds);
20: printf ("Please enter your year of birth:");
21: scanf ("% d", & year_of_birth);
22:
23: / * Perform conversions * /
24:
25: weight_in_gram = weight_in_pounds * GRAMM_PRO_PFUND;
26: age_in_2010 = TARGET_YEAR - year_of_birth;
27:
28: / * output results on screen * /
29:
30: printf ("\ nYour weight in grams =% d", weight_in_grams);
31: printf ("\ nIn 2010 you are% d years old. \ N", age_in_2010);
32:
33: return 0;
34: }

Please enter your weight in pounds: 175
Please enter your year of birth: 1960

Your weight in grams = 87,500
In 2010 you will be 50 years old.

The program declares two types of symbolic constants on lines 5 and 8. The constant declared in line 5 is used to formulate the conversion from pounds to grams (i.e. the value 500) in a more understandable manner, as is done in line 25. Lines 11 and 12 declare variables that are used in other parts of the program. The meaning of a calculation can be more easily understood from the descriptive names such as. Lines 18 and 20 display the texts for the prompts on the screen. The function is covered in detail later in this book. So that the user can react to the prompts, lines 19 and 21 use another library function, with which inputs can be received via the keyboard. The book will also go into this function in more detail later. Lines 25 and 26 calculate the user's weight in grams and age for 2010. These and other instructions will be discussed in tomorrow's lesson. At the end of the program, lines 30 and 31 display the results for the user.

What you should be doing

What not

Use constants to make your programs easier to understand.

Do not try to assign a value to a constant after it has already been initialized.

Summary

This lesson introduced you to the main components of a typical C program. We have dealt extensively with the numeric variables that are used in C programs to store data during program execution. You have learned that the only required part of any C program is function. The real work is done by the program instructions that instruct the computer to take the desired actions. You also got to know variables and variable definitions and learned how to use comments in the source code.

In addition to the function, a C program can contain two types of functions: library functions that are supplied with the compiler and user-defined functions that the programmer creates.

You learned that there are two categories of numeric variables - integers and floating point. There are various specific variable types within these categories. Which type of variable -,, or - is used for a particular application depends on the nature of the data to be stored in the variable. It was also shown that in a C program you have to declare a variable first before you can use it. A variable definition informs the compiler of the name and type of the variable.

Another topic in this lesson was constants. You got to know the two constant types of C - literal and symbolic constants. In contrast to the variables, the value of a constant cannot be changed during program execution. You enter literal constants directly into the source code whenever the corresponding value is required. Symbolic constants are assigned a name, and by this name you refer to the value of the constant in the source code. Symbolic constants are created with the directive or the keyword.

questions and answers

Question:
What effect do comments have on a program?

Answer:
Comments are intended for the programmer. When the compiler converts the source code into object code, it ignores comments as well as spaces, tabs, etc., which only serve to structure the source text (so-called whitespace). This means that comments have no influence on the executable program. A program with a lot of comments runs just as fast as a program that has no or few comments. Comments increase the size of the source file, but that is usually of minor importance. Bottom line: use comments and whitespace to make the source code as understandable as possible.

Question:
What is the difference between an instruction and a block?

Answer:
A block is a group of instructions enclosed in curly braces (). A block can be used in all places where an instruction can be found.

Question:
How can I find out what library functions are available?

Answer:
Hundreds of libraries are standard in Linux. You can view some of them by browsing the directories / lib and / usr / lib list. Most importantly, the standard C library, the / lib / libc- 2.1.1.so or something like that is called. This library contains a huge selection of predefined functions for keyboard input / screen output, file input / output, string manipulation, math, memory allocation and error handling. All of these predefined functions are fully integrated into the libc-Section of the GNU info pages documented and categorized according to their functionality. You can view the documentation using one of the information reading programs mentioned on Day 1. You can go directly to the with either of the following two commands libc-Jump section:

    With kdehelp there is no direct way that libcDocumentation, but it is relatively easy to find the GNU information pages and the information they contain libc- Find section.

    Question:
    What happens if I assign a fractional number to an integer variable?

    Numbers with a fractional part can certainly be assigned to a variable of the type. If you use a constant variable, the compiler might issue a warning. The assigned value is cut off at the decimal point. For example, if you assign an integer variable name, contains the value. The broken portion is simply lost.

    Question:
    What if I assign a number to a variable whose type is not large enough for the number?

    Answer:
    Many compilers allow such assignments without returning an error. The number is adjusted in the manner of an odometer, i.e. when the maximum value is exceeded, the counting starts again from the beginning. For example, if you assign a signed integer variable (type), the variable contains the value at the end. And if you assign the value to this integer variable, the value is actually in the variable. Subtract the maximum value that the variable can hold from the assigned value. This gives you the value that is actually saved.

    Question:
    What happens if I write a negative number in an unsigned variable?

    Answer:
    As mentioned in the previous answer, the compiler is unlikely to return an error message. It treats the number in the same way as it would when assigning a number that is too large. For example, if you assign the number to a variable of type two bytes long, the compiler takes the largest possible value that can be stored in the variable (in this case).

    Question:
    What are the practical differences between symbolic constants that you create with the directive and constants that you declare with the keyword?

    Answer:
    The differences have to do with pointers and the scope of variables. These are two very important aspects of C programming that days 8 and 11 will address. For now, you should keep in mind that a program is easier to understand if you also create constants.

    Workshop

    The workshop contains quiz questions designed to help you consolidate your knowledge, as well as exercises designed to encourage you to apply what you have learned and gain your own experience. The solutions to the questions and the exercises can be found in Appendix C.

    quiz

    1. What do you call a group of one or more C statements within curly brackets?
    2. Which components must be present in every C program?
    3. How do you insert program comments and what are they used for?
    4. What is a function?
    5. C knows two kinds of functions. What do you call them and how do they differ?
    6. What is the purpose of the directive?
    7. Can comments be nested?
    8. Can comments be longer than one line?
    9. What else do you call an include file?
    10. What is an include file?

    Exercises

    1. Write the smallest program possible.
    2. Take a look at the following program: 1: / * Ueb2-2.c * /
      2: #include
      3:
      4: void show_line (void);
      5:
      6: int main ()
      7: {
      8: display_line ();
      9: printf ("\ n C in 21 days \ n");
      10: display_line ();
      11: printf ("\ n \ n");
      12: return 0;
      13: }
      14:
      15: / * output line with asterisk * /
      16: void show_line (void)
      17: {
      18: int counter;
      19:
      20: for (counter = 0; counter <21; counter ++)
      21: printf ("*");
      22: }
      23: / * end of program * /
    3. a. Which lines contain instructions?
    4. b. Which lines contain variable definitions?
    5. c. Which lines contain function prototypes?
    6. d. Which lines contain function definitions?
    7. e. Which lines contain comments?
    8. Write a sample comment.
    9. What does the following program do? (Enter it and run it.) 1: / * Ueb2-4.c * /
      2: #include
      3:
      4: int main ()
      5: {
      6: int ctr;
      7:
      8: for (ctr = 65; ctr <91; ctr ++)
      9: printf ("% c", ctr);
      10:
      11: return 0;
      12: }
      13: / * end of program * /
    10. What does the following program do? (Enter it and run it.) 1: / * Ueb2-5.c * /
      2: #include
      3: #include
      4: int main ()
      5: {
      6: char buffer [256];
      7:
      8: printf ("Please enter your name and press : \ n");
      9: fgets (buffer, 256, stdin);
      10:
      11: printf ("\ nYour name contains% d characters (including spaces).",
      12 strlen (buffer));
      13:
      14: return 0;
      15: }