Português
preview
Del básico al intermedio: Variables (II)

Del básico al intermedio: Variables (II)

MetaTrader 5Ejemplos | 18 diciembre 2024, 10:43
69 0
CODE X
CODE X

Introducción

El contenido expuesto aquí tiene como objetivo, pura y simplemente, la enseñanza didáctica. En ningún caso debe considerarse como una aplicación final donde el objetivo no sea el estudio de los conceptos aquí mostrados.

En el artículo anterior Del básico al intermedio: Variables (I)", comenzamos a hablar sobre las variables y algunos aspectos relacionados con ellas. Por ejemplo, el hecho de que podemos transformar variables en constantes. También empezamos a abordar el tiempo de vida y la visibilidad de las variables.

Aquí continuaremos aquel punto, partiendo del supuesto de que tú has comprendido de manera adecuada aquel material inicial. Pues bien, dentro de la cuestión que involucra el tiempo de vida y la visibilidad de las variables, nos encontramos con algo que para muchos principiantes resulta un poco complicado de entender. Esto se debe a que, en muchos casos, NO QUEREMOS que las variables globales nos generen inconvenientes. Queremos que las variables existan únicamente dentro de un bloque de código. Pero —y es en este punto donde las cosas comienzan a complicarse— NO QUEREMOS que el valor de una variable muera o desaparezca cuando el bloque finaliza.

Este tipo de situación que acabo de mencionar es una de las que más genera confusión en la mente de muchos programadores ocasionales o incluso principiantes que buscan profesionalizarse. Esto ocurre porque muchos no comprenden el concepto de que existen mecanismos en ciertos lenguajes de programación que permiten que una variable mantenga su valor en la memoria. Esta dificultad probablemente se debe precisamente al hecho de que lenguajes de scripting populares como Python no utilizan esta implementación. Por esta razón, un programador acostumbrado a trabajar en Python tiene una inmensa dificultad para entender este concepto. Las variables no siempre pierden —o mejor dicho, olvidan— su valor cuando el bloque al que pertenecen deja de existir.

Sin embargo, los programadores de C/C++ tienen este concepto bastante afianzado en sus mentes. Y como MQL5 deriva de estos lenguajes, terminó adoptando este mismo tipo de concepto. Lo cual, en mi opinión, es algo muy positivo. Ya que, de otra forma, sería necesario trabajar con variables globales en el ámbito de la aplicación, lo que en muchos casos resulta ser un gran inconveniente.

Muy bien, entonces, para explicar cómo funciona este tipo de concepto, vamos a iniciar un nuevo tema.


Variables estáticas

Las variables estáticas son uno de los conceptos más poderosos y, al mismo tiempo, más complicados de comprender para una amplia gama de programadores principiantes. Esto ocurre porque, a primera vista, no tienen mucho sentido. Sin embargo, conforme las estudias y comienzas a comprender su funcionamiento, pero sobre todo los momentos en los que pueden y deben ser aplicadas, llegas a sentir un profundo aprecio por ellas. Ya que resuelven muchos problemas que, de otra manera, serían mucho más complicados de resolver.

Para empezar, vamos a ver un caso bastante sencillo. Sin embargo, aunque todavía no hemos entrado en ciertos conceptos de programación, quiero que no te preocupes por nada más que no sean las variables. Olvida todo lo demás y trata de entender lo que está ocurriendo con las variables, pues este será el punto realmente importante aquí.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     uchar counter = 0;
07.     ulong value = 1;
08. 
09.     Print("Factorial of ", counter, " => ", value);
10.     counter = counter + 1;
11.     value = value * counter;
12.     Print("Factorial of ", counter, " => ", value);
13.     counter = counter + 1;
14.     value = value * counter;
15.     Print("Factorial of ", counter, " => ", value);
16.     counter = counter + 1;
17.     value = value * counter;
18.     Print("Factorial of ", counter, " => ", value);
19.     counter = counter + 1;
20.     value = value * counter;
21.     Print("Factorial of ", counter, " => ", value);
22. }
23. //+------------------------------------------------------------------+

Código 01

