Variables, Arrays, Strings

Variables store numbers. For defining variables and giving them initial values, use a declaration like this:

var Number;	// uninitialized variable of type 'var'
int Number = 123; // initialized variable of type 'int'

This declaration creates a variable of the given type with the given name. The name can contain up to 30 characters, and must begin with A..Z, a..z, or an underscore _. Variables must never have names that are already used for functions and for other previously-defined variables.

Also constant expressions can be assigned to variables. Example:

int Size = 100/2; // assign the value 50

Variable types

Computers calculate with finite accuracy. Therefore all normal variable types are limited in precision and range. Lite-C supports the following variable types:

Type Size (bytes) Range Step Digits Used for
double, var 8 -1.8·10308 to 1.8·10308 2.2·10-308 ~14 high precision numbers
float 4 -3.4·1038 to 3.4·1038 1.2·10-38 ~7 script constants, compact numbers
fixed 4 -1048577.999 to 1048576.999 0.001 ~9 special purposes (HFT)
int, long 4 -2147483648 to 2147483647 1 ~10 script constants, counting, flags
short 2 0 to 65536 1 ~5 compact integers
char, byte 1 0 to 256 1 ~2 text characters
bool, BOOL 4 true, false or 1,0 - - yes/no decisions
size_t, intptr_t 4 or 8 0 to 4294967295 / 18446744073709551615 - - sizes, addresses, long integers
char*, string characters+1 "..." - - text
var*, vars elements*8 -1.8·10308 to 1.8·10308 2.2·10-308 ~14 arrays, simple time series
DATE 8 12-30-1899 00:00 to doomsday ~0.1 ms - time, date
mat rows*cols*8 -1.8·10308 to 1.8·10308 2.2·10-308 ~14 vectors, matrices
dataset records*(fields+1)*4 -3.4·1038 to 3.4·1038 1.2�10-38 ~7 candles, complex time series

 !!  The limited accuracy of variable types affects numerical expressions. If an expression contains only integers (numbers without decimals), the result is also an integer. For instance, the expression (99/2) is 49, but (99.0/2.0) is 49.5. The expression 1.0/4 is 0.25, but 1/4 is 0. Integer numbers in the script - such as character constants ('A'), numeric constants (12345) or hexadecimal constants (0xabcd) are treated as int with 10 significant digits; numbers or constant expressions containing a decimal point (123.456) are treated as float with 7 significant digits. Due to the 7 digit limit, var X = 123456789.0; would in fact set X to 123456792.0; but var X = 123456789; sets it to 123456789.0 since int has 10 significant digits.

var Half = 1/2;  // wrong!
    var Half = 1./2; // ok! 
Since constants or constant expressions are float, avoid arithmetic with constants when higher precision is needed. Use var or double variables instead:
var Days = Seconds/(24.*60.*60.);  // low precision
    var SecondsPerday = 24*60*60; 
    var Days = Seconds/SecondsPerday; // high precision 

Typecast operators

Variables are normally automatically converted to another type. So you can assign var to int variables or vice versa without having to care about type conversion. However, sometimes you'll need to convert expressions or variables when the conversion is not obvious - for instance when calling an overloaded function that accepts several variable types. In this case you can enforce a type conversion with a typecast operator. A typecast (or cast) operator is the target variable type in parentheses - f.i. (int) or (var) - placed before the expression or variable to be converted. Example:
var dx = 123.456;
float fy = 0.12345; printf("The integer value of dx is %i, fy is %f",(int)dx,(var)fy); // %i expects the "int" variable type, %f expects "var"
Be aware of the above mentioned limited accuracy when using floating point arithmetic and then typecasting the result to an integer. Operations with the theoretical result 1 can in practice return 1.000001 or 0.999999, and cause unexpected results. If in doubt: round.  

Global, local, and static variables

Variables can be defined outside functions or inside functions. When defined outside, they are called global variables and are accessible by all functions. They keep their values until the script is compiled the next time. Variable definitions inside functions produce local variables. Local variables only exist within the scope of the function. They are unknown outside the function, and lose their values when the function returns. If a global variable with the same name as a local variable exists, the local variable has priority inside its function. If you declare a variable multiple times, the most recent declared copy is used. But for your own sake you should better avoid using the same name for different variables. 

