What does idx mean in c programming

C programming: functions

An important requirement of structured programming is the avoidance of jumps within the program. As we have seen, this is possible in all cases with control structures.

The second requirement of structured programming is modularization. A program is broken down into several program sections, the modules. In C, such modules are also referred to as functions. Other programming languages ​​refer to modules as subroutines or differentiate between functions (modules with return value) and procedures (modules without return value). Despite these different names, the same thing is meant.

Object-oriented programming languages ​​go one step further and use classes for modularization. Put simply, classes consist of methods (comparable to functions) and attributes (variables). C itself does not support object-oriented programming, in contrast to C ++, which is based on C.

The modularization has a number of advantages:

Better readability

The source code of a program can easily comprise several thousand lines. The Linux kernel even has over 15 million lines and Windows, which was also largely written in C, is estimated to have several million lines. In order to ensure the readability of the program, modularization is essential.

Reusability

The same problems arise several times in almost every program. This often also applies to different applications. Since only the parameters and return type need to be known to use a function, this makes reusability easier. The developer then no longer has to worry about the implementation details.

Maintainability

The modularization makes it easier to find and correct errors. It is also easier to add or change other functionalities.

Function definition [edit]

In the chapter What are variables, we calculated the surface of the cuboid. Now let's write a function that calculates the surface area of ​​a cylinder. To do this, let's first look at the syntax of a function:

Return Type Function Name (Parameter List) {Instructions}

The instructions are saved as Functional body the first line as Functional head.

A program with a function for calculating the cylinder surface looks, for example, as follows:

#include #define PI 3.1415926535898 floatzylinder_oberflaeche (floath, floatr) {floato; o = 2 * PI * r * (r + h); returno;} intmain () {floatr, h; printf ("Program for Calculation of a cylinder surface \ n \ n "); printf (" Height of the cylinder: "); if (scanf ("% f ", & h)! = 1) {printf (" The height should be a number! \ N ") ; return-1;} printf ("Radius of the cylinder:"); if (scanf ("% f", & r)! = 1) {printf ("The radius should be a number! \ n"); return-1 ;} printf ("Surface:% f \ n", cylinder_surface (h, r)); return0;}
  • The function definition begins in line 5. The one at the very beginning of the function, called the function type, tells the compiler that a value with the type will be returned. The transfer parameters and that are transferred to the function are declared in brackets.
  • The function is ended with and a value is returned to the calling function (here:). In our example we are returning the value of, i.e. the result of our calculation. The data type of the expression should match the type of the return value of the function head.
    If no value is to be returned to the calling function, the return value must be specified as the type. For example, a function that only outputs text has the return type because it does not return a value.
  • The function is called in line 26. The two parameters and are transferred here. The returned value is output. However, it is just as conceivable that the value is assigned to a variable, compared with another value or further calculated with the return value.
    The return value does not have to be evaluated. It is not an error if the return value is not taken into account. However, you can assign a so-called attribute to a function, which causes the compiler to issue a warning if the return value is ignored, which is the case with scanf, for example.

The function also has a return value. If the value is 0, this means that the program was terminated properly; if the value is -1, it means that an error has occurred.

Examples of faulty functions [edit]

voidfoo () {/ * code * / return5; / * error * /}

A function declared as must not have a return type. The compiler should issue a warning or even an error message here.

#include intfoo () {/ * Code * / return5; printf ("This line is never executed");}

In this example, the compiler will not issue a warning or an error message. However, the function is never executed because it not only returns a value but also terminates the function.

Other [edit]

In the original language definition by K&R it was not required that every function must have a return type. If the return type was missing, it was assumed by default. However, this is no longer allowed. Every function must explicitly specify a return type.
If a function with a return value that is not void does not return anything using return, the compiler issues a warning and the value returned is not defined when it is executed.

Prototypes

As with variables, one differentiates between functions definition and declaration. With

floatzylinder_oberflaeche (floath, floatr) {floato; o = 2 * PI * r * (r + h); returno;}