Lo sé, podríamos usar un bucle aquí. Pero vamos a considerar que tú estás, de hecho, comenzando desde cero a aprender programación. No sabes absolutamente nada sobre el tema y todo lo que conoces fue visto en el artículo anterior. Por lo tanto, necesitamos ir desde el principio. Al inicio es un poco más complicado, pero pronto las cosas serán más claras.

Muy bien, el gran detalle aquí es el siguiente: cuando ejecutamos este Código 01 en el terminal de MetaTrader 5, obtendremos como resultado lo que se muestra justo a continuación.


Figura 01

Perfecto, como puedes ver, funciona. Lo que estamos haciendo aquí es calcular el factorial de un número. Solo que, en lugar de hacerlo y devolver simplemente el resultado, lo estamos calculando paso a paso. Este hecho es importante para que entiendas a dónde quiero llegar.

Ahora bien, presta atención, querido lector. En la línea seis, creamos e inicializamos una variable. Esta se encargará de contar cuál es el factorial actual que estamos calculando. Luego, en la línea siete, declaramos otra variable y la inicializamos con el valor adecuado. Y sí, el factorial de cero es uno, al igual que el factorial de uno también es igual a uno. Tener este conocimiento es fundamental para realizar cualquier trabajo de programación. Ya que programar implica resolver las cosas de manera matemática, al contrario de lo que muchos piensan, que la programación consiste simplemente en escribir muchas cosas y hacer que el computador las ejecute. El trabajo del programador, en esencia, consiste en transformar fórmulas matemáticas en código que la máquina pueda comprender. Por esta razón, saber matemáticas es fundamental para ser un buen programador.

Volviendo a nuestra cuestión, en las líneas 09, 12, 15, 18 y 21 imprimimos los resultados de una forma legible para los humanos. Y entre cada uno de estos pasos, le indicamos a la máquina cómo debe proceder para calcular el siguiente valor. Ahora presta atención al siguiente hecho: cada vez que calculamos el factorial del número actual, usamos el valor del factorial anterior. Es decir, aunque inicialmente counter y value sean constantes, con cada nuevo cálculo solicitado, esos valores que antes eran constantes cambian, convirtiéndose en una nueva constante. Este es el concepto más singular sobre las variables que debes llevar contigo por el resto de tu vida como programador.

Bien, ahora que estamos en el mismo barco, podemos intentar simplificar las cosas usando menos líneas de código. Para lograr esto, necesitaremos utilizar otro concepto, que aunque será explicado de manera más adecuada más adelante, es necesario en este momento. El concepto en sí es el de rutina.

Una rutina, básicamente, es algo que la máquina debe ejecutar cada vez que se lo ordenamos. Sería como una tarea tediosa y repetitiva, que no queremos estar escribiendo en forma de código todo el tiempo. Algo parecido a lo que ocurre en varias líneas del Código 01. Existen, básicamente, dos tipos de rutinas: las funciones y los procedimientos. Pero aquí, para explicar las variables estáticas, utilizaremos un procedimiento, porque resulta más sencillo comprender lo que está ocurriendo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. uchar counter = 0;
05. ulong value = 1;
06. //+------------------------------------------------------------------+
07. void OnStart(void)
08. {
09.     Factorial();
10.     Factorial();
11.     Factorial();
12.     Factorial();
13.     Factorial();
14. }
15. //+------------------------------------------------------------------+
16. void Factorial(void)
17. {
18.     Print("Factorial of ", counter, " => ", value);    
19.     counter = counter + 1;
20.     value = value * counter;
21. }
22. //+------------------------------------------------------------------+

Código 02

Ahora observa que este Código 02 es mucho más sencillo de entender. A simple vista, notarás que estamos calculando el valor del factorial desde cero hasta cuatro. Esto ocurre porque tenemos cuatro llamadas al procedimiento Factorial, dentro de lo que es el bloque principal del código, es decir, el procedimiento OnStart. Como mencioné anteriormente, hablaremos más sobre este tipo de cosas más adelante. Pero, por ahora, enfoquémonos en entender las variables.

Observa que, a pesar de la aparente diferencia entre el Código 01 y el Código 02, ambos tendrán como resultado la Figura 01. Sin embargo, aquí en el Código 02, estamos utilizando dos variables globales, que nacerán cuando el código se ejecute y morirán solo después de que el código finalice. Entre un momento y otro, estas mismas variables podrán ser modificadas por cualquier procedimiento o función que tenga visibilidad sobre ellas. Incluso si el cambio ocurre por una falla tuya, debido a una distracción durante el proceso de implementación del código. Lo cual no es raro en códigos complejos.

No obstante, aunque se trate de variables globales y no pertenezcan a ningún bloque específico, estos valores necesitan ser inicializados. Como puedes ver, las estamos inicializando en el momento en que las declaramos. Sin embargo, esto podría hacerse en cualquier otro momento, lo que dificultaría rastrear posibles cambios en sus valores. Pero, para simplificar, las estoy inicializando justo al declararlas. Por esta razón, en este preciso momento surge una pregunta perfectamente válida: si estoy diseñando algo que, en mi opinión, es muy complejo, y temo cambiar los valores de alguna variable global por alguna distracción durante la codificación de mi aplicación, ¿no sería mejor declarar las variables counter y value dentro del procedimiento Factorial? ¡De este modo no correría el riesgo de que dichas variables sean alteradas por un descuido!

Sí, querido lector, la mejor idea de hecho sería eliminar counter y value del ámbito global y colocarlas dentro del procedimiento Factorial. Así tendríamos un mejor control sobre las variables presentes en el código. Entonces, hagamos esto y veamos qué sucede. Pues, aparentemente, tanto el Código 01 como el Código 02 funcionan, y si funcionan, significa que vamos por buen camino. De este modo, al realizar el cambio mencionado, obtendremos el siguiente código que se muestra a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     Factorial();
07.     Factorial();
08.     Factorial();
09.     Factorial();
10.     Factorial();
11. }
12. //+------------------------------------------------------------------+
13. void Factorial(void)
14. {
15.     uchar counter = 0;
16.     ulong value = 1;
17. 
18.     Print("Factorial of ", counter, " => ", value);    
19.     counter = counter + 1;
20.     value = value * counter;
21. }
22. //+------------------------------------------------------------------+

Código 03

Genial, ahora ya no tenemos el problema de las variables globales en el ámbito del código. Nuestro programa, de hecho, está mucho más organizado. Pero, ¿qué hay del resultado? ¿Todavía estamos calculando los valores del factorial entre cero y cuatro? Bien, veamos. Después de compilar el código y ejecutarlo en el terminal de MetaTrader 5, se nos presenta el siguiente resultado:


Figura 02

¡Vaya! No funcionó. Pero, ¿por qué? Si antes funcionaba. Ahora, de hecho, no entiendo, ya que aparentemente estamos ejecutando el procedimiento cinco veces, como era esperado. Sin embargo, parece que todo el tiempo estamos obteniendo los mismos valores. Hmm, déjame pensar un poco... Tranquilo.

Entendí lo que está ocurriendo: cada vez que ejecutamos una de las llamadas presentes en lo que tú llamaste el bloque principal, que es OnStart, estamos declarando nuevamente las variables counter y value. Y al hacer esto, también las estamos inicializando con los valores iniciales que se vieron en los demás códigos anteriores. Ahí está la razón por la que no funcionó. Ahora entendí lo que se denomina el "bloque de vida" de una variable. Pero aún me queda una duda: ¿y si NO informo el valor en las líneas 15 y 16? ¡Quizás funcione! No, querido lector, puedes intentar hacer eso si quieres, pero terminarás cayendo en los problemas que ya fueron abordados en el artículo anterior.

Entonces, podríamos pasar los valores al procedimiento. De esa forma funcionaría. Sí, en este caso funcionaría. Sin embargo, estarías poniendo la carreta delante de los bueyes. Como todavía no se ha explicado cómo pasar valores entre procedimientos y funciones, no puedes utilizar ese recurso por ahora. Necesitas idear otra forma de hacer que este Código 03 funcione y nos muestre la misma información que se ve en la Figura 01, y no esa cosa extraña que observamos en la Figura 02. ¿Te das por vencido?

Bien, si ese es el caso, llegó la hora de terminar con este sufrimiento. Para resolver el problema, sin recurrir a ninguna solución mágica y manteniendo las variables counter y value dentro del procedimiento Factorial, necesitamos usar lo que se conoce como una variable estática. Al hacer esto, la variable que esté declarada como estática NO perderá su valor durante llamadas distintas a un mismo procedimiento o función.

Parece algo muy complicado, ¿verdad? Pero en la práctica, la cosa es mucho más simple. Siempre que prestes atención a lo que estás haciendo, todo saldrá bien. Sin embargo, si te descuidas, todo podría salirse completamente de control. Para comprender esto, veamos cómo quedaría el código en la práctica. Se puede ver a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     Factorial();
07.     Factorial();
08.     Factorial();
09.     Factorial();
10.     Factorial();
11. }
12. //+------------------------------------------------------------------+
13. void Factorial(void)
14. {
15.     static uchar counter = 0;
16.     static ulong value = 1;
17. 
18.     Print("Factorial of ", counter, " => ", value);    
19.     counter = counter + 1;
20.     value = value * counter;
21. }
22. //+------------------------------------------------------------------+

Código 04

Observa que la única diferencia entre el Código 03 y el Código 04 es justamente la presencia de la palabra reservada static en las líneas 15 y 16. Sin embargo, solo por este hecho, ahora el resultado al ejecutar este Código 04 en el terminal de MetaTrader 5 es exactamente el que se ve en la Figura 01, es decir, hemos obtenido el tan esperado éxito. No obstante, debido a la propia naturaleza estática, estas variables declaradas como estáticas deben ser tratadas con cierto cuidado y atención. Esto se debe a que existen reglas muy específicas sobre ellas. No es que estés obligado a hacer ciertas cosas, sino que necesitas entender cómo funcionan.

Una variable estática es, en primer lugar, una variable que siempre debe estar dentro de un bloque. Aunque en ciertos tipos de situaciones podamos utilizarlas fuera de bloques para fines específicos, siempre debes pensar en usarlas dentro de algún tipo de bloque.

En segundo lugar, salvo en casos muy, pero muy específicos, NUNCA inicialices una variable estática fuera del lugar donde se declara. Hacer esto sin el debido cuidado puede hacer que pierdas el control de tu código. Como aquí estamos trabajando con algo muy simple y orientado a la didáctica, podrías tener una falsa sensación de control. Sin embargo, no te engañes pensando que siempre estás en control. Cualquier descuido que cometas será suficiente para que pierdas horas o días intentando resolver el problema. Para dejar esto muy claro, vamos a hacer un pequeño cambio en el Código 04. Y veamos qué ocurre. El cambio puede verse en el siguiente código.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     Factorial();
07.     Factorial();
08.     Factorial();
09.     Factorial();
10.     Factorial();
11. }
12. //+------------------------------------------------------------------+
13. void Factorial(void)
14. {
15.     static uchar counter;
16.     static ulong value = 1;
17. 
18.     counter = 1;
19.     Print("Factorial of ", counter, " => ", value);    
20.     counter = counter + 1;
21.     value = value * counter;
22. }
23. //+------------------------------------------------------------------+

Código 05

Estoy colocando los códigos completos para que puedas seguir las modificaciones. De este modo, podrás comprender de manera más profunda lo que está ocurriendo y lo que un pequeño descuido puede provocar en una aplicación. Observa y compara el cambio que ocurrió aquí entre el Código 04 y este Código 05. Parece algo trivial, casi sin ningún riesgo o efecto secundario. Algo que ni siquiera pensarías que podría causar algún problema o un cambio en los resultados finales. Sin embargo, al ejecutarse, lo que debería mostrar la Figura 01 en el terminal de MetaTrader 5, se convierte en algo completamente diferente, como puede verse en la figura a continuación.


Figura 03

¡Esto es una locura! Por lo que puedo percibir, lo que se suponía que era un cálculo factorial se convirtió en un cálculo de potencias de dos. Esto sí que es algo extraño. Pero, ¿por qué ocurrió esto? Bien, querido lector, existe un pequeño truco para trabajar adecuadamente con variables estáticas. Un programador más experimentado, cuando se encuentra con un código que no se comporta como se esperaba, inmediatamente sospecha de algún error en el uso de las variables. Si el lenguaje permite el uso de este tipo de variable y el código contiene variables de este tipo, debes verificar estas variables primero.

Procura comprobar si están siendo inicializadas correctamente y si se espera que sus valores cambien. Estos son los primeros puntos que deberás revisar. Como normalmente los cambios en los valores de una variable son algo esperado —de lo contrario, usaríamos constantes—, puedes verificar si la variable está cambiando y si no está olvidando el último valor que se le asignó. Existen varias técnicas de depuración para esto. Estudia cómo depurar un programa para obtener más detalles, ya que cada situación requiere un enfoque ligeramente diferente.

Pero volviendo a la cuestión de por qué el código se comportó de manera extraña, siendo que aparentemente no hay nada incorrecto en él, ese es el primer pensamiento que le pasa por la mente a cualquier programador. Sin embargo, las variables estáticas SON INICIALIZADAS en el momento en que son creadas. Si esto no ocurre, en el momento en que le asignes un valor, la variable se comportará como una variable local. Es decir, es como si hubiese sido declarada en ese instante. Naturalmente, esto implica que dentro de un bloque debes evitar al máximo lo que se ve en la línea 18 del Código 05. Hacer esto romperá la variable estática, haciendo que trabaje de manera incorrecta. Por eso el código se comportó de forma extraña: porque lo que era una variable estática ahora es simplemente una variable común.

Muy bien, con esto ya tenemos una buena base para comenzar a trabajar en los próximos puntos.


Tipos de datos

Dentro del tema que estamos tratando en este momento, hay una cuestión que podemos abordar brevemente. Esto con el fin de introducir el tema de manera inicial, ya que a medida que avancemos, notarás que hay mucho más involucrado aquí.

El asunto en cuestión es el tipo de dato o variable. Diversos lenguajes, pero principalmente las basadas en scripts, como por ejemplo JavaScript y Python, lenguajes que no requieren que el programador declare el tipo de datos que se van a almacenar. Es decir, son del tipo NO TIPADAS Mientras que otras, como C/C++ y el propio MQL5, son lenguajes fuertemente TIPADOS. Es decir, exigen que el programador indique qué tipo de dato se espera. ¿Y qué significa esto en la práctica? Bien, en la práctica, esto significa que una variable en Python puede recibir cualquier tipo de valor. Sin embargo, una variable en MQL5 no puede recibir cualquier valor. Esto es en teoría, ya que existen maneras de intentar sortear este tipo de inconveniente.

De cualquier manera, para quienes programan en lenguajes tipados, existe un mayor nivel de dificultad para realizar ciertas cosas, ya que no basta con declarar una variable y colocar cualquier cosa en ella. Existen reglas y límites para esto. Sin embargo, lenguajes como Python permiten que una variable pueda recibir un texto o incluso cualquier otro valor, y la propia lengua se encargará de ajustar la variable al tipo más adecuado. Es decir, la dificultad para programar es mucho menor debido a esto, lo que hace que la creación del código sea mucho más simple, rápida y sin necesidad de tanta especialización por parte del programador. Esto es diferente de lo que ocurre en un lenguaje tipado, donde necesitas saber qué puede o no contener cada tipo.

En este momento, quizás estés pensando en desistir de entender MQL5 y comenzar a buscar algo más simple como Python o JavaScript. Sin embargo, sin desmerecer a estas otros lenguajes no tipados, cuando aprendes a manejar los tipos presentes en un lenguaje, trabajar en uno donde no existe este control se vuelve algo muy monótono y, a veces, incluso aburrido. Esto se debe a que manipular datos implica entender qué representa cada uno, poder clasificarlos en tipos y conocer los límites que tiene cada uno. Este tipo de conocimiento abre puertas a diversas aplicaciones interesantes, como criptografía o compresión de datos.

Pero dejemos este tema para otro momento. Ahora mismo, vamos a entender qué son los tipos y cuáles son sus limitaciones básicas.

En MQL5 tenemos algunos tipos básicos, que pueden ser: enteros, lógicos, literales, punto flotante, enumeradores y strings. Estos también se encuentran en códigos C/C++. Sin embargo, además de estos tipos comunes en muchos lenguajes basados en C/C++, MQL5 tiene algunos especiales, como datos de color y datos para fecha y hora. Aunque estos son tipos derivados de otros, como veremos más adelante, el hecho de que existan resulta de gran ayuda en varios momentos.

Por otro lado, también existen tipos de datos complejos tanto en C/C++ como en MQL5. Estos tipos se clasifican en estructuras y clases. En el caso de las clases, estas solo existen en C++. Sin embargo, en MQL5, las clases son mucho más simples de entender y trabajar que en C++. Aunque, en algunos momentos, como programador de C++, echo de menos algunos recursos de clases que están presentes en C++ pero no en MQL5. Aun así, si no están disponibles, nos adaptamos para que el trabajo y el objetivo puedan cumplirse.

Bien, esta fue la introducción básica sobre el tema. Pero podemos hablar un poco más antes de finalizar este artículo, como por ejemplo la cuestión de los límites de cada uno de los tipos básicos. Conocer y entender estos límites te ayudará enormemente en la creación de tus futuros códigos, sin importar cuál sea el objetivo que desees alcanzar. Vamos a comenzar con una pequeña tabla, que se puede observar a continuación.

Tipo Número de bytes Valor más bajo Valor más alto
char 1 -128 127
uchar 1 0 255
bool 1 0 (Falso) 1 (Verdadero)
short 2 -32 768 32 767
ushort 2 0 65 535
int 4 - 2 147 483 648 2 147 483 647
uint 4 0 4 294 967 295
color 4 -1 16 777 215
float 4 1.175494351e-38 3.402823466e+38
long 8 -9 223 372 036 854 775 808 9 223 372 036 854 775 807
ulong 8 0 18 446 744 073 709 551 615
datetime 8 0 (01/01/1970 00:00:00) 32 535 244 799 (31/12/3000 23:59:59)
double 8 2.2250738585072014e-308 1.7976931348623158e+308

Tabla de tipos básicos

Esta tabla representa únicamente los tipos simples de datos. Aquí no estamos analizando los tipos complejos. Estos serán tratados en un momento más oportuno. Sin embargo, entender esta tabla con los tipos simples nos ayuda a elegir el tipo más adecuado según lo que necesitemos para nuestros cálculos. Esto se debe a que cada tipo tiene un límite inferior y superior que puede representar.

No obstante, hay algo en esta tabla que será analizado con más detalle en el futuro: los tipos double y float. Esto es porque ambos tienen algunas particularidades que necesitan ser explicadas aparte y con calma, para que puedas comprenderlos de manera adecuada.

Pero vamos a analizar brevemente esta tabla. Puedes notar que existe una similitud en los nombres, donde en algunos casos aparece la letra u precediendo el nombre del tipo, como en char y uchar. Esta letra u tiene un significado especial: cuando el nombre del tipo está precedido por esta letra, significa que el tipo comienza en cero y llega hasta un máximo determinado. Esto se debe a que esta u inicial proviene de la palabra inglesa unsigned, que significa sin signo. Pero, ¿qué significa "sin signo" en la práctica? Bien, querido lector, cuando tenemos un valor sin signo, significa que será interpretado siempre como un valor positivo. En cambio, cuando el valor tiene signo, puede ser tanto positivo como negativo. Esto se comprenderá mejor cuando hablemos sobre operaciones matemáticas. Pero, básicamente, puedes interpretarlo de la siguiente manera: si deseas almacenar un valor negativo, puedes colocarlo en un tipo que tenga signo. Sin embargo, si todos los valores que se almacenarán son positivos, puedes usar un tipo sin signo. Pero, ¿por qué digo puedes? ¿No sería más correcto decir debes? En realidad, esto no es obligatorio, querido lector. Cuando hablemos de operaciones matemáticas, explicaré esto con más detalle. Pero aquí hay una regla fundamental: los valores del tipo entero, es decir, los que no utilizan punto flotante, son valores precisos. En cambio, los valores del tipo punto flotante no son valores exactos. Aunque, al observar esta tabla, podrías pensar que lo mejor sería usar siempre datos del tipo double porque abarcan un rango considerable, en la práctica esto no se aplica necesariamente. Por lo tanto, saber elegir el tipo adecuado es algo fundamental para un buen programador.

Sin embargo, probablemente estés mirando esta tabla y pensando: ¿Pero dónde está el tipo string? ¡¿Acaso no es un tipo básico?! Sí, querido lector, el tipo string es un tipo básico. Sin embargo, es un tipo especial que encaja mejor en otra categoría, la cual será explicada más adelante. Por esta razón no aparece en esta tabla.


Consideraciones finales

En este artículo nos hemos dedicado, básicamente, a hablar sobre las variables del tipo estática. Hicimos algunos experimentos con ellas para demostrar cómo podrías, en algún momento, sacarles provecho. Es un hecho que aquí nos enfocamos en explicar una de las posibles aplicaciones del tipo estático, ya que estas también pueden utilizarse para otros propósitos. Sin embargo, la gran mayoría de las veces en que te encontrarás con variables del tipo estática, estarán siendo utilizadas como se mostró aquí. En otro artículo hablaremos sobre otras formas de usar las variables estáticas para distintos fines. Por ahora, lo que hemos visto y explicado aquí te ayudará a entender muchos programas, así como también a implementar soluciones más eficientes que no dependan del uso excesivo de variables globales sin ningún tipo de criterio.

También dimos un breve vistazo a lo que será el tema del próximo artículo, que trata precisamente sobre los tipos de datos. Descubrimos que existen diferencias y límites para cada tipo de dato presente en MQL5, aunque no hemos explicado por qué existen dichos límites ni cómo podemos encontrar formas de sortearlos con el fin de extenderlos para propósitos más específicos.

Pero no te preocupes, querido lector, veremos esto en breve. Por ahora me despido, y dejo adjuntos los códigos vistos en este artículo para que puedas experimentarlos y sacar tus propias conclusiones respecto a lo que hemos presentado aquí. Así que, hasta pronto.

Traducción del portugués realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/pt/articles/15302

Archivos adjuntos |
Anexo.zip (1.75 KB)
Algoritmo de optimización de reacciones químicas (CRO) (Parte II): Ensamblaje y resultados Algoritmo de optimización de reacciones químicas (CRO) (Parte II): Ensamblaje y resultados
En la segunda parte, reuniremos los operadores químicos en un único algoritmo y presentaremos un análisis detallado de sus resultados. Descubramos cómo el método de optimización de reacciones químicas (CRO) aborda la solución de problemas complejos en funciones de prueba.
Del básico al intermedio: Variables (I) Del básico al intermedio: Variables (I)
Muchos programadores principiantes tienen muchas dificultades para comprender por qué sus códigos no funcionan como esperan. Existen muchos detalles que hacen que un código sea realmente funcional. No se trata simplemente de escribir toda una serie de funciones y operaciones para que un código funcione. ¿Qué tal si aprendemos de la manera correcta cómo se crea un código real en lugar de copiar y pegar fragmentos de código encontrados aquí y allá? El contenido expuesto aquí tiene como objetivo, pura y simplemente, la didáctica. En ningún caso debe considerarse como una aplicación cuya finalidad no sea el aprendizaje y el estudio de los conceptos mostrados.
Desarrollamos un asesor experto multidivisa (Parte 17): preparación adicional para el trading real Desarrollamos un asesor experto multidivisa (Parte 17): preparación adicional para el trading real
Ahora nuestro EA utiliza una base de datos para recuperar las cadenas de inicialización de instancias individuales de estrategias comerciales. Sin embargo, la base de datos es bastante voluminosa y contiene mucha información innecesaria para el funcionamiento real del asesor experto. Vamos a intentar que el EA funcione sin conexión obligatoria a la base de datos.
La teoría del caos en el trading (Parte 2): Continuamos la inmersión La teoría del caos en el trading (Parte 2): Continuamos la inmersión
Continuamos nuestra inmersión en la teoría del caos en los mercados financieros: hoy analizaremos su aplicabilidad al análisis de divisas y otros activos.