A local variable can be declared as static. It is then treated as a global variable even if it is declared within a function, and keeps its content when the function terminates or when another instance of the function is called. This means that it is initialized only the first time the function is called. Example:

function foo() 
    {
      static bool Initialized = false;
      if(!Initialized) { initialize(); } // initialize only once
      Initialized = true;
      ...
    }
 !!  Static and global variables keep their values until the script is compiled again. So make sure to initialize them at script start - if(Init) - to their initial values if required.

The value of another variable, or the return value of a function can be assigned to a local variable at declaration, but not to a global or static variable. Use only constants for a declaration of a global or static variable.

int GlobalCounter = count(); // wrong!
    
    function foo() 
    {
      int FooCounter = count(); // ok!
      static int FooCounter2 = FooCounter; // wrong!
      ...
    }

Arrays

If you group several variables of the same type together, you have an array:
var name[N]; // uninitialized array
var name[N] = { 1, 2, ... N }// initialized global array
This creates a variable that contains N numbers, and optionally gives them default values as in the second line. Note the winged brackets { } that must surround the set of default values. Such a multi-number variable is called an array. The number N is called the length of the array. It must be really a number; arithmetic expressions or formulas cannot be used for defining a fixed-length array,  Example:
int my_array[5] = { 0, 10, 20, 30, 40 }; 

This creates an array of 5 numbers that can be accessed in expressions through my_array[0]...my_array[4]. In such an expression, the number in the [ ] brackets - the index - tells which one of the 5 numbers of the array is meant. Note that there is no my_array[5], as the index starts with 0. The advantage of using an array, compared to defining single variables, is that the index can be any numeric expression. Example:

int i;
    for (i=0; i<5; i++) 
      my_array[i] = i; // sets the array to 0,1,2,3,... etc.
    

Care must be taken that the index never exceeds its maximum value, 4 in this example. Otherwise the script will crash.

 !!  Initializing in the definition works only for simple arrays; multidimensional arrays, arrays that contain strings, structs, or anything else than numbers, or several arrays defined together in a single logical line must be initialized by explicitly setting their elements. Initializing local arrays makes them static (see below), meaning that they keep their previous values when the function is called the next time. For initializing them every time the function is called, explicitly set them to their initial values, like this:

function foo()
    {
      var my_vector[3];
      my_vector[0] = 10;
      my_vector[1] = 20;
      my_vector[2] = 30;
      ...
      var my_static[3] = { 10, 20, 30 }; // initializing local arrays makes them static 
      ...
    }

 !!  All local variables are stored on a special memory area called the stack. The stack has a limited size that is sufficient for many variables, but not for huge arrays. Exceeding the stack size causes a Error 111 message at runtime, so when you need large arrays of more than 100 variables, better declare them global, i.e. outside the function. When you want to determine the array size dynamically, use the malloc / free method. When you need a data structure whose size can grow or change at runtime, use no array, but a dataset.

In C, arrays are in fact pointers to the start of a memory area containing the array elements. So, my_vector[3] is the same as *(my_vector+3).

Arrays can contain not only variables, but also complex data types such as structs. For sorting or searching arrays, the standard C functions qsort and bsearch can be used. They are documented in any C book and available in the stdio.h include file.

Multidimensional arrays can be defined by using several indices:

var Map[10][20];
... Map[j][i] = 10; // j = 0..9, i = 0..19
Computer memory has only one dimension, so the above defined array is in fact still a pointer to a one-dimensional memory area of the size 200 (10*20). Pointer offsets or the & operator can be used to address array elements or pointers to array elements. In the above example, Map[j][i] is the same as *(Map+j*20+i), and &(Map[j][i]) is the same as (Map+j*20+i).

typedef

You can define your own variable types with typedef statements. Example;
typedef long DWORD;
typedef char byte;

...

DWORD dwFlags;
byte mypixel; 
typedef can be used to redefine variables and structs; it can not be used for arrays.
 

Strings

Strings are arrays of char variables that contain alphanumerical characters - letters, numbers or symbols - which can be used for messages or names. They are defined this way:

string Name = "characters"; 

This defines a string with the given name and initializes it to the content characters between the quotation marks. Special characters within a string must be preceded by a '\': \n = Line feed; \\ = Backslash; \" = Quotation mark. The string type is simply a char pointer (char*) that points to the first character. The last character is followed by a 0 byte to indicate the end of the string.

