Variables and Functions

This page was translated by a robot.

Variables and functions denote values ​​that are stored or to be calculated, which can be addressed using a symbol . The symbol denotes the name of the variable or function.

Every variable and every function is assigned a type, which is called a declaration . The content is actually determined by means of a so-called definition .

The value of a variable resides at a specified address in memory or in a processor register. By specifying the symbol, the values ​​it represents can be read or written without the programmer having to know exactly where the value represented by the variable is located.







25.000000
#include <stdio.h>

int main(){
  int   a = 5;
  float b;
  b = a * a;
  printf("%f\n", b);
  return 0;
}

A function is to be understood as a functional unit that can be called when required by specifying the symbol and the required arguments. The result of the function is calculated fresh when it is called and returned as a so-called return value .









Area: 78.539749
#include <stdio.h>

float area(float r){
  return r * r * 3.14159;
} 

int main(){
  float radius = 5;
  printf("Area: %f", area(radius));
  return 0;
}

Details

Variables store values ​​which, in contrast to values ​​firmly anchored in the program text , can change during the runtime of a program. So the value of a variable can vary, it is variable. In C and C++, variables are therefore not stored together with the machine code, but in a separate data structure.

From a semantic point of view, functions in C and C++ are nothing more than extended variables. However, the value that a function represents is not read directly from memory as with a variable, but is recalculated by branching off the program code into an environment that is independent of the rest of the program and returned as a return value to the calling point. In addition, arguments can be passed to a function, which are then available as parameters within the environment.

Even operators (such as addition, multiplication...) can be understood as functions and can even be programmed in C++ (see operator overloading ).

Declaration and Definition

A declaration assigns a type to a symbol in a specific program area. This tells the compiler exactly what a symbol represents, whether it's a variable or a function, and how the symbol is to be interpreted without specifying the exact content. A declaration is also referred to as a prototype in certain situations.

A definition causes a symbol to be provided. A function is programmed from a definition and a variable is assigned to a reserved memory location, also known as instantiation . When defining a variable, the symbol is often additionally initialized, which determines the value to be saved.

There is always confusion about the two terms declaration and definition. A declaration is used to announce to the compiler a symbol that will be defined later. Due to a declaration, the compiler is aware of the symbol and, in particular, is informed about the type of the symbol. A definition, on the other hand, means the concrete formulation and provision of a symbol. By allocation it is meant that the compiler allocates memory according to the symbol's type and assigns the memory location (an address in memory or a processor register) to the symbol, so that the symbol ultimately represents a reference to that memory location. A symbol can therefore only be defined in one place. On the other hand, any number of declarations can be written for each symbol, as long as they do not declare the symbol with a contradictory type.

A definition always results in a declaration. The reverse is not true in general: a declaration does NOT automatically result in a definition. However, there are many cases in which the corresponding symbol is automatically defined by the compiler when it is declared. If, for example, a variable is introduced within executable code by means of a declaration, the variable is also defined at the same time. However, if, for example, the variable declaration is written as part of a parent declaration (e.g. a class declaration), or the variable is declared with the externkeyword , no definition takes place..






Variable declaration
Function declaration


Function definition
Variable definition
#include <cstdio>
#include <cmath>

class Vector2{
public:
  float a[2];
  void normalize();
};

void Vector2::normalize(){
  float length = sqrtf(a[0]*a[0] + a[1]*a[1]);
  a[0] /= length; a[1] /= length;
}

Declarations and Prototypes

Declarations are very versatile. The many possibilities are described in detail in the syntax descriptions of variables and functions.

Each symbol must have been declared somewhere in the program text before it can be used in the code. Since it is very possible in more complex programs that functions and variables cannot be arranged strictly sequentially one after the other (e.g. when functions are called interactively or by including other files), so-called prototypes are used.

A prototype is basically nothing more than a declaration that is given before the use of a symbol. Starting with a declaration, the compiler has information about what type the symbol will later be.



Prototype


1234




Definition
#include <stdio.h>

void printInt(int x);

int main(){
  printInt(1234);
  return 0;
}

void printInt(int x){
  printf("%d\n", x);
}

A prototype doesn't create executable code or reserve space, it just tells the compiler that the corresponding symbol exists and is likely to be defined elsewhere. A prototype is therefore sometimes also referred to as a forward declaration . The German term advance declaration is used on this page.

The term prototype is basically interchangeable with declaration . However, it has become common practice to designate a declaration as a prototype if it can be viewed as a framework, i.e. only provides the most necessary information. For example, a function declaration with no parameter names is called a prototype rather than a declaration.

It should be noted that the parameter names of function declarations do not contain hints for the compiler and are therefore ignored. It is therefore possible without any problems to use different parameter names for each declaration of a symbol (or even to omit them) than for the final definition.

Writing prototypes is called prototyping . In C, the term prototype is basically only used for functions. However, variables can also be declared somewhere before they are actually defined, although this is rare.

Prototypes provide the compiler with enough hints to process all uses of a symbol. However, when linking, the symbols are associated with the definitions. If the symbol is never defined, a linker error occurs.

Types can also be pre-declared. Symbol types can be assigned using the typedefkeyword . However, sometimes the actual definition of a type is found later in the code or is even invisible to the programmer. If a type is completely hidden, it is referred to as a so-called opaque type. It can only be used by the programmer as a pointer.

In C++, entire classes can be written as pre-declarations. This is often necessary when a class is to store a pointer to another class. A pre-declaration of a class is written as follows:

class TestClass;

Basically, prototypes can be written anywhere before using the symbol. However, the programmer must ensure that it is actually a declaration and not a definition. It must also be ensured that the declaration of the symbol is visible from the area of ​​use and that the definition of the symbol is visible from the area of ​​declaration. For this reason, prototypes and advance declarations are usually written in global space and also at the beginning of a file before any implementation.

Declarations are always terminated with a semicolon ;. Forgetting the semicolon in a declaration can sometimes lead to nasty compiler confusion, especially if, for example, the semicolon at the end of a class declaration is forgotten. So if hundreds of errors suddenly occur during compilation, and if a large number of these errors also affect code that was never edited (such as the libraries used), this is a sure sign that a semicolon was missed somewhere..

Definitions

After a definition, the compiler assigns the corresponding memory address or the corresponding register to each symbol, which means that the value or the function can be found unambiguously, i.e. localized. Once defined, a symbol reflects the corresponding variable or function itself. It is not a pointer but a reference to the specified content. Each later occurrence of the variable or function name within a statement is converted by the compiler to the corresponding value or function call.

Variable definitions are most often written inside functions. By using statement blocks , a function can be divided into several nested areas where variables can be defined independently. With older C standards (before C99), all required definitions must be written at the beginning of the statement block contained, but this restriction no longer applies to many newer compilers and in C++ in general.

However, a variable definition can also be outside of a function. In C, such variables are thus correctly called external variables . Here on ManderC, however, this term is not used and instead we speak of global variables , which is not exactly the same, but is more clearly distinguished from the notion of so-called external binding , which is of far greater importance to the programmer. More detailed information can be found in the extern storage class.

In addition to the global area, a variable can also be assigned to a namespace in C++. Details can be found under the namespaces .

Function definitions contain the formulation of the code which is to be executed by the function. Details can be found in the function syntax .

Function definitions are outside of executable code within the global area or in C++ also within a namespace. Function definitions within executable code (i.e. functions within functions) are called nested functions and, as far as we know today, are no longer used. Some C language compilers allow nested functions, but this option is turned off by default these days. Nested functions are not allowed in C++.

Occurrences in Files

In principle, both declarations and definitions can occur in any file. Nevertheless, definitions are mainly found in implementation files (.c, .cpp) and declarations or prototypes are mainly found in header files (.h). Header files are usually included at the beginning of an implementation file, so that all declarations in the header file are automatically known to the compiler before implementation.

Declarations not only provide a necessary programming tool, but allow a programmer to provide additional information about how to use the declared symbol. The declarations in header files are often provided with many explanatory comments, easy-to-read arrangement and catchy parameter names, which make the use of each individual parameter obvious.

// Reads the a number of Bytes from the given
// file and stores it in the given buffer.
// Note: Buffer must be big enough!
void readBytesFromFile( void* buffer,
                        int   filedescriptor,
                        int   numbytes);

Declarations thus serve as an interface for the programmer, which is often referred to as an API (Application Programming Interface). By knowing the declarations of variables and functions, a programmer can access the given functionality without knowing (or having to worry about) exactly how it was programmed. Precompiled libraries always provide one or more header files as an interface.

Next Chapter: Statements and Control Structures