the function (see above) is defined.

In the case of a function declaration, only the function header followed by a semicolon is specified. For example, the function is declared as follows:

floatzylinder_oberflaeche (floath, floatr);

This is identical to

externfloatzylinder_oberflaeche (floath, floatr);

Opinions on which variant should be used differ here: some developers are of the opinion that the keyword improves readability, while others do not. We will not use the keyword in this context in the following.

A separation of definition and declaration is necessary if the function is only to be defined after use. A declaration of a function is also called a prototype or Functional head designated. This enables the compiler to check whether the function exists at all and whether the return type and type of the arguments are correct. If the prototype and function definition do not match or if a function is called that has not yet been defined or does not have a prototype, this is an error.

The following program is a further modification of the program for calculating the cylinder surface. The function was used before it was defined:

#include #define PI 3.1415926535898ffloatzylinder_oberflaeche (floath, floatr); intmain () {floatr, h; printf ("Program to calculate a cylinder surface \ n \ n"); printf ("Height of the cylinder:") ; if (scanf ("% f", & h)! = 1) {printf ("The height should be a number! \ n"); return-1;} printf ("Radius of the cylinder:"); if (scanf ("% f", & r)! = 1) {printf ("The radius should be a number! \ n"); return-1;} printf ("Surface:% f \ n", cylinder_surface (h, r) ); return0;} floatzylinder_oberflaeche (floath, floatr) {floato; o = 2 * PI * r * (r + h); returno;}

The prototype is declared on line 5 so that the function on line 21 can be used. At this point, the compiler can also check whether the type and number of parameters passed is correct (it could not do this if we had not declared a function prototype). The function is defined from line 25.

The identifiers of the parameters do not have to match in the prototype and the function definition. They can even be left out entirely. Line 5 can also be replaced by:

floatzylinder_oberflaeche (float, float);

Important: With prototypes, C differentiates between an empty parameter list and a parameter list with. If the parameter list is empty, this means that the function has an undefined number of parameters. The keyword indicates that no values ​​may be passed to the function. Example:

intfoo1 (); intfoo2 (void); intmain () {foo1 (1,2,3); // no error foo2 (1,2,3); // error return0;}

When the function is called in line 7, the compiler outputs an error message; when the function is called in line 6, it does not.

Incidentally, this statement only applies to prototypes: According to the C standard, an empty list for function declarations that are part of a definition means that the function has no parameters. In contrast, an empty list in a function declaration that is not part of a definition (i.e. prototypes) means that there is no information about the number or types of parameters - as we have just seen with the example of the function.

If the program is compiled with a C ++ compiler, an error message is also output in the case of, since an empty parameter list there also means that no parameters can be passed to the function.

Library functions like or have a prototype that is usually in the header file or other header files. This allows the compiler to check whether the statements have the correct syntax. For example, the prototype of the statement has the following form (or similar) in the:

externintprintf (constchar * __ restrict__format, ...);

If the compiler now finds the following line in the program, for example, it outputs an error:

The compiler compares the type of the parameter with that of the prototype in the header file and finds no match there. Now it "knows" that an incorrect parameter was passed to the instruction and issues an error message.

The concept of prototypes was first introduced in C ++ and did not exist in the original Kernighan and Ritchie language definition. That is why, for example, the "Hello World" program in the first edition of "The C Programming Language" managed without instructions. Only with the introduction of the ANSI standard were prototypes introduced in C as well.

Inline functions [edit]

Inline functions are new to the C99 standard. They are defined by prepending the keyword. Example:

inlinefloatzylinder_oberflaeche (floath, floatr) {floato; o = 2 * 3.141 * r * (r + h); return (o);}

A function that is defined as should be called as quickly as possible according to the C standard. The exact implementation is left to the implementation. For example, the function call can be accelerated by the fact that the function is no longer available as an independent code, but is inserted at the point of the function call. This means that there is no need to jump to the function and back again. However, the compiler does not have to pay attention to the keyword if the compiler does not determine any need for optimization. Many compilers therefore completely ignore this keyword and rely on heuristics as to when a function should be inline.

Global and local variables [edit]

All previous example programs used local variables. They were declared at the beginning of a function and were only valid within this function. As soon as the function is exited, it loses its validity. A global variable, on the other hand, is declared outside of a function (usually at the beginning of the program) and remains valid and correspondingly a value until the program is terminated.

#include intGLOBAL_A = 43; intGLOBAL_B = 12; voidfunction1 (); voidfunction2 (); intmain (void) {printf ("Examples of local and global variables: \ n \ n"); function1 (); function2 (); return0;} void function1 () {intlokal_a = 18; intlokal_b = 65; printf ("\ nGlobal variable A:% i", GLOBAL_A); printf ("\ nGlobal variable B:% i", GLOBAL_B); printf ( "\ nLocal variable a:% i", local_a); printf ("\ nLocal variable b:% i", local_b);} voidfunction2 () {intlocal_a = 45; intlocal_b = 32; printf ("\ n \ nGlobal variable A :% i ", GLOBAL_A); printf (" \ nGlobal variable B:% i ", GLOBAL_B); printf (" \ nLocal variable a:% i ", local_a); printf (" \ nLocal variable b:% i \ n ", local_b);}

The variables and were declared at the beginning of the program and outside the function and are therefore valid throughout the program. They can be used within any function. Local variables like and against are only valid within the function in which they were declared. They lose their validity outside of this function.

Global variables differ from local variables in one more point: They are automatically initialized with the value 0 if no value is assigned to them. Local variables, on the other hand, always receive the (random) value that is currently in the memory location reserved by the compiler (memory garbage). The following program makes this clear:

#include intZAHL_GLOBAL; intmain (void) {int number_local; printf ("Local variable:% i", number_local); printf ("\ nGlobal variable:% i \ n", NUMBER_GLOBAL); return0;}

The result:

Local variable: 296 Global variable: 0

Concealment [edit]

If two variables with the same name are defined as global and local variables, the local variable is always preferred. The next example shows such a "double declaration":

#include int number = 5; voidfunc (); intmain (void) {int number = 3; printf ("Is the number% i declared as a local or global variable?", number); func (); return0 ;} voidfunc () {printf ("\ nGlobal variable:% i \ n", number);}

In addition to the global variable, another variable with the name is declared in the main function. The global variable is replaced by the local covered. Since there are now two variables with the same name, the instruction outputs the local variable with the value 3. The function is only intended to make it clear that the global variable has not been deleted or overwritten by the local variable declaration.

Variables should never be covered by others, as this hinders intuitive understanding and access to the global variable within the scope of the local variable is not possible. Good compilers can be set to issue a warning when variables are obscured.

Another (valid) example of concealment is

#include intmain (void) {inti; for (i = 0; i <10; i ++) {inti; for (i = 0; i <10; i ++) {inti; for (i = 0; i <10; i ++) {printf ("i =% d \ n", i);}}} return0;}

Here 3 different variables are created with the name, but only the innermost one is relevant for this. This example is difficult to understand intuitively and should only be a negative example.

exit () [edit]

With the library function, a program can be ended at any point. A value must be passed in brackets, which is returned to the environment - i.e. usually the operating system. The value 0 is used to signal that the program was terminated correctly. If the value is not equal to 0, the meaning of the return value depends on the implementation. Example:

Exits the program and returns the value 2 to the operating system. Alternatively, the macros and can also be used to return a successful or incorrect termination of the program.

Note: Under DOS, this return value can be evaluated in a batch file using IF ERRORLEVEL, for example; under Unix / Linux the special variable $? the return value of the last called program. Other operating systems have similar capabilities; This allows you to create your own mini-programs that can circumvent certain limitations (e.g. from batch or other script languages). You should therefore always use error codes to make the result available to other programs.