Tutorial Completo de C orientado a Decompilación
ATENCIÓN: Si eres nuevo en este mundillo, es normal que no entiendas muchas cosas, a pesar de que está todo explicado muy meticulosamente. Si no entiendes cualquier parte NO TENGAS MIEDO de dejar un comentario para preguntarlo. Es más tonto el que se calla para no parecerlo, que el que pregunta para aprender más.
ATENCIÓN: Si eres nuevo en este mundillo, es normal que no entiendas muchas cosas, a pesar de que está todo explicado muy meticulosamente. Si no entiendes cualquier parte NO TENGAS MIEDO de dejar un comentario para preguntarlo. Es más tonto el que se calla para no parecerlo, que el que pregunta para aprender más.
El objetivo de este post es que cualquier persona, incluso aquellas que nunca han programado, salgan de aquí pudiendo leer los archivos de decompilación y se sientan lo suficientemente cómodos porque lo entienda prácticamente todo. Creo que es el paso que falta dar para que la gente se anime con estos proyectos, y el mundo de la creación de fangames en esta base resurja.
A continuación tenéis spoilers con la explicación y ejemplos de todos los conceptos necesarios para aprender a programar, aunque lo que os diferenciará de un buen y un mal programador, dependerá de lo mucho que practiquéis y lo estrictos que seáis con las buenas prácticas que os explique. Si consideráis que ya sabéis en que consiste alguno de los conceptos, podéis sentirlos libres de saltar al que más os interese.
Puede que pienses...
A mi me gusta decir que programar es dar órdenes a un ordenador, y dar órdenes sabemos todos ( ͡° ͜ʖ ͡°). Para que me entendáis mejor, vamos a crear un contexto, y a ejemplificar entorno a ese contexto.
Para el ejemplo, tendremos a Alan y Ada, que viven juntos. Ada trabaja por la mañana, y Alan por la tarde, por lo que Ada le dice a Alan por la mañana
Ya veréis como todo tiene su lógica y es super fácil de entender, os doy mi palabra
Programar no es para mi, no me gustan las mates
, o que directamente pienses que es demasiado complicado, pero tengo una grata noticia para ti: En realidad, tú ya sabes programar, y dirás Me voy saliendo del tutorial, que este tío está absolutamente loco.
, pero nada de eso.A mi me gusta decir que programar es dar órdenes a un ordenador, y dar órdenes sabemos todos ( ͡° ͜ʖ ͡°). Para que me entendáis mejor, vamos a crear un contexto, y a ejemplificar entorno a ese contexto.
Para el ejemplo, tendremos a Alan y Ada, que viven juntos. Ada trabaja por la mañana, y Alan por la tarde, por lo que Ada le dice a Alan por la mañana
Si a las 13:30 no he llegado a casa, haz la comida
. ¿Todos entendemos que Alan hará la comida si son las 13:30 y Ada no ha llegado de trabajar verdad?, bien, pues esto mismo se lo podríamos transmitir a un ordenador, y con tan solo dos simples líneas de código, el ordenador podría hacerlo
C:
if(AdaTrabajando && SonLas13_30)
HacerComida();
Ya veréis como todo tiene su lógica y es super fácil de entender, os doy mi palabra
Puede parecer que no es necesario saber binario (lo de los ceros y los unos) para los proyectos de decompilación, pero en realidad, es bastante necesario entender al menos la base del binario. Visto que luego tengo que explicaros más cosas que se basan en esto.
En primer lugar, ¿qué es el código binario?, bueno, tan solo es una forma de representar los números. Nosotros estamos acostumbrados a representar cualquier número con cualquiera de los 10 dígitos que todos conocemos, es decir,
Bueno, pues voy a explicaros como hacen por lo general los ordenadores para leer un número sin signo (es decir, que con este formato no puedes representar números negativos, pero ya hablaremos de cómo hacerlo en otro momento).
Vamos a empezar por lo básico de lo básico (que al principio os va a parecer obvio, pero os va a servir para entender el binario mejor), y es que nosotros, cuando contamos por lo general, hacemos esto
Creo que ya vais pillando por donde van los tiros. Con los números binarios, hacemos exáctamente lo mismo, pero sólo con 0 y 1. A continuación os dejo una lista de los primeros números binarios para que lo veáis más claro.
A la izquierda, tenemos los números como estamos acostumbrado a leerlos (en base decimal), a la derecha, como se escribirían con solo unos y ceros (base binaria).
Y al igual que con la explicación de antes, a la izquierda podríamos ponerle tantos 0 como quisieramos, porque no significarían nada (y puede que así lo veáis más claro), pero es exactamente lo mismo
¡¡Genial!! Ya sabemos como funciona el binario. Parecía tan difícil y ahora es tan fácil... .
Como regalito por haber entendido este primer concepto, os voy a dar un truquito para que podáis saber que valor decimal le corresponde a un número en base binaria.
NOTA: Debéis saber que decir que tenemos 8 bits, es lo mismo que decir que tenemos un 1 byte. Y 16 bits, son 2 bytes. Para que lo tengáis en cuenta si lo digo más adelante.
En primer lugar, ¿qué es el código binario?, bueno, tan solo es una forma de representar los números. Nosotros estamos acostumbrados a representar cualquier número con cualquiera de los 10 dígitos que todos conocemos, es decir,
0, 1, 2, 3, 4, 5, 6, 7, 8 y 9
. Y con estos dígitos, podemos formar cualquier número, el 73, el 248, el 1830, cualquiera. Pero... ¿Y si os digo que con sólo unos y ceros, también podemos representar cualquier número?Bueno, pues voy a explicaros como hacen por lo general los ordenadores para leer un número sin signo (es decir, que con este formato no puedes representar números negativos, pero ya hablaremos de cómo hacerlo en otro momento).
Vamos a empezar por lo básico de lo básico (que al principio os va a parecer obvio, pero os va a servir para entender el binario mejor), y es que nosotros, cuando contamos por lo general, hacemos esto
0, 1, 2, ... 8, 9, 10
, cuando llegamos al 9, ya no existe otro dígito, porque solo tenemos 10, así que, tenemos que añadir un número más a la izquierda para poder seguir representando más números. Puede que así lo veáis más claro: 00, 01, 02, ... 08, 09, 10
. Si os dais cuenta, cuando contamos, es como si a la izquierda tuviéramos un cero, y cuando llegamos al tope, si queremos seguir contando, aumentamos el valor de ese cero, sólo que como cuando hacemos operaciones, o usamos los números en el día a día, ese cero ahí no tiene sentido, pues no lo usamos, pero estar, está ahí . Y lo mismo pasa si seguimos: ... 18, 19, 20...
, siempre que llegamos al tope, aumentamos el dígito de la izquierda, y el de la derecha lo ponemos a cero, además, esto se puede expandir al siguiente caso001, 002, ..., 008, 009, 010, 011, 012 ... 097, 098, 099, 100, 101, 102...
.Creo que ya vais pillando por donde van los tiros. Con los números binarios, hacemos exáctamente lo mismo, pero sólo con 0 y 1. A continuación os dejo una lista de los primeros números binarios para que lo veáis más claro.
A la izquierda, tenemos los números como estamos acostumbrado a leerlos (en base decimal), a la derecha, como se escribirían con solo unos y ceros (base binaria).
C:
0 = 0
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
9 = 1001
10 = 1010
11 = 1011
12 = 1100
C:
0 = 0000
1 = 0001
2 = 0010
3 = 0011
4 = 0100
5 = 0101
6 = 0110
7 = 0111
8 = 1000
9 = 1001
10 = 1010
11 = 1011
12 = 1100
Como regalito por haber entendido este primer concepto, os voy a dar un truquito para que podáis saber que valor decimal le corresponde a un número en base binaria.
NOTA: Debéis saber que decir que tenemos 8 bits, es lo mismo que decir que tenemos un 1 byte. Y 16 bits, son 2 bytes. Para que lo tengáis en cuenta si lo digo más adelante.
Si queremos leer un número binario, debemos saber que a cada dígito le corresponde un valor en decimal, y que si los sumamos todos, tendremos el valor decimal del número binario. Dicho así suena muy lioso, pero con esta imagen lo vais a entender super fácil seguro.
El valor del bit más a la izquierda en decimal, siempre es 1, el siguiente, 2, el siguiente 4, luego 8, luego 16, 32, 64...
Y tiene todo el sentido, ¿porque este número cuál es?
Es el 2.
¿Y este?
Exacto, el 4.
Y si sumamos
Así que, sip, podemos asignar los decimales a cada bit, y sumarlos para obtener el resultado en decimal.
Vamos ahora con un ejemplo más largo, para que veáis que es igual de fácil.
Algo importante es que tendréis que sumar sólo los valores cuyo bit esté a 1, si está a 0, no se debe sumar.
Como resultado, obtenemos
Efectivamente. Ahora somos los putos amos y podemos leer binario de cabeza
El valor del bit más a la izquierda en decimal, siempre es 1, el siguiente, 2, el siguiente 4, luego 8, luego 16, 32, 64...
Y tiene todo el sentido, ¿porque este número cuál es?
Es el 2.
¿Y este?
Exacto, el 4.
Y si sumamos
4 + 2
, tenemos 6, que mira por donde, se representa así:Así que, sip, podemos asignar los decimales a cada bit, y sumarlos para obtener el resultado en decimal.
Vamos ahora con un ejemplo más largo, para que veáis que es igual de fácil.
Algo importante es que tendréis que sumar sólo los valores cuyo bit esté a 1, si está a 0, no se debe sumar.
Como resultado, obtenemos
128 + 16 + 4 + 1 = 149
, vamos a probar a pasar este valor a la calculadora de windows, a ver si estamos en lo cierto.Efectivamente. Ahora somos los putos amos y podemos leer binario de cabeza
Antes de continuar, es importante que que entendáis que cuando programamos, podemos guardarnos valores en algo que llamamos
Para que me entendáis mejor, si yo le digo al ordenador:
Bien, pues este concepto se puede aplicar para todo tipo de operaciones, osea que imaginad cuando multipliquemos 5 cosas entre si, o tengamos una operación complicada, lo útil que nos será.
Además, por lo general, podremos cambiar el valor de la variable, por lo que si hacemos esto
Con esto claro, podemos seguir.
variables
. Así, si por ejemplo tenemos que hacer un cálculo de cualquier cosa, podemos guardar su resultado en dichas variables, para poder usarlo más tarde.Para que me entendáis mejor, si yo le digo al ordenador:
primerNumero = 3
, más tarde, si yo quisiera sumar ese valor a un 5 por ejemplo, podría escribir primerNumero + 5
, y el ordenador sabrá que lo que tiene que hacer es sumar 3 + 5. Y además, si lo que quisiera es almacenar ese mismo resultado en otra variable, podría hacer segundoNumero = primerNumero + 5
. Y en un futuro, cuando usemos la variable segundoNumero
, el ordenador lo leerá como si fuera un 8.Bien, pues este concepto se puede aplicar para todo tipo de operaciones, osea que imaginad cuando multipliquemos 5 cosas entre si, o tengamos una operación complicada, lo útil que nos será.
Además, por lo general, podremos cambiar el valor de la variable, por lo que si hacemos esto
primerNumero = 3
, y en la siguiente línea ponemos primerNumero = 5
, la variable primerNumero valdrá 5.Con esto claro, podemos seguir.
Debéis saber, que según lo que nos interese, un ordenador nos puede guardar la información de una manera, o de otra. Para que entendáis porqué esto es así, si quisiéramos que el ordenador por ejemplo sumara dos números, pues le podemos decir que haga
Ahora que ya sabemos porqué podríamos necesitar tener distintos tipos de datos, vamos a explicar todos ellos, aunque primero, os hablaré del tipo de dato como concepto, y luego explicaré como se usan en los proyectos de decompilación.
Tal y como hemos visto anteriormente, los datos los podemos almacenar en variables, y aunque no os lo he dicho antes por no liaros demasiado, os he de decir que todas las variables son de un tipo de dato. Es decir, vosotros en lenguaje C (hay algunos lenguajes que si), no podéis hacer
Y ahora... ¡Vamos a dar el gran paso! Ya empezamos a conocer como funcionan los ordenadores por dentro, pero aún no sabemos como podemos comunicarnos con ellos para pedirles que almacenen estos datos, pero eso va a cambiar dentro de poco . Lo primero será aclarar que hay muchas formas distintas de hacer estas cosas, es decir, existen muchos lenguajes de programación para hacer esto (exactamente igual que tú diciendo
NOTA: Es importante declarar los tipos de datos tal y como se especifica aquí, no cambiar las mayúsculas o minúsculas, ni poner espacios donde quieras. Todo tiene su debida forma de escribirse, y hay que ser rigurosos con ello.
NOTA 2: Los tipos numéricos volátiles no se explicarán, porque para empezar no son necesarios.
suma = 5 + 4
, por ejemplo, y nos dará como resultado 9. Pero no hay nada que nos impida que le digamos que nos sume sumaImposible = 3 + Hola
, por lo que por si cometemos un error de este tipo (que puede parecer muy obvio y que a nadie le va a pasar, pero más adelante, entenderéis que no es así), es importante que el ordenador sepa diferenciar si estamos intentando sumar un número con otro número, o si estamos sumando algo que no tiene sentido, como un número con un texto para que nos pueda dar un error en el que diga ¡Hey, cuidado! estás intentando sumar un número con un texto.
. Ese no es el único motivo, también está hecho por cuestión de ahorrar espacio. Para representar por ejemplo un número pequeñito, el ordenador puede necesitar sólo 1 byte (8 bits). Pero para almacenar por ejemplo Bienvenido al Mundo de los Pokémon
, se necesitarían unos 35 bytes, imaginad la diferencia que hay. Además, también sirve para tener las cosas más organizadas.Ahora que ya sabemos porqué podríamos necesitar tener distintos tipos de datos, vamos a explicar todos ellos, aunque primero, os hablaré del tipo de dato como concepto, y luego explicaré como se usan en los proyectos de decompilación.
- Tipos de datos numéricos: Los tipos de datos numéricos, sirven para almacenar números, como bien dice su nombre, y se dividen en dos tipos
- Enteros: Se usa para los números enteros, es decir, todos aquellos que no tengan decimales
2
,351
,-12
- Flotantes: Sirven para representar números con decimales:
1.5
,3.1415
,1.618033
- Enteros: Se usa para los números enteros, es decir, todos aquellos que no tengan decimales
- Tipos de datos alfanuméricos: Sirve para almacenar cualquier dato alfanumérico (números, letras y carácteres especiales), y de nuevo, tenemos dos tipos de datos alfanuméricos (NOTA: Debéis saber que para indicar que es un caracter, lo pondremos entre comillas como estas
'
, y para las cadenas de carácteres, lo pondremos entre comillas dobles como esta"
)- Carácter: En estos sólo podemos guardar un único carácter:
'a'
,'P'
,'5'
,'('
. - Cadena de caracteres: Y para estos, podríamos guardar una cadena de caracteres, es decir, un conjunto de carácteres:
"Hola"
,"¡Estoy aprendiendo a programar!"
,"Ò.Ó"
- Carácter: En estos sólo podemos guardar un único carácter:
- Tipo Booleano: Este es el más facilito, simplemente sirve para almacenar la opción
VERDADERO
, oFALSO
. Parece una tontería, pero más adelante vais a ver que es super útil (cuando programemos, tendrémos que ponerlo en inglés):TRUE
,FALSE
.
Tal y como hemos visto anteriormente, los datos los podemos almacenar en variables, y aunque no os lo he dicho antes por no liaros demasiado, os he de decir que todas las variables son de un tipo de dato. Es decir, vosotros en lenguaje C (hay algunos lenguajes que si), no podéis hacer
variable1 = 5
y luego hacer variable1 = "Texto de prueba"
. ¿Porqué? Porque cuando usamos una variable por primera vez en C, ya se guarda en la memoria del ordenador como que esa variable sirve para almacenar ese tipo de dato, y si luego le intentas asignar algo de un tipo de dato distinto, adivina que pasa... ¡ERROR!Y ahora... ¡Vamos a dar el gran paso! Ya empezamos a conocer como funcionan los ordenadores por dentro, pero aún no sabemos como podemos comunicarnos con ellos para pedirles que almacenen estos datos, pero eso va a cambiar dentro de poco . Lo primero será aclarar que hay muchas formas distintas de hacer estas cosas, es decir, existen muchos lenguajes de programación para hacer esto (exactamente igual que tú diciendo
Hola
y Hello
estás diciendo lo mismo pero en idiomas distintos. Prácticamente todos los lenguajes de programación funcionan similar, pero unos lenguajes son más útiles para unas cosas, y otros para otras. En este caso, tenemos el código fuente de los juegos de Pokémon en código C, por lo que nos enfocaremos en como hacerlo en este lenguaje de programación.NOTA: Es importante declarar los tipos de datos tal y como se especifica aquí, no cambiar las mayúsculas o minúsculas, ni poner espacios donde quieras. Todo tiene su debida forma de escribirse, y hay que ser rigurosos con ello.
NOTA 2: Los tipos numéricos volátiles no se explicarán, porque para empezar no son necesarios.
Podemos declarar hasta 4 tipos distintos de enteros, uno que sólo tenga 8 bits, otro que tenga 16, otro 32, y otro 64. Según cuánto pensemos que podamos necesitar, usaremos un tipo u otro. A continuación os dejo cuál es el valor máximo que podría almacenar cada tipo:
Por lo general, con el de 16 bits nos sobrará, pero bueno, los otros, ahí están.
Para indicar que queremos crear una variable sin signo (que será la que usemos casi siempre), pondremos una u (de unsigned) delante de uno de los cuatro valores posibles, y luego pondremos el nombre de la variable que queramos usar, es decir
¡ATENCIÓN! El nombre de la variable no puede tener espacios, tan sólo puede tener letras, números, guiones y guiones bajos, y nada más, además, es sensible a las mayúsculas y minúsculas, es decir, no será lo mismo
Bien, llegó el momento de ver el primero código en C, a continuación, vamos a declarar una variable para almacenar un número.
¡Geniaaal! Ya hemos aprendido a declarar variables, esto es un paso enorme, ni os lo imagináis.
No sé si lo habéis notado, pero después del número hay un punto y coma. El punto y coma sirve para decirle al ordenador que en esa línea ya hemos puesto todo lo que teníamos que poner, osea que tenemos que acostumbrarnos a poner el punto y coma después de las líneas. Hay algunas líneas en las que no tendremos que poner el punto y coma, pero es porque sirven para cosas diferentes. Aún así, tampoco es necesario que os aprendáis de memoria cuando poner el punto y coma, con el tiempo, y viendo el propio código de decompilación, sabréis cuando se pone y cuando no.
Aclarar que si queréis cambiar el valor de una variable que ya habéis usado una vez, no es necesario que pongáis el tipo otra vez, sólo hay que ponerlo la primera vez para que el ordenador sepa de qué tipo es la variable. Es decir, que si primero le damos un valor, y luego le damos otro, tendríamos esto.
Y el ordenador leería
Por tanto, si quisiéramos declarar otro número, pero esta vez de 64 bits por ejemplo, pues
Bien, ya entendemos los unsigned. Ahora, para los signed (con signo), es decir, con los que podremos distinguir entre números positivos y negativos, es exactamente lo mismo, pero en lugar de una u, pondremos una s, es decir
Como veis, es el mismo concepto. Y como imagino que os preguntaréis, ¿Qué son las
El ordenador no leerá todo lo que haya después de esa doble barra en esa línea. Esto nos sirve por si tenemos un programa muy largo, y en algún momento queremos dejar escrito un comentario personal de lo que hace cada cosa, para entenderlo si en un futuro volvemos a leer ese código. Por ejemplo, ahora podríamos hacer algo así
Por último, tenemos los tipos
8 bits = 255
, 16 bits = 65 535
, 32 bits = 4 294 967 295
, 64 bits = Unos cuantos cuatrillones
.Por lo general, con el de 16 bits nos sobrará, pero bueno, los otros, ahí están.
Para indicar que queremos crear una variable sin signo (que será la que usemos casi siempre), pondremos una u (de unsigned) delante de uno de los cuatro valores posibles, y luego pondremos el nombre de la variable que queramos usar, es decir
u8
para unsigned de 8 bits, u16
para unsigned de 16 bits, u32
para los de 32 bits y u64
para los de 64.¡ATENCIÓN! El nombre de la variable no puede tener espacios, tan sólo puede tener letras, números, guiones y guiones bajos, y nada más, además, es sensible a las mayúsculas y minúsculas, es decir, no será lo mismo
variabledeprueba
que variableDePrueba
. Cuando queráis poner más de una palabra en el nombre de la variable, podéis hacerlo de varias formas, ya sea separando por como hemos visto antes, como poniendo todas las primeras letras con mayúscula VariableDePrueba
, como separandolo por guiones bajos variable_de_prueba
, en fin, como más os guste, pero sin espacios ni carácteres especiales.Bien, llegó el momento de ver el primero código en C, a continuación, vamos a declarar una variable para almacenar un número.
C:
u8 primerNumero = 8;
No sé si lo habéis notado, pero después del número hay un punto y coma. El punto y coma sirve para decirle al ordenador que en esa línea ya hemos puesto todo lo que teníamos que poner, osea que tenemos que acostumbrarnos a poner el punto y coma después de las líneas. Hay algunas líneas en las que no tendremos que poner el punto y coma, pero es porque sirven para cosas diferentes. Aún así, tampoco es necesario que os aprendáis de memoria cuando poner el punto y coma, con el tiempo, y viendo el propio código de decompilación, sabréis cuando se pone y cuando no.
Aclarar que si queréis cambiar el valor de una variable que ya habéis usado una vez, no es necesario que pongáis el tipo otra vez, sólo hay que ponerlo la primera vez para que el ordenador sepa de qué tipo es la variable. Es decir, que si primero le damos un valor, y luego le damos otro, tendríamos esto.
Código:
u16 variable = 1;
variable = 9;
variable
como 9.Por tanto, si quisiéramos declarar otro número, pero esta vez de 64 bits por ejemplo, pues
C:
u64 numero65Bits = 11;
s8
, s16
, s32
y s64
.
C:
//Número negativo
s16 numeroConSigno = -14;
//Número positivo
s16 numeroConSigno2 = 14;
//
? Pues es lo que se conoce como comentarios.El ordenador no leerá todo lo que haya después de esa doble barra en esa línea. Esto nos sirve por si tenemos un programa muy largo, y en algún momento queremos dejar escrito un comentario personal de lo que hace cada cosa, para entenderlo si en un futuro volvemos a leer ese código. Por ejemplo, ahora podríamos hacer algo así
C:
//El u8 sirve para declarar números sin signo
u8 num1 = 4; //Si llamo a num1, es como si escribiera un 4
//Ahora declaro un número con signo con s8
s8 num2 = -1; //Si llamo a num2, es como si escribiera un -1
//A continuación, un mal ejemplo de comentario
u16 num3 = //Con esto me cargo el código 5;
//A pesar de poner un 5 y un ; es como si escribiera
//u16 num3 =
//Por lo que recibiría un error
float
y double
, que se representan como f32
y f64
respectivamente. Ambos sirven para almacenar números con decimales, pero los float tienen 32 bits, y los double tienen 64. Estos prácticamente no los vamos a usar.
C:
//Punto flotante es lo mismo que decir decimal
f32 numeroEnPuntoFlotante = 0.33f;
//Si os fijáis, cuando es decimal, hay que poner una f al final
f32 otroNumeroDecimal = 66.0f;
//A pesar de que no tenga decimales, ponemos el .0 con la f.
f64 loMismoPeroMasBits = 1.13872f;
Aquí realmente seguimos la misma lógica que antes, y ya os he explicado gran parte de lo que tenía que explicaros, así que iremos al grano.
Ejemplos para declarar carácteres sueltos, y cadenas de carácteres
Y ahora, para los textos en C para Decompilación, tenemos una forma un poco especial de hacerlo, no hace falta que lo entendáis, simplemente usadlo así, es un concepto un poco más avanzado que entenderéis más adelante. Usaremos el tipo u8, al final del nombre de la variable pondremos
Por lo que tendríamos esto
Ejemplos para declarar carácteres sueltos, y cadenas de carácteres
C:
//Declaración de una variable de un carácter
char letraA = 'A';
//Declaración de otra variabl de caracter
char numero5 = '5';
[]
, y el texto, lo pondremos dentro de las comillas de esta estructura _(" ");
Por lo que tendríamos esto
C:
u8 texto[] = _("¡Hola mundo!");
u8 texto2[] = _("Mi primer texto personalizado");
Pues estos son los más fáciles de todos, la manera en la que declararemos los booleanos será con
bool8
, también existen bool16
y bool32
, pero para el propósito actual, no los usaremos, así que
C:
bool8 miPrimerBool = TRUE;
bool8 MiSegundoBool = FALSE;
Bien, ahora trataremos los tipos de operadores. ¿Y qué es un operador? Pues cualquier cosa que sirva para hacer una operación a dos valores (no tienen porqué ser numéricos). Por ejemplo, una suma es una operación entre dos números.
Irémos por los distintos tipos de operadores, y lógicamente, empezaremos por los que todos conocemos. Además, empezaré a usar la sintaxis de C (es decir, la forma en la que se escribiría en código C) para que nos vayamos familiarizando con el código y le perdamos el miedo.
Irémos por los distintos tipos de operadores, y lógicamente, empezaremos por los que todos conocemos. Además, empezaré a usar la sintaxis de C (es decir, la forma en la que se escribiría en código C) para que nos vayamos familiarizando con el código y le perdamos el miedo.
Los dos primeros, son los de suma
También tenemos operador de multiplicación
De división
Vale pero... ¿Y entonces no podremos sacar el resto de las divisiones de enteros? Jejejeje, sabía que me lo preguntaríais. Para guardar el resto en lugar del cociente, no usaremos
+
y resta -
, con lo que lógicamente, podremos sumar o restar dos números.
C:
u16 sumaNums = 3 + 5;
s8 restaNums = 2 - 6;
*
C:
u8 mutliplicacion = 3*10;
/
, con el que en caso de dividir números decimales, recibiremos el número en decimal, pero si lo hacemos con enteros (u8, u16, s8, s16, etc), al dividir dos números obtendremos el cociente.
C:
s16 siete = 7;
s16 seis = 6;
s16 tres = 3;
s16 seisEntreTres = 6/3; //Por lo que seisEntreTres = 2
s16 sieteEntreTres = 7/3; //De nuevo, sieteEntreTres = 2 porque queda 1 de resto.
/
, sino que usaremos %
.
C:
u16 siete = 7;
u16 tres = 3;
u16 cociente = siete/tres; // Que daría 2 como resultado
u16 resto = siete%tres; //Que daría 1
//Y ya tendríamos cociente y resto :D
Con estos operadores, podremos comparar dos números, pero ahora, en lugar de recibir como resultado otro número, recibiremos como resultado un booleano, es decir, recibiremos o
Para agilizar, a partir de ahora explicaré todos los operadores del tipo que tengamos que ver, y luego pondré un código con ejemplos para todos.
TRUE
, o FALSE
.Para agilizar, a partir de ahora explicaré todos los operadores del tipo que tengamos que ver, y luego pondré un código con ejemplos para todos.
- Operador
<
: Servirá para comparar si el número de la izquierda es menor que el de la derecha - Operador
>
: Comparará si el número de la izquierda es mayor al número de la derecha - Operador
<=
: Comprobará si el número de la izquierda es menor o igual al de la derecha - Operador
>=
: Comprueba si el número de la izquierda es mayor o igual al de la derecha - Operador
==
: Comprueba que los dos números sean igual- Ojo, no me he equivocado, hay que poner DOS signos de igual, porque cuando pones un signo, estamos asignando y no queremos asignar, queremos comparar
- Operador
!=
: Comprobará si los números son diferentes
C:
bool8 menorQue1 = 3 < 5; //TRUE
bool8 menorQue2 = 6 < 5; //FALSE
bool8 mayorQue1 = 3 > 5; //FALSE
bool8 mayorQue2 = 6 > 5; //TRUE
bool8 menorIgualQue1 = 3 <= 5; //TRUE
bool8 menorIgualQue2 = 5 <= 5; //TRUE
bool8 menorIgualQue3 = 6 <= 5; //FALSE
bool8 mayorIgualQue1 = 2 >= 9; //FALSE
bool8 mayorIgualQue2 = 7 >= 7; //TRUE
bool8 igualQue1 = 1 == -3; //FALSE
bool8 igualQue2 = 32 == 32; //TRUE
bool8 distintoQue1 = 1 != 2; //TRUE
bool8 distintoQue2 = 5 != 5; //FALSE
Se empieza a venir la magia de la programación .
Los operadores lógicos no sirven para operar con números, ¡si no con booleanos! (Y sus resultados son booleanos también)
Me gustaría recordaros que los booleanos sólo pueden tener dos valores, verdadero, o falso. Aunque también puedes referirte a ellos como activado y desactivado, apagado y encendido, 1 (verdadero) y 0 (falso) etc.
¿Recordáis lo que os explicaba al principio de que si Ada no ha llegado de trabajar y son la 1:30PM, Alan prepara la comida? Bien, pues eso se lo traduciríamos al ordenador como una operación lógica.
Bien, explicaré que hace cada operador, y luego, ejemplos de uso.
Ahora los ejemplos
Los operadores lógicos no sirven para operar con números, ¡si no con booleanos! (Y sus resultados son booleanos también)
Me gustaría recordaros que los booleanos sólo pueden tener dos valores, verdadero, o falso. Aunque también puedes referirte a ellos como activado y desactivado, apagado y encendido, 1 (verdadero) y 0 (falso) etc.
¿Recordáis lo que os explicaba al principio de que si Ada no ha llegado de trabajar y son la 1:30PM, Alan prepara la comida? Bien, pues eso se lo traduciríamos al ordenador como una operación lógica.
Bien, explicaré que hace cada operador, y luego, ejemplos de uso.
- Operador
&&
: Compara si los dos valores booleanos son verdaderos, si lo son, devuelve TRUE, si no, devuelve FALSE - Operador
||
: Compara si al menos uno de los dos (es decir, o uno de ellos, o los dos) valores booleanos es (o son) TRUE, si es así, devuelve TRUE, si no, devuelve FALSE - Operador
!
: Niega el booleano al que se lo apliquemos, por lo que si se lo aplicamos a TRUE, devolverá FALSE, y si se lo aplicamos a FALSE, devolverá TRUE.
Ahora los ejemplos
Código:
bool8 CondicionAND1 = TRUE && TRUE; //TRUE
bool8 CondicionAND2 = TRUE && FALSE; //FALSE
bool8 CondicionAND3 = FALSE && TRUE; //FALSE
bool8 CondicionAND4 = FALSE && FALSE; //FALSE
bool8 CondicionOR1 = TRUE || TRUE; //TRUE
bool8 CondicionOR2 = TRUE || FALSE; //TRUE
bool8 CondicionOR3 = FALSE || TRUE; //TRUE
bool8 CondicionOR4 = FALSE || FALSE; //FALSE
bool8 Negador1 = !TRUE; //FALSE
bool8 Negador2 = !FALSE; //TRUE
He de decir que el primero de ellos, ya os lo he colado y no os habíais dado ni cuenta. ¿Que cuál es?
El operador de asignación básico
Con el
Pero hay más operadores de asignación, que son útiles para resumir código y quedar como unos putos pros de la programación, he de decir que los operadores de asignación que vienen a continuación, funcionarán siempre y cuando la variable ya tenga un valor de antes (con el ejemplo lo entenderéis mejor).
Y ya estaría
El operador de asignación básico
=
, que como bien dice la palabra sirve para asignar. ¿Asignar que? Pues valores a variables. Tal y como hemos venido haciendo hasta ahora
C:
s16 variableX = -2;
=
, le decimos al código que ahora la variable variableX
, vale -2
. Bastante sencillo.Pero hay más operadores de asignación, que son útiles para resumir código y quedar como unos putos pros de la programación, he de decir que los operadores de asignación que vienen a continuación, funcionarán siempre y cuando la variable ya tenga un valor de antes (con el ejemplo lo entenderéis mejor).
- Operador
+=
: Suma el valor de la derecha a la variable. Tenemos dos formas de hacer esto, convariable = variable + 3;
como lo harían los noobs, ovariable += 3;
, como lo haríamos los pros . (Pero es lo mismo) - Operador
-=
: Lo mismo, pero en lugar de sumar, resta. Código de noobs:variable = variable - 5;
- Operador
*=
: Igual que antes, pero multiplicando - Operador
/=
: Y dividiendo (Se cambia el valor de la variable por el valor del cociente de la divisón) - Operador
%=
: Y finalmente, el resto de la divisón entre la variable y el número de la derecha.
C:
u8 numero1 = 3;
numero1 += 7; //Ahora numero1 = 10 (3+7)
u8 numero2 = 5;
numero2 -= 2; //numero2 = 3 (5-2)
u8 numero3 = 3;
numero3 *= 3; //numero3 = 9 (3*3)
u8 numero4 = 5;
numero4 /= 2; //numero4 = 2 (Cociente de 5/2)
u8 numero5 = 5;
numero5 %= 2; //numero5 = 1 (Cociente de 5/2)
Los operadores unarios simplemente suben para incrementar o decrementar el valor de una variable. Se usarían así
Cada vez que lo uses sumará, o restará, depende cual uses, en una unidad.
C:
u8 valorAIncrementar = 5;
u8 valorADecrementar = 12;
valorAIncrementar++; //Ahora valorAIncrementar vale 6
valorADecrementar--; //Ahora valorADecrementar vale 11
Estos operadores son algo más complejos, y requieren de conocimientos más avanzados. Como no es algo realmente necesario para la base necesaria, os recomiendo que lo dejéis para el final.
Como es bastante más largo, creé un tutorial a parte, que podéis encontrar dando click aquí
Como es bastante más largo, creé un tutorial a parte, que podéis encontrar dando click aquí
Este es un concepto sencillito. Hasta ahora, podréis haber pensado que qué sentido tiene usar variables para darle un nombre a los números, si es más fácil escribirlos directamente. Bueno, pues en realidad, vosotros sólo estáis viendo el momento en el que creamos la variable, pero en un programa de C real, los valores de las variables están cambiando constantemente, y es extremadamente útil que se guarden con un nombre para que podamos saber qué es cada cosa.
¿Pero, y si lo que queremos es darle un nombre a un valor para que sepamos el porqué de ese valor, pero no va a cambiar? Bueno, pues eso se llaman constantes, porque son constantes, y su valor nunca cambia. Esos valores no se deben declarar en el código como las variables. Lo ideal es colocarlos todos al principio del archivo. Para que cuando estemos entre todas las líneas sepamos distinguir entre lo que es una variable o una constante, normalmente los nombres de las constantes se escriben en mayúscula y con guiones bajos.
Por ejemplo, las constantes serían útiles para guardar números concretos que signifiquen algo, así como podría ser el ancho en pixeles de la pantalla del juego.
Y así, podríamos saber qué es el número que estamos dividiendo entre 2, en lugar de poner un 240 o un 160 ahí directamente, que dentro de dos semanas no sabremos porque está ahí.
Como veis, para declarar constantes, usaremos
Y ya somos un poquito más organizados con nuestro código
¿Pero, y si lo que queremos es darle un nombre a un valor para que sepamos el porqué de ese valor, pero no va a cambiar? Bueno, pues eso se llaman constantes, porque son constantes, y su valor nunca cambia. Esos valores no se deben declarar en el código como las variables. Lo ideal es colocarlos todos al principio del archivo. Para que cuando estemos entre todas las líneas sepamos distinguir entre lo que es una variable o una constante, normalmente los nombres de las constantes se escriben en mayúscula y con guiones bajos.
Por ejemplo, las constantes serían útiles para guardar números concretos que signifiquen algo, así como podría ser el ancho en pixeles de la pantalla del juego.
C:
#define ANCHO_PIXELES_PANTALLA 240
#define ALTO_PIXELES_PANTALLA 160
u8 centroHorizontalPantalla = ANCHO_PIXELES_PANTALLA/2;
u8 centroVerticalPantalla = ALTO_PIXELES_PANTALLA/2;
Como veis, para declarar constantes, usaremos
#define NOMBRE_DE_LA_CONSTANTE valor
Y ya somos un poquito más organizados con nuestro código
Bienvenidos a una de las secciones más útiles. Con esto es con lo que le vais a empezar a dar más juego a vuestro código.
¿Recordáis el ejemplo del principio de Alan y Ada? Pues eso era una estructura condicional.
Y hasta aquí los condicionales, son mucho más útiles de lo que pueden parecer ahora, ya veréis.
¿Recordáis el ejemplo del principio de Alan y Ada? Pues eso era una estructura condicional.
Si se cumple esto, haz esta cosa, y si no se cumple, no la hagas
. Aunque hay muchas formas de usar las estructuras condicionales. Pero empezaré por explicarlas, y luego sacaremos conclusiones.Esta ya la conocemos. Simplemente escribiremos
Si analizamos el código, veremos varias cosas. En primer lugar, inicializamos el valor de
if( )
, y dentro de los paréntesis, pondremos la condición que queremos que se cumpla, luego, para indicar que queremos que haga el código si se cumple esa condición, lo pondremos después de los paréntesis, y entre corchetes. Vamos a ver un ejemplo para entenderlo mejor.
C:
bool8 adaTrabajando = TRUE;
bool8 sonLas13_30 = TRUE;
bool8 debemosHacerLaComida = FALSE;
//Como adaTrabajando es TRUE, y sonLas13_30 también, el resultado
//de la operación será TRUE, así que, si que se cumple
//la condición
if (adaTrabajando && sonLas13_30)
{
debemosHacerLaComida = TRUE;
}
debemosHacerLaComida
a FALSE
, por lo que de momento, ese es su valor. Pero cuando llegamos a la condición, vemos que la condición que ponemos, se cumple, por lo que ya cambiamos el valor de debemosHacerLaComida
a TRUE
. Ahora mismo podéis pensar que esto es inútil, pero en cuanto veamos las estructuras else y else if, os voy a poner un ejemplo más grande, y vais a ver el verdadero potencial de la programación. Prometido Esta estructura es muy sencilla si ya entendemos la estructura if. En resumen,
Bueno, bueno, esto ya no parece tan absurdo, nos sirve para saber si un número es negativo. Efectivamente, el programa primero compara la condición que le damos, que en este caso es que el número sea mayor o igual a 0, si el número es mayor o igual a 0, el valor de la variable
No está mal, pero aún podemos hacer cosas más interesantes, sigamos.
else
signifca En caso contrario
, por lo que si estáis algo avispados, ya podréis imaginar para que sirve
C:
//Como veis, no le estamos dando ningún valor inicial.
//Esto es perfectamente posible siempre y cuando más tarde
//le déis uno
bool8 numeroNegativo;
s16 numeroAComparar = -13;
if (numeroAComparar >= 0)
{
numeroNegativo = FALSE;
} else
{
numeroNegativo = TRUE;
}
numeroNegativo
pasa a ser FALSE
, y si no es mayor o igual a 0, pues su valor pasa a ser TRUE
.No está mal, pero aún podemos hacer cosas más interesantes, sigamos.
El nombre de esta puede que os confunda, pero es muy sencillita, esta sirve por si tenemos varias posibilidades y las queremos comparar todas, os pongo un ejemplo para que lo veáis de forma más visual, que sé que así lo entendéis mejor.
Y con esto, podríamos decir que hemos creado un programa que simula una calculadora simple, así de fácil. Simplemente antes de empezar el programa, tendríamos que cambiar el caracter de
Va molando, ¿eh? Pues ya veréis cuando lleguemos a las funciones... Vais a flipar.
C:
//Con esto, elegiremos la operación que queremos hacer
char operacion = '+';
//Con estas dos variables, operaremos
u16 x = 9;
u16 y = 3;
//Y aquí, guardaremos el resultado
u16 res;
if(operacion == '+')
{
res = x + y;
} else if (operacion == '-')
{
res = x - y;
} else if (operación == '*')
{
res = x * y;
} else if (operación == '/')
{
res = x / y;
} else if (operación == '%')
{
res = x % y;
} else
{
res = 0;
}
operacion
al que represente la operación que nos interese, y lo mismo con la variable x
y la variable y
. Además, hemos hecho que si en operación
ponemos cualquier otro caracter que no hayamos tenido en cuenta, el valor de res
sea 0.Va molando, ¿eh? Pues ya veréis cuando lleguemos a las funciones... Vais a flipar.
Esto es prácticamente como todo lo que podemos hacer con las estructuras
En resumen, dentro de los paréntesis después de switch, ponemos la variable a evaluar, o el resultado de una operación (porque podemos analizar cualquier tipo de datos, y por ejemplo si fueran numéricos, podríamos estar analizando
Aclarar que tanto este código como el anterior de los
if
, else if
y else
, pero en una sola estructura. La diferencia de hacerlo con uno o con otro, es que con las estructuras if
y else if
nos dan mucha más versatilidad, porque en cada condición podemos comparar variables distintas, según nos interese, sin embargo, la estructura switch sirve para comparar una única variable (o el resultado de alguna operación), y según el valor que contenga, se hará una cosa u otra. A continuación el mismo ejemplo de antes, pero con la sentencia switch. Luego del ejemplo explicaré como funciona.
C:
//Con esto, elegiremos la operación que queremos hacer
char operacion = '+';
//Con estas dos variables, operaremos
u16 x = 9;
u16 y = 3;
//Y aquí, guardaremos el resultado
u16 res;
switch(operacion)
{
case '+':
res = x + y;
break;
case '-':
res = x - y;
break;
case '*':
res = x * y;
break;
case '/':
res = x / y;
break;
case '%':
res = x % y;
break;
default:
res = 0;
break;
}
(x*5)/2
. Y después, abrimos corchetes, y dentro de los corchetes, ponemos case valor:
siendo ese valor, el que queremos que de como resultado para que pase lo que pondrémos a continuación. En las siguientes líneas, pondremos todo lo que queramos que pase, y cuando acabemos con ese caso, escribiremos break;
para indicar que ya hemos acabado. Podremos añadir tantos casos como queramos. Y por último, si queremos que pase algo cuando sea cualquier caso que no hemos puesto antes, en lugar de escribir case valor:
, simplemente escribiremos default:
, porque será lo que pasará por defecto.Aclarar que tanto este código como el anterior de los
if
, else if
, sirven exactamente para lo mismo. Sólo que como digo, en switch estás trabajando todo el rato sobre el mismo resultado, con los if
else if
else
puedes comprobar un resultado de algo distinto en cada condición.Y hasta aquí los condicionales, son mucho más útiles de lo que pueden parecer ahora, ya veréis.
Los bucles son pura magia, nos van a facilitar muchísimo muchas operaciones repetitivas, ya veréis por qué.
Para entender el concepto, en este ejemplo conoceremos a Pepe, un humilde trabajador, cuyo trabajo consiste en hacer multiplicaciones para la fábrica en la que trabaja. El encargado de Pepe llega por la mañana y le encomienda el trabajo diario.
Si traducimos esto a programación, los bucles trabajan como Pepe. Le damos un conjunto de tareas a hacer, que la tiene que repetir una cantidad de veces determinada, cuando ya lo ha hecho esa cantidad de veces, o alcanza esa condición, pues puede dejar de hacer operaciones, o lo que es lo mismo, sale del bucle.
Tenemos tres tipos de bucles, empezaré por el que más se parece al ejemplo de Pepe
Y bueno, pues ya conocemos las estructuras básicas de programación. ¡¡FELICIDADES!!
Para entender el concepto, en este ejemplo conoceremos a Pepe, un humilde trabajador, cuyo trabajo consiste en hacer multiplicaciones para la fábrica en la que trabaja. El encargado de Pepe llega por la mañana y le encomienda el trabajo diario.
Pepe, hoy tienes que hacer 200 multiplicaciones, cuando acabes te puedes ir
, por lo que Pepe empezará a hacer las multiplicaciones y las irá contando hasta que llegue al límite que su encargado le ha puesto.Si traducimos esto a programación, los bucles trabajan como Pepe. Le damos un conjunto de tareas a hacer, que la tiene que repetir una cantidad de veces determinada, cuando ya lo ha hecho esa cantidad de veces, o alcanza esa condición, pues puede dejar de hacer operaciones, o lo que es lo mismo, sale del bucle.
Tenemos tres tipos de bucles, empezaré por el que más se parece al ejemplo de Pepe
Usando el caso de Pepe, tenemos que añadir un concepto extra para el bucle for, y es la cantidad de operaciones que ya ha hecho. Puede ser que su encargado le diga que tiene que hacer 500 operaciones en dos días, en lugar de dárselas de forma diaria, por lo que el día dos, no empezará de 0, si no de la cantidad de operaciones que ya hizo ayer.
Para hacer un bucle for, tenemos tres parámetros pues.
Bien, pues ahora, vamos a poner el ejemplo real. Ahora Pepe va a empezar con un valor inicial. Luego, y ese valor, lo multiplicará por la cantidad de veces que ya ha multiplicado
Si empieza con el número a 3, veríamos que los valores del bucle for en cada iteración, serían:
Y así seguiría el pobre Pepe hasta las 200 operaciones. Por suerte tenemos los ordenadores y la programación, que nos lo pueden calcular en menos de un segundo (literalmente).
Para hacer un bucle for, tenemos tres parámetros pues.
- Parámetro 1 - Valor inicial: Este es el valor desde el que nuestro contador empieza a contar.
- Parámetro 2 - Condición para seguir en el bucle: Aquí le pondremos la condición que se debe cumplir para que siga haciendo operaciones
- Parámetro 3 - Operación sobre el contador por cada iteración: Tomando el ejemplo de Pepe, esto es cuanto se le suma al contador cada vez que hace una multiplicación.
;
):contador = 1; contador <= 200; contador++
. ¿Fácil, no?Bien, pues ahora, vamos a poner el ejemplo real. Ahora Pepe va a empezar con un valor inicial. Luego, y ese valor, lo multiplicará por la cantidad de veces que ya ha multiplicado
C:
#define OPERACIONES_DIARIAS 200
u8 contador;
u8 valorACalcular = 3;
for(contador = 1; contador <= OPERACIONES_DIARIAS; contador++)
{
valorACalcular *= contador;
}
Primera iteración
: contador = 1
, valorACalcular = 3*1 // 3
Segunda iteración
: contador = 2
, valorACalcular = 3*2 // 6
Tercera iteración
: contador = 3
, valorACalcular = 6*3 // 18
Cuarta iteración
: contador = 4
, valorACalcular = 18*4 // 72
Quinta iteración
: contador = 5
, valorACalcular = 72*5 // 360
Y así seguiría el pobre Pepe hasta las 200 operaciones. Por suerte tenemos los ordenadores y la programación, que nos lo pueden calcular en menos de un segundo (literalmente).
Este es bastante más sencillo porque usa menos parámetros (no os lo esperabais, ¿eh? ), tranquilos, lo más difícil ya está entendido.
Este bucle, simplemente seguirá haciendo iteraciones hasta que se cumpla una condición. Aquí un ejemplo.
¿Qué hace este código? Mientras que (significado de while en inglés) la variable
Podéis ver el bucle while como un if que se repite hasta que su condición no se cumpla más.
Los más avispados ya os habréis dado cuenta, pero os tengo que avisar de algo. Existe la posibilidad de crear LOS BUCLES INFINITOS . Esto nos pasará cuando por muchas iteraciones que tenga el bucle, su condición no cambia, o simplemente es imposible que deje de cumplirse, por lo que estaríamos ante un bucle infinito (y nuestro ordenador o el emulador del juego se nos quedaría pillado y tendríamos que reiniciarlo).
Un ejemplo de bucle infinito (no lo probéis, cabroncetes, que os conozco ¬u¬)
¿Qué pasa aquí? Que el bucle está sumando todo el rato 9 a la variable
Este bucle, simplemente seguirá haciendo iteraciones hasta que se cumpla una condición. Aquí un ejemplo.
Código:
u8 varX = 2;
while(varX < 100)
{
varX += varX;
}
varX
sea menor de 100, la variable varX
se suma a si misma (como si la estuviéramos multiplicando por dos, porque varX + varX = 2*varX
. He de matizar que si por ejemplo nosotros pusieramos que la variable empieza con el valor 100, o el 101, no se ejecutaría ninguna vez.Podéis ver el bucle while como un if que se repite hasta que su condición no se cumpla más.
Los más avispados ya os habréis dado cuenta, pero os tengo que avisar de algo. Existe la posibilidad de crear LOS BUCLES INFINITOS . Esto nos pasará cuando por muchas iteraciones que tenga el bucle, su condición no cambia, o simplemente es imposible que deje de cumplirse, por lo que estaríamos ante un bucle infinito (y nuestro ordenador o el emulador del juego se nos quedaría pillado y tendríamos que reiniciarlo).
Un ejemplo de bucle infinito (no lo probéis, cabroncetes, que os conozco ¬u¬)
C:
u8 numero = 2;
while(numero > 0)
{
numero += 9;
}
numero
, pero la condición es que sea mayor que 0, y es que con este código si la variable ya de por si empieza con un valor mayor a 0, nunca saldrá del bucle.Bueno, este bucle en realidad es igual que el do-while, sólo que con este, el bucle siempre se ejecuta mínimo una vez, no hace la comprobación de si se cumple la condición antes de realizar el bucle, si no después, pero la teoría es la misma.
C:
u8 varX = 2;
do
{
varX += varX;
} while(varX < 100)
Y bueno, pues ya conocemos las estructuras básicas de programación. ¡¡FELICIDADES!!
Bienvenidos a las funciones. Esto es lo más útil bajo mi punto de vista en la programación. Sin esto, no podríamos hacer casi nada, y en 10 minutos, habréis aprendido lo más importante para programar. (Con esto ya podréis editar gran parte del código de decompilación entendiendo lo que hacéis). Que ojo, no os vengáis atrás, esto a la par que lo más importante, es también de lo más fácil.
¿Recordáis cuando os enseñé que podemos darle un nombre a una variable? Bien, pues ahora os digo que podemos darle nombre a una secuencia de operaciones. Me explico, imaginad que tenemos que hacer varios cálculos diferentes para obtener un resultado final como este, a partir de tres valor iniciales
Como veis es un cálculo muy largo. Pero... ¿Y si os dijera que podemos darle un nombre a todos esos cálculos, como por ejemplo
conseguiríamos el mismo resultado?
Pues así es, así es como funcionan las funciones. Tenemos varios conceptos a destacar.
Y luego, llamaríamos a la función de la manera que vimos antes
De hecho, os he estado medio mintiendo hasta ahora. En realidad cuando estemos en C, siempre escribiremos el código en funciones, no tendremos código fuera de las funciones, pero era demasiado pronto para que lo supierais. Espero que me perdonéis :C
Además, debéis tener en cuenta una cosa muy importante. Las variables que declaréis dentro de una función, sólo la podréis usar DENTRO de esa función, es decir, no podéis hacer esto.
Si quisiéramos usar el valor de la primera función en la segunda tenemos varias opciones, la primera y menos recomendable sería declarar lo que se conoce como variables globales, es decir, que se pueden usar en todo el código. (Aunque no es recomendable que hagáis esto, hay mejores formas de hacerlo) ya que si cada vez que las necesitáis, recurrís a ellas, os pueden quedar incluso cientos de ellas, y a parte de que eso hará que nuestro código tienda a tener más errores, se quedará todo mucho más desordenado, por lo que mi obligación es deciros que existen, pero recomendaros encarecidamente que no abuséis de ellas.
Una buena forma de hacerlo sin recurrir a variables globales, sería hacer que
¿Recordáis cuando os enseñé que podemos darle un nombre a una variable? Bien, pues ahora os digo que podemos darle nombre a una secuencia de operaciones. Me explico, imaginad que tenemos que hacer varios cálculos diferentes para obtener un resultado final como este, a partir de tres valor iniciales
C:
//PRO TIP: Podemos declarar variables del mismo tipo en una misma línea
s32 a = 1, b = 3, c = 2;
//Sería lo mismo que hacer
//s32 a = 1;
//s32 b = 3;
//s32 c = 2;
s32 calculo1 = -b * (c + (b/2)) + (a*c);
s32 calculo2 = a * (-1 * c * c * b * b) - (4 * b);
s32 resultadoFinal = (calculo1 - calculo2) * (calculo1 + calculo2);
codigoLargo
, y que si luego escribiéramos esta línea
C:
s32 resultadoFinal = codigoLargo(1, 3, 2);
Pues así es, así es como funcionan las funciones. Tenemos varios conceptos a destacar.
- Podemos crear funciones que simplemente ejecuten código sin devolver un valor, o podemos recibir un valor cuando llamamos una función, tenemos las dos opciones. Si únicamente queremos ejecutar código sin que devuelva nada, empezaremos a declarar la función con
void
, que es vacío en inglés, ya que no devolverá nada. Si devuelve valor, tendremos que poner de qué tipo de dato es el valor que devuelve. Ya sea un unsigned, un bool, un char, etc. - Después del tipo, pondremos el nombre con el que llamaremos a la función (es decir, al conjunto de código), y el nombre tiene los mismo requisitos que las variables: mayúsculas y minúsculas, números, guión alto y bajo, y sin espacios.
- Después, pondremos unos paréntesis siempre, y dentro de ellos, podremos poner opcionalmente, si queremos que reciba algún valor para usarlo dentro de su código, en ese caso, pondremos el tipo de dato del parámetro, y el nombre que usaremos para referirnos a él dentro de la función, y si queremos pasar más de un parámetro, los separaremos por comas.
- Luego abrimos corchetes, y dentro pondremos todo nuestro código.
- Al final del código, justo antes de cerrar los corchetes, si hemos decidido que devuelva un valor cuando la llamemos, pondremos
return
seguido de el valor a devolver, puede ser tanto un valor concreto escrito directamente, como una variable. Pero sí o sí, deberá ser del tipo de dato que especificamos al principio de la función.
C:
s32 codigoLargo(s32 a, s32 b, s32 c)
{
s32 calculo1 = -b * (c + (b/2)) + (a*c);
s32 calculo2 = a * (-1 * c * c * b * b) - (4 * b);
s32 resultadoFinal = (calculo1 - calculo2) * (calculo1 + calculo2);
return resultadoFinal;
}
C:
s32 resultadoFinal = codigoLargo(1, 3, 2);
Además, debéis tener en cuenta una cosa muy importante. Las variables que declaréis dentro de una función, sólo la podréis usar DENTRO de esa función, es decir, no podéis hacer esto.
C:
void func1()
{
u32 x = 5;
}
void func2()
{
//No lo podríamos hacer, y daría error, porque dentro
//de esta función no existe ninguna variable con nombre "x"
u32 y = x*2;
}
C:
s32 variableGlobal = 3;
void funcion1()
{
variableGlobal = variableGlobal*2; //O variableGlobal *= 2; que queda más bonito.
}
void funcion2()
{
variableGlobal = variableGlobal/2; //variableGlobal /= 2;
}
fucnion1
, devolviera el valor de x, y que llamaramos a funcion1
desde funcion2
para almacenar su valor. Aquí un ejemplo.
Código:
u8 funcion1()
{
u8 numeroDeFuncion1 = 5;
return numeroDeFuncion1;
}
void funcion2()
{
u8 numeroDeFuncion2 = 3 * funcion1();
}
DADO QUE LOS POSTS TIENEN LÍMITES DE 50.000 CARÁCTERES, NO PUEDO SEGUIR ESCRIBIENDO AQUÍ, PARA SEGUIR CON LAS SIGUIENTES SECCIONES, HACED CLICK SOBRE CUALQUIER PARTE DE ESTE TEXTO
En construcción...
Próximos puntosEn construcción...
- Punteros y referencias
- Visibilidad de funciones
- Usos de funciones entre archivos
- Estructuras de archivos de código
Última edición: