English Русский Deutsch 日本語 Português
preview
Del básico al intermedio: Arrays y cadenas (II)

Del básico al intermedio: Arrays y cadenas (II)

MetaTrader 5Ejemplos | 14 enero 2025, 06:04
112 0
CODE X
CODE X

Introducción

El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación final cuyo objetivo no sea el estudio de los conceptos expuestos.

En el artículo anterior, «Del básico al intermedio: Arrays y cadenas (I)», hicimos una breve introducción sobre cadenas y arrays. Aunque ese artículo se centró prácticamente en las cadenas, todo lo que se mostró es solo una introducción ligera y breve sobre el tema. Sin embargo, para poder abordar otros temas, necesitamos profundizar un poco más en lo que se explicó en él. Por lo tanto, para seguir y comprender lo que se verá en este artículo es necesario haber entendido lo que se presentó en el artículo anterior.

Pero, además de este primer requisito, existen otros igualmente necesarios, como comprender el comando IF y los comandos utilizados en bucles, así como tener nociones básicas sobre operadores y variables. Si has estudiado los artículos anteriores, habrás cubierto todos estos requisitos. Si no es tu caso, asegúrate de repasar lo que se mostró antes para poder comprender el contenido de este artículo.

Muy bien, a la luz de estas primeras informaciones, podemos pasar al tema principal de este artículo. Pero, para ello, avancemos hacia un nuevo tema.


Formato personalizado

Una de las cosas más interesantes de programar en MQL5 es que no tenemos que preocuparnos de crear ciertas cosas. De hecho, son raros los momentos en los que la biblioteca estándar no satisface nuestras necesidades. Sin embargo, es posible que no lo haga completamente o que no se adapte a lo que necesitamos o deseamos hacer. Un ejemplo de esto es crear un formato personalizado para presentar algún tipo de información, ya sea en el terminal o en algún objeto gráfico que vayamos a utilizar.

Como en estos primeros momentos no utilizaremos objetos gráficos, todo el trabajo que realizaremos estará orientado a usar la salida estándar de MetaTrader 5, es decir, el terminal. Pronto mostraré cómo puedes hacer que las cosas sean mucho más interesantes. Pero, para llegar a ese momento, primero debemos adquirir unos conocimientos sólidos y consolidados sobre ciertas características de un lenguaje de programación.

Por tanto, este contenido inicial no está exclusivamente orientado a MQL5. También puede aplicarse a otros lenguajes, especialmente en lo que se refiere a conceptos y reglas de programación. Como se mencionó al inicio de este tema, existen situaciones en las que la biblioteca estándar de MQL5 no será suficiente para cubrir nuestras necesidades. Sin embargo, si aplicas los conocimientos presentados en los demás artículos y pones en práctica un poco de razonamiento lógico, podrás implementar muchas cosas interesantes, aunque en este artículo solo hayamos abordado conceptos básicos sin un propósito definido.

La parte más fascinante de ser programador no es, de hecho, definir un propósito para un determinado conocimiento, sino idear formas de utilizar ese conocimiento para resolver un problema específico. Lo interesante es que, a medida que comprendes cómo funcionan ciertas cosas y comienzas a idear formas de utilizar ese conocimiento para resolver un problema específico, dicho conocimiento acaba cobrando un propósito.

Ahora quiero que pienses en el siguiente problema, estimado lector: supongamos que deseas visualizar o imprimir valores binarios en el terminal de MetaTrader 5. El motivo no importa, solo el problema. Bien, tienes este desafío frente a ti y piensas: «Bueno, puedo usar la formateo de cadenas para presentar valores binarios en el terminal». Perfecto. Este sería el primer pensamiento de un buen programador. Sin embargo, un programador con más experiencia ya sabría la respuesta. Sin embargo, un programador principiante buscaría en la documentación una forma de formatear la cadena para mostrar la representación binaria de un valor numérico, solo para descubrir que tal funcionalidad no existe. Es en este momento cuando la creatividad, aliada al conocimiento, comienza a mostrar el camino a seguir.

Muy bien, dado que no existe un formato predefinido para presentar valores binarios, debemos crearlo. Siendo un principiante en programación y teniendo en cuenta solo la información presentada en los artículos anteriores, podrías pensar que esto no es posible. Pero ¿es realmente así? Veamos si es posible hacerlo utilizando únicamente la información proporcionada en los demás artículos.

Primero, sabemos que existe una función en la biblioteca estándar que nos permite formatear diversos tipos de datos. Por lo tanto, todo lo que necesitamos es crear lo que sería nuestro formato personalizado para que el formateo con valores binarios pueda realizarse. Bien, esta es la parte fácil. Sin embargo, hay una parte un poco más complicada de resolver. Esto se debe a que, a diferencia de C y C++, donde es posible añadir un número ilimitado de datos o argumentos en una función, en MQL5 no tenemos esa posibilidad. Y hasta donde sé, C y C++ son los únicos lenguajes que permiten este tipo de funcionalidad. Bueno, también está Assembly, pero nadie está tan loco como para programar algo en Assembly. Sinceramente, eso sí sería una prueba de locura.

Bien. El hecho de que no se puedan pasar un número ilimitado de argumentos a una función complica un poco las cosas, al menos a primera vista. Sin embargo, podemos dividir el problema en etapas pequeñas para resolverlo. Como queremos crear un nuevo formato y utilizar uno ya presente en la biblioteca estándar de MQL5, podemos manipular los datos para lograrlo. ¿Cómo? Muy sencillo, estimado lector. Creamos una función que devuelve una cadena de texto con el valor convertido en su representación binaria. Dado que la biblioteca estándar de MQL5 puede trabajar con cadenas para formatear el texto, será fácil crear nuestro formato personalizado.

Tal vez, al pensar en ello de esta manera, parezca difícil de hacer. Pero, si observas el código que se muestra a continuación, verás que es muy sencillo.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     uchar value = 138;
07. 
08.     PrintFormat("The value %d in binary is written as: %s", value, BinaryToString(value));
09. }
10. //+------------------------------------------------------------------+
11. string BinaryToString(const uchar arg)
12. {
13.     return "--BINARY--";
14. }
15. //+------------------------------------------------------------------+

Código 01

Cuando ejecutemos este código 01, el resultado será el que podemos ver justo abajo.

Imagen 01

En este punto, podrías pensar: «Vaya, pero esto no es lo que queríamos hacer». Efectivamente, estimado lector, no es lo que deseamos. Pero sirve para mostrarte que podemos aprovechar lo que ya existe para intentar crear algo nuevo. Observa que la cadena de texto que está en la línea 13 es la misma que se visualiza en la imagen 01. Es decir, funciona.

Ahora, lo único que tenemos que hacer es convertir, o traducir, el valor que la función está recibiendo en una representación binaria. A continuación, insertamos esa representación dentro de una cadena y la devolvemos. Algo que estamos haciendo en la línea 13.

Entonces, ¿cómo podemos transformar el valor recibido en una cadena que contenga solo ceros y unos? Es bastante sencillo, estimado lector. Para ello, utilizaremos un bucle. Sin embargo, hay un pequeño detalle. Pero te lo explicaré directamente dentro del código, que puedes ver a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     uchar value = 138;
07. 
08.     PrintFormat("The value %d in binary is written as: %s", value, BinaryToString(value));
09. }
10. //+------------------------------------------------------------------+
11. string BinaryToString(const uchar arg)
12. {
13.     string  sz0 = "";
14.     uchar   mask = 0x80;
15. 
16.     while (mask)
17.     {
18.         sz0 = sz0 + ((arg & mask) == mask ? "1" : "0");
19.         mask = mask >> 1;
20.     }
21. 
22.     return sz0;
23. }
24. //+------------------------------------------------------------------+

Código 02

Al ejecutar este código, verás la imagen que se muestra justo abajo en el terminal de MetaTrader 5.

Imagen 02

Es definitivamente perfecto. Es decir, con unos conocimientos mínimos y bastante básicos, conseguimos cumplir el desafío. Sin embargo, hay un pequeño detalle en este código. Con los conocimientos que hemos mostrado hasta este punto, NO PODEMOS utilizar cualquier tipo de dato para convertirlo en su representación binaria. Esto solo sería posible si entráramos en temas más avanzados de programación. Sin embargo, para cuestiones simples, donde usaremos solo un único tipo de dato —en este caso, uchar—, ya tenemos una función que funciona correctamente. Y observa que es bastante sencilla. Además, como todo lo que se ha hecho aquí se ha explicado en los artículos anteriores, no es necesario explicar cómo esta función realiza su tarea. Sin embargo, dado que el operador de desplazamiento aún no se ha explicado y se está utilizando en esta función, considero prudente explicar cómo funciona. Esto lo veremos en el próximo tema. Antes de continuar, quiero llamar tu atención sobre un detalle importante, estimado lector. La variable `mask` debe tener el mismo ancho de bits que la variable `arg`. Esto garantiza una conversión y traducción perfecta de los valores. A medida que publiquemos nuevos artículos con contenido más avanzado, veremos cómo hacer que el compilador resuelva este problema por nosotros. Esto nos permitirá usar cualquier tipo de dato, desde tipos complejos hasta tipos más simples, sin modificar casi nada en la función mostrada en el código 02. Pero bueno, esto lo abordaremos en el futuro. Por ahora, aprendamos cómo funciona el operador de desplazamiento. Así que avancemos hacia un nuevo tema.


Operador Shift, o de desplazamiento

Normalmente, los operadores son bastante intuitivos. Sin embargo, el operador de desplazamiento puede ser algo confuso para algunas personas, ya que está diseñado exclusivamente para trabajar con información computacional. Al menos, no tengo conocimiento de su uso fuera del ámbito de la computación o la electrónica digital. Este operador, que puedes observar en la línea 19 del código 02, es muy práctico e incluso interesante en varios casos. Sin embargo, NO es un operador especial. Simplemente reemplaza a otros dos operadores que suelen aparecer en ciertos códigos. Me refiero a dos operadores porque existen dos tipos de desplazamiento: uno para desplazar hacia la derecha y otro para desplazar hacia la izquierda. Algunas personas, cuando comienzan a estudiar programación, confunden estos operadores de desplazamiento con los operadores de relación, que se usan para determinar si un valor es mayor o menor que otro. Esta confusión suele deberse a la falta de atención, ya que el operador de desplazamiento está compuesto por dos flechas —ya sea hacia la derecha o hacia la izquierda—, mientras que los operadores de relación utilizan solo una flecha.

Bien, pero ¿qué nos dice este operador de desplazamiento? Cuando se utiliza, este operador nos indica cuántos bits se van a desplazar hacia la derecha o hacia la izquierda un determinado valor. Este tipo de operación puede parecer algo complicada a primera vista. Sin embargo, es mucho más simple que utilizar los operadores que sustituye. 

¿Cómo es eso? No entiendo. Si existe otra manera de decir lo mismo, ¿por qué no la utilizamos? Al menos, ¿podrías mostrarnos cuál sería esa otra forma? Por supuesto que puedo mostrarla, estimado lector. De hecho, precisamente por eso estoy escribiendo este tema. Quiero que comprendas por qué, en ocasiones, una respuesta no utiliza la misma implementación. Es bastante improbable que dos programadores tuvieran la misma idea para resolver el mismo problema. Sin embargo, no estoy diciendo que no pueda suceder, solo que es poco probable. Esto se debe a que la forma de resolver un problema depende del nivel de conocimiento y experiencia de cada programador.

Volvamos a nuestra cuestión. Para explicar de manera clara, sencilla y didáctica cómo actúan los operadores de desplazamiento, juguemos un poco con el código que se muestra a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const uchar shift = 1;
07.     uchar   i0 = 153,
08.             i1,
09.             i2,
10.             i3,
11.             i4;
12. 
13.     i1 = i0 << shift;
14.     i2 = i0 * (uchar)MathPow(2, shift);
15.     i3 = i0 >> shift;
16.     i4 = i0 / (uchar)MathPow(2, shift);
17. 
18.     PrintFormat("Shift value          : %d\n" + 
19.                 "Original             : %s\t%d\n" +
20.                 "Shifted to the left  : %s\t%d\n" +
21.                 "Multiplication result: %s\t%d\n" +
22.                 "Shifted to the right : %s\t%d\n" +
23.                 "Division result      : %s\t%d"
24.                 , shift, BinaryToString(i0), i0, 
25.                          BinaryToString(i1), i1, 
26.                          BinaryToString(i2), i2, 
27.                          BinaryToString(i3), i3, 
28.                          BinaryToString(i4), i4
29.                 );
30. }
31. //+------------------------------------------------------------------+
32. string BinaryToString(const uchar arg)
33. {
34.     string  sz0 = "";
35.     uchar   mask = 0x80;
36. 
37.     while (mask)
38.     {
39.         sz0 = sz0 + ((arg & mask) == mask ? "1" : "0");
40.         mask = mask >> 1;
41.     }
42. 
43.     return sz0;
44. }
45. //+------------------------------------------------------------------+

Código 03

Cuando ejecutes este código, verás la imagen que se muestra justo debajo.

Imagen 03

Ahora presta atención para entender lo que estamos haciendo aquí, querido lector. Este código 03, que al principio puede parecer confuso, es bastante claro en su objetivo y lo cumple muy bien. Sin embargo, para entenderlo, necesitas saber qué significa la función MathPow. Dado que forma parte de la biblioteca de MQL5, revisa la documentación para obtener más detalles. En pocas palabras, esta función realiza el cálculo de potenciación y devuelve un valor del tipo double. Como nuestros datos son del tipo uchar, debemos hacer una conversión explícita de tipos. De esta manera, el compilador no generará advertencias sobre que estamos trabajando con tipos diferentes.

Ahora, observa que en la imagen 03 mostramos el valor y su representación binaria en cada una de las líneas. Esta representación binaria es importante porque muestra con más claridad lo que sucedió con nuestro valor original. Podríamos decir que, al desplazar un valor hacia la izquierda, lo estamos multiplicando por dos, y que, al desplazarlo hacia la derecha, lo estamos dividiendo por dos. En cierto sentido, no te equivocas al analizar la imagen 3. Sin embargo, si cambiamos el valor del desplazamiento, por ejemplo de uno a tres, ¿qué ocurrirá?

Imagen 04

La imagen 04 muestra lo que sucede cuando usamos un desplazamiento de tres posiciones. En este caso, puedes observar algo curioso que ocurre al desplazar por tres. En realidad, no estamos simplemente multiplicando o dividiendo por dos, sino que el cálculo se realiza mediante una potencia de dos. Es decir, necesitamos dividir por dos elevado a algún número o multiplicar por dos elevado a ese mismo número para obtener el resultado correcto, algo que se logra justamente utilizando el operador de desplazamiento. Como realizar este tipo de operaciones con potencias y luego multiplicaciones o divisiones es más costoso en términos computacionales, es preferible utilizar el operador de desplazamiento.

Sin embargo, al observar los valores en la imagen 04, notarás que parte de la información desaparece. Esto no es un error en el programa, estimado lector. Es una consecuencia de los límites que tiene cada tipo de dato. Dado que MQL5 es un lenguaje que utiliza tipos para definir variables, cuando se exceden esos límites, parte de la información se pierde. Existen varias formas de evitar o mitigar este problema, pero en este momento no viene al caso. Podemos dejar la explicación de cómo resolver esto para otra oportunidad, que seguramente llegará. Créeme, en programación siempre hay oportunidades para nuevos aprendizajes.

Espero que haya quedado claro cómo funciona el operador de desplazamiento. De esta forma, el código 02 debería estar completamente explicado y comprendido a la perfección. Podemos pasar a otro tema relacionado con cadenas y arrays.


Pangrama y Anagrama

Existe una aplicación bastante curiosa y, en algunos casos, incluso divertida, que podemos abordar en este momento, aunque hayamos visto poco contenido hasta ahora. Se trata de los pangramas. Un pangrama es una frase en la que se utilizan todas las letras del abecedario con fines de prueba. Aunque es algo relativamente antiguo, puede ofrecernos una actividad muy interesante y bastante didáctica. Quizás el pangrama más famoso sea:

A QUICK BROWN FOX JUMPS OVER THE LAZY DOG 0123456789

Se utilizó para realizar pruebas en antiguos telégrafos. Incluía todos los caracteres que podían aparecer en una frase. Sin embargo, lo que probablemente lo hizo aún más famoso fue cuando Microsoft lo utilizó en Word para mostrar cómo se vería el texto impreso. En aquel entonces, algunas personas llegaron a afirmar que había cosas ocultas en las herramientas de Microsoft, lo que provocó que mucha gente temiera utilizar ordenadores.

Pero incluso en el contexto que estamos tratando en este momento podemos utilizar este tipo de frases. Esto nos permitirá demostrar y aprender ciertos conceptos sobre cadenas y arrays. Como es algo bastante simple y muy entretenido, creo que te gustará entender cómo funciona.

No es raro escuchar consejos para crear contraseñas fuertes o incluso frases que funcionen como contraseña. Sin embargo, crear contraseñas fuertes o recordarlas puede ser muy complicado. Por otro lado, muchas personas argumentan, y encontrarás bastante información al respecto, que existen programas especializados para almacenar contraseñas. Pero si estos programas requieren una contraseña para guardar otras de manera segura, en mi opinión, esto no resulta muy útil.

Sin embargo, incluso un programador principiante que ya comprende cómo funcionan algunos comandos y funciones básicas puede crear una aplicación para generar una contraseña relativamente segura. Claro está, la fortaleza de la contraseña dependerá de ciertas características del sistema en el que se programe. Aun así, siguiendo esta lógica, tú, estimado lector, podrás crear algo bastante interesante, siempre y cuando sepas cómo mejorar lo que mostraré aquí, ya que el objetivo principal es puramente didáctico.

Para empezar, pensemos en lo siguiente: ¿qué es una contraseña? Bien, una contraseña es un conjunto de caracteres imprimibles que están en una cadena de texto. Por tanto, si tomamos una cadena y trabajamos con ella, podremos crear un programa que la mezcle o la cifre. El objetivo es crear una contraseña fuerte, para lo cual este proceso de mezcla, que podría ser un cifrado o incluso un anagrama, ocultará parcialmente la contraseña original. Sin embargo, los anagramas no son muy efectivos para ocultar información que se vaya a utilizar en otro lugar, como una contraseña. Lo mejor es utilizar una mezcla o un cifrado, empleando un anagrama o un pangrama como frase de codificación. La clave es la frase que puedas recordar y el resultado final será la contraseña que utilizaremos.

Para que tú, estimado lector, entiendas lo que intento describir, echemos un vistazo a un primer código bastante básico y sin muchas pretensiones. Puedes verlo justo a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const string sz_Secret_Phrase = "Um pequeno jabuti xereta viu dez cegonhas felizes";
07. 
08.     Print("Result:\n", PassWord(sz_Secret_Phrase));
09. }
10. //+------------------------------------------------------------------+
11. string PassWord(const string szArg)
12. {
13.     const string szCodePhrase = "The quick brown fox jumps over the lazy dog";
14. 
15.     string  szPsw = "";
16.     uchar   pos;
17. 
18.     for (int c = 0; c < StringLen(szArg); c++)
19.     {
20.         pos = (uchar)(StringGetCharacter(szArg, c) % StringLen(szCodePhrase));
21.         szPsw = StringFormat("%s%c", szPsw, StringGetCharacter(szCodePhrase, pos));
22.     }
23. 
24.     return szPsw;
25. }
26. //+------------------------------------------------------------------+

Código 04

Al observar este código, podrías pensar: «¡Vaya locura es esta que estás intentando hacer aquí!». Tranquilo, estimado lector. Sé que lo que estamos haciendo aquí parece extraño y sin sentido, pero pronto entenderás lo que quiero mostrarte. Observa lo siguiente: este código solo utiliza lo que hemos visto hasta ahora. No se está añadiendo nada nuevo. Todo lo que se está haciendo aquí se entiende perfectamente si has comprendido los artículos anteriores y te tomas el tiempo de estudiar las funciones de la biblioteca que se usan en este código. Todo lo utilizado aquí se puede encontrar fácilmente en la documentación de MQL5. Por ello, no entraré en detalles sobre las funciones utilizadas. Sin embargo, si ejecutas este código SIN MODIFICAR, verás la imagen que se muestra justo a continuación.

Imagen 05

La región marcada en la imagen 05 representa la contraseña que deberías utilizar. Pero fíjate que contiene un problema evidente: los espacios. Normalmente, las contraseñas no incluyen espacios en ninguna parte. Por lo tanto, debemos corregir este error. Una forma muy sencilla de hacerlo es eliminar los espacios y poner la primera letra en mayúscula. Verás que es algo bastante simple de lograr. Al realizar este cambio en la línea 13 del código 04, obtendremos algo parecido al código que se muestra a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const string sz_Secret_Phrase = "Um pequeno jabuti xereta viu dez cegonhas felizes";
07. 
08.     Print("Result:\n", PassWord(sz_Secret_Phrase));
09. }
10. //+------------------------------------------------------------------+
11. string PassWord(const string szArg)
12. {
13.     const string szCodePhrase = "TheQuickBrownFoxJumpsOverTheLazyDog";
14. 
15.     string  szPsw = "";
16.     uchar   pos;
17. 
18.     for (int c = 0; c < StringLen(szArg); c++)
19.     {
20.         pos = (uchar)(StringGetCharacter(szArg, c) % StringLen(szCodePhrase));
21.         szPsw = StringFormat("%s%c", szPsw, StringGetCharacter(szCodePhrase, pos));
22.     }
23. 
24.     return szPsw;
25. }
26. //+------------------------------------------------------------------+

Código 05

En este punto, al comparar el código 05 con el 04, podrías decir: «Pero no ha cambiado nada. Esto no funcionará. El resultado será muy similar al anterior». ¿Será así en realidad, estimado lector? Veámoslo. Cuando se ejecute este código 05, el resultado será el que se muestra en la siguiente imagen.

Imagen 06

¡Vaya! Ha cambiado, y mucho. Es completamente diferente. No tiene nada que ver con la imagen 05. Muchas personas piensan que para programar algo así es necesario ser un genio de las matemáticas o tener muchos años de experiencia en programación. Sin embargo, aquí estoy demostrando que, con unos conocimientos mínimos de programación y una buena dosis de creatividad, puedes obtener resultados muy buenos e incluso sorprendentes. Si consideras que esta contraseña es demasiado simple, aunque bastante larga, podemos solucionarlo fácilmente. Nota que la única diferencia entre el código 04 y el código 05 es precisamente la línea 13; ninguna otra línea se ha modificado. Por lo tanto, es natural preguntarse si mejoraría la contraseña si añadimos algunos símbolos extra a esa línea 13. Bien, podemos probar también eso, estimado lector. Así que modifiquemos la línea 13 reemplazándola con la que se muestra a continuación.

    const string szCodePhrase = ")0The!1quick@2brown#3fox$4jumps%5over^6the&7lazy*8dog(9";

Y el resultado será el que se muestra a continuación.

Imagen 07

Entonces, estimado lector, ¿no le parece divertido? Y eso que estamos usando una programación muy básica. Sin embargo, podemos mejorar un poco las cosas, aunque para eso tendremos que escribir un código ligeramente diferente.

Voy a hacer algo un poco distinto para que puedas comprender otro detalle mencionado en el artículo anterior. Allí mencioné que el tipo `string` NO existe en C y C++. Sin embargo, en MQL5 este tipo sí existe, precisamente para evitar que tengamos que usar un estilo de programación presente en C y C++. Esto se debe a que, en C y C++, una cadena es realmente una matriz que contiene un valor especial que indica dónde termina la cadena. Como MQL5 utiliza el mismo valor para señalar esto, podemos modificar el código que genera una contraseña para que no dependa de las llamadas a la biblioteca estándar de MQL5.

Ahora bien, quiero que prestes atención, porque utilizaremos algo que también se usa en C y C++. Esto sitúa a MQL5 en una posición intermedia, como mencioné en el artículo anterior. Sin embargo, aquí solo haré una breve introducción al tema, que se explicará con más detalle en el próximo artículo.


Cadenas son arrays

El título de este tema lo deja bien claro: habla exactamente de lo que sucede en las entrañas de la programación. Sé que a muchos esto les puede parecer confuso, pero en el próximo artículo abordaremos este concepto de manera más profunda. De todos modos, quiero dejarte una idea para que comiences a estudiar cuanto antes, porque las cosas se volverán bastante complejas y lo harán rápidamente cuando empecemos a hablar de este tema en el siguiente artículo.

Aprovechando esta oportunidad, podemos modificar el código del tema anterior para que trate la cadena como si fuera una matriz. Puede parecer una idea algo loca, pero existen ciertas ventajas desde el punto de vista de la programación cuando adoptamos este enfoque.

De esta manera, el código 04 se transforma en el que se muestra a continuación.

01. //+------------------------------------------------------------------+
02. #property copyright "Daniel Jose"
03. //+------------------------------------------------------------------+
04. void OnStart(void)
05. {
06.     const string sz_Secret_Phrase = "Um pequeno jabuti xereta viu dez cegonhas felizes";
07. 
08.     Print("Result:\n", PassWord(sz_Secret_Phrase));
09. }
10. //+------------------------------------------------------------------+
11. string PassWord(const string szArg)
12. {
13.     const string szCodePhrase = "The quick brown fox jumps over the lazy dog";
14. 
15.     uchar   psw[],
16.             pos;
17. 
18.     ArrayResize(psw, StringLen(szArg));
19.     for (int c = 0; szArg[c]; c++)
20.     {
21.         pos = (uchar)(szArg[c] % StringLen(szCodePhrase));
22.         psw[c] = (uchar)szCodePhrase[pos];
23.     }
24.     return CharArrayToString(psw);
25. }
26. //+------------------------------------------------------------------+

Código 06

Cuando se ejecute este código, el resultado será idéntico al mostrado en la imagen 5. Sin embargo, si modificas la línea 13 tal y como se explicó en el tema anterior, notarás que los resultados serán los mismos que los anteriores. No obstante, este código 06 tiene la ventaja de que aquí estamos utilizando un sistema de arrays en lugar de trabajar directamente con una cadena. Estas ventajas se explicarán con mayor detalle en el próximo artículo, donde se profundizará en cómo sacar provecho de este tipo de modelado. Y, por increíble que parezca, estimado lector, en mi opinión, este código sigue siendo algo que cualquier principiante bien instruido y dedicado a sus estudios puede comprender perfectamente, incluso sin que yo explique en detalle su funcionamiento.

De todos modos, en el próximo artículo explicaré este código con el detenimiento que merece. Solo lo estoy presentando ahora para que no dejes que el material se acumule y pienses que, por ser sencillo y fácil, puedes posponer su estudio para otro momento.


Consideraciones finales

En este artículo, que me pareció bastante entretenido, creamos algo práctico con un propósito real, más allá de simplemente aplicar conceptos teóricos. Sé que algunos de los temas tratados aquí pueden parecer intimidantes al principio, pero esto no debe disuadirte. Al contrario, con este artículo quiero demostrarte que, incluso si eres un programador principiante, con una buena dosis de creatividad e ingenio, puedes crear y manipular datos de texto para construir algo que muchos consideran que requiere años de experiencia en programación.

Creo firmemente que el hecho de haber visto estas cosas realizadas con un conocimiento mínimo —pues todo lo que se hizo aquí puede comprenderse con base en lo explicado en los artículos anteriores— te hará más proactivo y menos relajado al pensar que lo visto antes no tendría ninguna utilidad. Pues ahí lo tienes. Así que diviértete explorando los archivos del anexo. Y queda confirmado: nos vemos en el próximo artículo, donde el tema serán los ARRAYS.

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

Archivos adjuntos |
Anexo.zip (2.43 KB)
Del básico al intermedio: Arrays y cadenas (III) Del básico al intermedio: Arrays y cadenas (III)
En este artículo veremos dos aspectos. El primero es cómo la biblioteca estándar puede transformar valores binarios en otras formas de representación, como el sistema octal, el sistema decimal y el sistema hexadecimal. El segundo versará sobre cómo podríamos definir el ancho de nuestra contraseña basándonos en una frase secreta, con el conocimiento mostrado hasta ahora. El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación cuya finalidad no sea aprender y estudiar los conceptos mostrados.
Del básico al intermedio: Arrays y cadenas (I) Del básico al intermedio: Arrays y cadenas (I)
En este artículo, empezaremos a explorar algunos tipos especiales de datos. Empezaremos definiendo qué es una cadena de texto (string) y explicando cómo utilizar algunos procedimientos básicos. Esto nos permitirá trabajar con este tipo de dato, que puede resultar curioso, aunque en ciertos momentos puede resultar un poco confuso para principiantes. El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación cuya finalidad no sea aprender y estudiar los conceptos mostrados.
Del básico al intermedio: Array (I) Del básico al intermedio: Array (I)
Este artículo constituye una transición entre lo que se ha visto hasta ahora y una nueva etapa de estudios. Para comprender este artículo es necesario haber leído los artículos anteriores. El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación cuya finalidad no sea aprender y estudiar los conceptos mostrados.
Del básico al intermedio: Precedencia de operadores Del básico al intermedio: Precedencia de operadores
Se trata, sin duda, del tema más complicado de explicar únicamente con la parte teórica. Por esta razón, te aconsejo que practiques lo que se mostrará aquí. Aunque al principio todo parezca simple, esta cuestión sobre los operadores solo se comprenderá bien con la práctica aliada a un estudio constante. El contenido expuesto aquí tiene un propósito puramente didáctico. En ningún caso debe considerarse una aplicación cuya finalidad no sea aprender y estudiar los conceptos mostrados.