Any static char array can serve as a string with a fixed maximum length and variable content:

char Name[40];
...
strcpy(Name,"My String!"); 

After filling this array with characters, it can be used as a string. Care must be taken not to exceed 39 characters, as the last one is the end mark 0. String functions can be used for setting and manipulating string content.

The content of a string can be compared with a string constant using the '==' operator:

string MyAsset = "AAPL";
...
if(MyAsset == "AAPL")
  ...
 !!  Comparing strings with string constants is not the same as comparing two strings (f.i. if(MyAsset1 == MyAsset2) ...). The latter expression is only true when the two string pointers are really identical. For comparing the contents of two non-constant strings, use standard C library functions such as strstr or strcmp.

 !! 
For convenience reasons, some string functions return temporary strings that are allocated on the CPU stack. Temporary strings can not be used for permanently storing content, as they are eventually overwritten by further string functions calls (see string function remarks).

Series

Series are a special array of var variables, normally used for time series of price data, indicators, or data curves. If not given otherwise, the length of a series is determined by the global variable LookBack. Series data is stored in reverse order, so the most recent data is at the begin of the array.

See also:

pointers, structs, functions, series

 

► latest version online

Variablen, Arrays, Strings

Variablen speichern Zahlen. Um Variablen zu definieren und ihnen Anfangswerte zuzuweisen, verwenden Sie eine Deklaration wie diese:

var Number;	// uninitialisierte Variable vom Typ 'var'
int Number = 123; // initialisierte Variable vom Typ 'int'

Diese Deklaration erstellt eine Variable des angegebenen Typs mit dem gegebenen Namen. Der Name kann bis zu 30 Zeichen enthalten und muss mit A..Z, a..z oder einem Unterstrich _ beginnen. Variablennamen dürfen niemals Namen haben, die bereits für Funktionen und für andere zuvor definierte Variablen verwendet werden.

Auch konstante Ausdrücke können Variablen zugewiesen werden. Beispiel:

int Size = 100/2; // weist den Wert 50 zu

Variablentypen

Computer rechnen mit endlicher Genauigkeit. Daher sind alle normalen Variablentypen in der Präzision und Reichweite eingeschränkt. Lite-C unterstützt die folgenden Variablentypen:

Typ Größe (Bytes) Reichweite Schritt Stellen Verwendung
double, var 8 -1.8·10308 bis 1.8·10308 2.2·10-308 ~14 hochpräzise Zahlen
float 4 -3.4·1038 bis 3.4·1038 1.2·10-38 ~7 Skriptkonstanten, kompakte Zahlen
fixed 4 -1048577.999 bis 1048576.999 0.001 ~9 spezielle Zwecke (HFT)
int, long 4 -2147483648 bis 2147483647 1 ~10 Skriptkonstanten, Zählung, Flags
short 2 0 bis 65536 1 ~5 kompakte Ganzzahlen
char, byte 1 0 bis 256 1 ~2 Textzeichen
bool, BOOL 4 true, false oder 1,0 - - Ja/Nein Entscheidungen
size_t, intptr_t 4 oder 8 0 bis 4294967295 / 18446744073709551615 - - Größen, Adressen, lange Ganzzahlen
char*, string Zeichen +1 "..." - - Text
var*, vars Elemente * 8 -1.8·10308 bis 1.8·10308 2.2·10-308 ~14 arrays, einfache Zeitserien
DATE 8 12-30-1899 00:00 bis doomsday ~0.1 ms - Zeit, Datum
mat Zeilen * Spalten * 8 -1.8·10308 bis 1.8·10308 2.2·10-308 ~14 Vektoren, Matrizen
dataset Datensätze * (Felder + 1) * 4 -3.4·1038 bis 3.4·1038 1.2�10-38 ~7 Kerzen, komplexe Zeitserien

 !!  Die begrenzte Genauigkeit der Variablentypen beeinflusst numerische Ausdrücke. Wenn ein Ausdruck nur ganze Zahlen (Zahlen ohne Dezimalstellen) enthält, ist das Ergebnis ebenfalls eine ganze Zahl. Zum Beispiel ist der Ausdruck (99/2) 49, aber (99.0/2.0) ist 49.5. Der Ausdruck 1.0/4 ist 0.25, aber 1/4 ist 0. Ganzzahlige Zahlen im Skript - wie Zeichenkonstanten ('A'), numerische Konstanten (12345) oder hexadezimale Konstanten (0xabcd) werden als int mit 10 signifikanten Stellen behandelt; Zahlen oder konstante Ausdrücke mit einem Dezimalpunkt (123.456) werden als float mit 7 signifikanten Stellen behandelt. Aufgrund des 7-stelligen Limits würde var X = 123456789.0; tatsächlich X auf 123456792.0 setzen; aber var X = 123456789; setzt es auf 123456789.0, da int 10 signifikante Stellen hat.

var Half = 1/2;  // falsch!
    var Half = 1./2; // ok! 
Da Konstanten oder konstante Ausdrücke float sind, vermeiden Sie Arithmetik mit Konstanten, wenn höhere Präzision benötigt wird. Verwenden Sie stattdessen var oder double Variablen:
var Days = Seconds/(24.*60.*60.);  // niedrige Präzision
    var SecondsPerday = 24*60*60; 
    var Days = Seconds/SecondsPerday; // hohe Präzision 

Typecast Operatoren

Variablen werden normalerweise automatisch in einen anderen Typ konvertiert. Sie können also var an int Variablen zuweisen oder umgekehrt, ohne sich um die Typkonvertierung kümmern zu müssen. Manchmal müssen jedoch Ausdrücke oder Variablen konvertiert werden, wenn die Konvertierung nicht offensichtlich ist - zum Beispiel beim Aufruf einer überladenen Funktion, die mehrere Variablentypen akzeptiert. In diesem Fall können Sie eine Typkonvertierung mit einem Typecast Operator erzwingen. Ein Typecast (oder Cast) Operator ist der Zielvariablentyp in Klammern - z.B. (int) oder (var) - vor dem Ausdruck oder der Variablen, die konvertiert werden soll. Beispiel:
var dx = 123.456;
float fy = 0.12345; printf("Der ganzzahlige Wert von dx ist %i, fy ist %f",(int)dx,(var)fy); // %i erwartet den "int" Variablentyp, %f erwartet "var"
Beachten Sie die oben erwähnte begrenzte Genauigkeit, wenn Sie mit Gleitkommaarithmetik arbeiten und dann das Ergebnis zu einer Ganzzahl casten. Operationen mit dem theoretischen Ergebnis 1 können in der Praxis 1.000001 oder 0.999999 zurückgeben und unerwartete Ergebnisse verursachen. Wenn Zweifel bestehen: round.  

Globale, lokale und statische Variablen

Variablen können außerhalb von Funktionen oder innerhalb von Funktionen definiert werden. Wenn sie außerhalb definiert sind, werden sie als globale Variablen bezeichnet und sind für alle Funktionen zugänglich. Sie behalten ihre Werte, bis das Skript das nächste Mal kompiliert wird. Variable Definitionen innerhalb von Funktionen erzeugen lokale Variablen. Lokale Variablen existieren nur innerhalb des Geltungsbereichs der Funktion. Sie sind außerhalb der Funktion unbekannt und verlieren ihre Werte, wenn die Funktion zurückkehrt. Wenn eine globale Variable mit demselben Namen wie eine lokale Variable existiert, hat die lokale Variable innerhalb ihrer Funktion Priorität. Wenn Sie eine Variable mehrfach deklarieren, wird die zuletzt deklarierte Kopie verwendet. Aber zu Ihrem eigenen Vorteil sollten Sie besser vermeiden, denselben Namen für verschiedene Variablen zu verwenden. 

Eine lokale Variable kann als static deklariert werden. Sie wird dann als globale Variable behandelt, auch wenn sie innerhalb einer Funktion deklariert ist, und behält ihren Inhalt bei, wenn die Funktion beendet wird oder wenn eine andere Instanz der Funktion aufgerufen wird. Das bedeutet, dass sie nur beim ersten Aufruf der Funktion initialisiert wird. Beispiel:

function foo() 
    {
      static bool Initialized = false;
      if(!Initialized) { initialize(); } // nur einmal initialisieren
      Initialized = true;
      ...
    }
 !!  Statische und globale Variablen behalten ihre Werte, bis das Skript erneut kompiliert wird. Stellen Sie daher sicher, dass Sie sie beim Skriptstart - if(Init) - auf ihre Anfangswerte initialisieren, falls erforderlich.

Der Wert einer anderen Variable oder der Rückgabewert einer Funktion kann einer lokalen Variable bei der Deklaration zugewiesen werden, aber nicht einer globalen oder statischen Variable. Verwenden Sie nur Konstanten für die Deklaration einer globalen oder statischen Variable.

int GlobalCounter = count(); // falsch!
    
    function foo() 
    {
      int FooCounter = count(); // ok!
      static int FooCounter2 = FooCounter; // falsch!
      ...
    }

Arrays

Wenn Sie mehrere Variablen desselben Typs zusammen gruppieren, haben Sie ein Array:
var name[N]; // uninitialisiertes Array
var name[N] = { 1, 2, ... N }// initialisiertes globales Array
Dies erstellt eine Variable, die N Zahlen enthält, und weist ihnen optional Standardwerte wie in der zweiten Zeile zu. Beachten Sie die geschweiften Klammern { }, die die Menge der Standardwerte umgeben müssen. Eine solche Mehrzahlenvariable wird als Array bezeichnet. Die Zahl N wird als Länge des Arrays bezeichnet. Sie muss tatsächlich eine Zahl sein; arithmetische Ausdrücke oder Formeln können nicht verwendet werden, um ein Array mit fester Länge zu definieren,  Beispiel:
int my_array[5] = { 0, 10, 20, 30, 40 }; 

Dies erstellt ein Array von 5 Zahlen, die in Ausdrücken über my_array[0]...my_array[4] zugänglich sind. In einem solchen Ausdruck gibt die Zahl in den [ ] Klammern - der Index - an, welche der 5 Zahlen des Arrays gemeint ist. Beachten Sie, dass es kein my_array[5] gibt, da der Index mit 0 beginnt. Der Vorteil von der Verwendung eines Arrays im Vergleich zur Definition einzelner Variablen ist, dass der Index ein numerischer Ausdruck sein kann. Beispiel:

int i;
    for (i=0; i<5; i++) 
      my_array[i] = i; // setzt das Array auf 0,1,2,3,... etc.
    

Es muss darauf geachtet werden, dass der Index niemals seinen Maximalwert, 4 in diesem Beispiel, überschreitet. Andernfalls stürzt das Skript ab.

 !!  Initialisierung bei der Definition funktioniert nur für einfache Arrays; mehrdimensionale Arrays, Arrays, die Strings enthalten, Strukturen oder andere als Zahlen enthalten, oder mehrere Arrays, die zusammen in einer einzigen logischen Zeile definiert werden, müssen durch explizites Setzen ihrer Elemente initialisiert werden. Die Initialisierung lokaler Arrays macht sie static (siehe unten), was bedeutet, dass sie ihre vorherigen Werte behalten, wenn die Funktion das nächste Mal aufgerufen wird. Um sie jedes Mal beim Funktionsaufruf zu initialisieren, setzen Sie sie explizit auf ihre Anfangswerte, wie folgt:

function foo()
    {
      var my_vector[3];
      my_vector[0] = 10;
      my_vector[1] = 20;
      my_vector[2] = 30;
      ...
      var my_static[3] = { 10, 20, 30 }; // Initialisierung lokaler Arrays macht sie static 
      ...
    }

 !!  Alle lokalen Variablen werden in einem speziellen Speicherbereich namens Stack gespeichert. Der Stack hat eine begrenzte Größe, die für viele Variablen ausreicht, aber nicht für riesige Arrays. Das Überschreiten der Stack-Größe verursacht eine Error 111 Meldung zur Laufzeit, so wenn Sie große Arrays mit mehr als 100 Variablen benötigen, deklarieren Sie sie besser global, d.h. außerhalb der Funktion. Wenn Sie die Array-Größe dynamisch bestimmen möchten, verwenden Sie die Methode malloc / free. Wenn Sie eine Datenstruktur benötigen, deren Größe zur Laufzeit wachsen oder sich ändern kann, verwenden Sie kein Array, sondern ein Dataset.

In C sind Arrays tatsächlich Pointer auf den Anfang eines Speicherbereichs, der die Array-Elemente enthält. Also ist my_vector[3] dasselbe wie *(my_vector+3).

Arrays können nicht nur Variablen enthalten, sondern auch komplexe Datentypen wie Structs. Zum Sortieren oder Suchen von Arrays können die Standard-C-Funktionen qsort und bsearch verwendet werden. Sie sind in jedem C-Buch dokumentiert und im stdio.h Include-File verfügbar.

Mehrdimensionale Arrays können definiert werden durch die Verwendung mehrerer Indizes:

var Map[10][20];
... Map[j][i] = 10; // j = 0..9, i = 0..19
Computer-Speicher hat nur eine Dimension, daher ist das oben definierte Array tatsächlich immer noch ein Pointer auf einen eindimensionalen Speicherbereich der Größe 200 (10*20). Pointer-Offsets oder der & Operator können verwendet werden, um Array-Elemente anzusprechen oder Pointer auf Array-Elemente zu erhalten. Im obigen Beispiel ist Map[j][i] dasselbe wie *(Map+j*20+i), und &(Map[j][i]) dasselbe wie (Map+j*20+i).

typedef

Sie können Ihre eigenen Variablentypen mit typedef Anweisungen definieren. Beispiel;
typedef long DWORD;
typedef char byte;

...

DWORD dwFlags;
byte mypixel; 
typedef kann verwendet werden, um Variablen und Structs neu zu definieren; es kann nicht für Arrays verwendet werden.
 

Strings

Strings sind Arrays von char Variablen, die alphanumerische Zeichen enthalten - Buchstaben, Zahlen oder Symbole - die für Nachrichten oder Namen verwendet werden können. Sie werden wie folgt definiert:

string Name = "characters"; 

Dies definiert einen String mit dem gegebenen Name und initialisiert ihn mit dem Inhalt characters zwischen den Anführungszeichen. Sonderzeichen innerhalb eines Strings müssen von einem '\' vorangestellt werden: \n = Zeilenumbruch; \\ = Backslash; \" = Anführungszeichen. Der string Typ ist einfach ein char Pointer (char*), der auf das erste Zeichen zeigt. Das letzte Zeichen wird von einem 0-Byte gefolgt, um das Ende des Strings anzuzeigen.

Jedes statische char Array kann als String mit einer festen maximalen Länge und variablem Inhalt dienen:

char Name[40];
...
strcpy(Name,"My String!"); 

Nach dem Befüllen dieses Arrays mit Zeichen kann es als string verwendet werden. Es muss darauf geachtet werden, 39 Zeichen nicht zu überschreiten, da das letzte Zeichen das Endemark 0 ist. String Funktionen können verwendet werden, um den String-Inhalt zu setzen und zu manipulieren.

Der Inhalt eines strings kann mit einer String-Konstante mit dem '==' Operator verglichen werden:

string MyAsset = "AAPL";
...
if(MyAsset == "AAPL")
  ...
 !!  Das Vergleichen von Strings mit String-Konstanten ist nicht dasselbe wie das Vergleichen zweier Strings (z.B. if(MyAsset1 == MyAsset2) ...). Der letzte Ausdruck ist nur dann wahr, wenn die beiden String-Pointer wirklich identisch sind. Um den Inhalt zweier nicht-konstanter Strings zu vergleichen, verwenden Sie Standard-C-Bibliotheksfunktionen wie strstr oder strcmp.

 !! 
Aus Gründen der Bequemlichkeit geben einige String-Funktionen temporäre Strings zurück, die auf dem CPU-Stack alloziert sind. Temporäre Strings können nicht zur permanenten Speicherung von Inhalten verwendet werden, da sie schließlich von weiteren String-Funktionsaufrufen überschrieben werden (siehe String-Funktionsanmerkungen).

Serien

Serien sind spezielle Arrays von var Variablen, die normalerweise für Zeitserien von Preisdaten, Indikatoren oder Datenkurven verwendet werden. Wenn nicht anders angegeben, wird die Länge einer Serie durch die globale Variable LookBack bestimmt. Serien-Daten werden in umgekehrter Reihenfolge gespeichert, sodass die neuesten Daten am Anfang des Arrays stehen.

Siehe auch:

pointers, structs, functions, series

 

► Neueste Version online

Siehe auch:

pointers, structs, functions, series

 

► Neueste Version online