El mayor objetivo de este post es darles a conocer una de las cosas que C++ permite hacer pero que nadie en su sano juicio deberÃa de hacer. ¿Y para que se los enseño entonces? Pues para que si algún dÃa lo ven en un código ajeno sepan qué pinch_ está pasando.
Bueno, antes que nada, #define sirve para dos cosas: definir una constante o crear un macro. Los macros pueden llegar a ser algo difÃcil de entender, ahora sólo veremos el asunto de las constantes. El asunto aquà es que si yo pongo (fuera del main) una lÃnea asÃ:
…significa que cada vez que escribamos PI en nuestro programa, C++ lo interpretará como 3.14159265. Es una simple sustitución.
#define <aquà va el nombre> <después de un espacio va el valor>
Pero el asunto es que se puedes hacer algunas cosas bastantes feas con esta propiedad. Vean este programa:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| #include<iostream>
using namespace std;
#define PI 3.14159265
#define NOF_CHAR 50
#define pause cin.get();cin.get();
#define ct cout
#define cn cin
#define false true
int main()
{
char name[NOF_CHAR] = {0};
ct << "Enter your name: ";
cn >> name;
ct << "Bye " << name << "." << endl;
if(false)
ct << "P.S. Pi = " << PI;
pause
} |
Tenemos 6 definiciones, ordenadas en su nivel de aceptabilidad:
- #define PI 3.14159265 y #define NOF_CHAR 50, éstos ejemplifican el uso primario de #define: guardan un valor que es constante durante toda la ejecución del programa.
- #define pause cin.get();cin.get();, ésta ya empieza a ser no aceptable pero podemos darla por buena porque nos ayuda a leer mejor nuestro código. Ya sabemos que al escribir cin.get();cin.get(); nuestro programa se pausa al igual que con un getch(), pero al usar este #define escribiremos en lugar de eso simplemente pause.
- #define ct cout y #define cn cin, totalmente inaceptables. Algunas personas usan este tipo de #define’s para escribir menos, pero de verdad que (en la gran mayorÃa de los casos) no vale la pena el ahorro de caracteres, sólo estamos haciendo nuestro código menos entendible para otras personas.
- #define false true, este es mas bien como una broma (y es increÃble que funcione en verdad), pero si se usa en serio es como una rayada de madre. Si ejecutan el código verán que sà se muestra la lÃnea donde se imprime PI aún que está dentro de un if al que nunca se deberÃa de entrar ¿y porqué sà entra? porque false es true.
Asà que ya saben cómo sà y cómo no usar un #define en C++, y ya no están ‘indefensos’ ante programadores con malos hábitos.
Bueno, siguiendo con la lÃnea de los posts sobre la librerÃa string.h les traigo esta función que no está en esa librerÃa pero que es muy útil al trabajar con strings. Ya dijimos que un/una string es una variable que puede contener 0, uno o más caracteres.
Ya vimos en nuestra introducción a string.h cómo declarar un string, hacerle algunas modificaciones y cómo mostrarlo. Ahora veremos como pedir un string (que el usuario la introduzca por medio del teclado).
Esto es muy sencillo si usamos la función cin.getline(); Esta función necesita tres datos o parámetros:
- Nombre. El nombre de la variable que va a contener el string
- Longitud. La cantidad de caracteres que queremos que se puedan introducir (nunca mayor que la longitud del string).
- Caracter de fin. El caracter que el usuario va usar como final de la cadena. Por lo general es el ‘enter‘ que se representa como ‘\n’ (diagonal n).
Por ejemplo, supongamos que tenemos un arreglo char de 500 elementos llamado str (nuestra string) y queremos pedirle al usuario que la “llene”, la función cin.getline quedarÃa asÃ:
cin.getline(str, 500, '\n');
Como ven, los parámetros van separados por comas (,), y el caracter de fin está entre comillas simples (‘). Pero bueno, dejemos de suponer y empecemos a programar.
#include<iostream>
using namespace std;
int main()
{
char str[500];
cout << "Introduce una frase: ";
cin.getline(str, 500, '\n');
cout << "Tu frase es: " << str;
cin.get();
}
Mas sencillo no podrÃa ser.
string.h es una librerÃa de c++ que contiene funciones que nos facilitan la vida al trabajar con cadenas o strings. Una cadena es un conjunto de caracteres almacenados en una variable.
DeberÃamos saber que char es un tipo de dato que almacena un caracter, por lo tanto un arreglo lineal de caracteres es una cadena:
char str[100];
Ahora podemos llenar nuestra cadena..
str ="Soy una cadena";
…y mostrarla
cout << str;
Pero recuerden que no podemos hacer nada de esto si no tenemos incluida la librerÃa string.h. Vamos a ver un programa de ejemplo:
#include<string.h>
#include<iostream>
using namespace std;
int main()
{
char esunacadena[100] = "Soy una cadena", esunacopia[100];
strcpy(esunacopia, esunacadena);
strcat(esunacopia, " - copia");
cout << esunacadena << endl << esunacopia;
cin.get();
return 0;
}
- Primero declaramos dos cadenas (‘esunacadena’ y ‘esunacopia’) que pueden tener hasta 100 caracteres, ‘esunacadena’ la llenamos con el texto “Soy una cadena“.
- Luego con la función strcpy copiamos el contenido de ‘esunacadena’ a ‘esunacopia’. Ahora las dos cadenas tienen el mismo texto.
- Ahora con la función strcat agregamos el texto ” - copia” al final de’esunacopia’.
- Al final solo mostramos las dos cadenas.
Bastante fácil ¿no? En los próximos dÃas voy a postear otros programas muy sencillos para seguir checando las funciones mas comunes para trabajar con cadenas.
Programar es como pensar, cada quien lo hace diferente, y el mismo lenguaje c++ nos facilita diversas formas de hacer las mismas cosas. Por ejemplo, el programa Hola Mundo que hicimos al principio podemos hacerlo utilizando la librerÃa <iostream> en lugar de <stdio.h>:
#include<iostream>
using namespace std;Â // Esta lÃnea es necesaria cuando
// utilizamos la librerÃa iostream
int main()
{
cout << "Hola Mundo!";Â //cout es el equivalente de printf,
//si se fijan la sintáxis es muy parecida.
cin.get(); // cin.get es el equivalente de getch, detiene la ejecución del programa.
return 0;Â // No es necesaria para que el programa funcione,
// pero es una buena costumbre indicar que nuestro programa terminó
// sin errores.
}
La sintáxis de cout es:
cout << "mensaje" ;
Mostrando una variable:
cout << "El promedio es:" << prom ;
El siguiente mensaje aparecerá en una lÃnea nueva:
cout << "mensaje" << endl;
¿Y cómo leo datos (scanf)?
Para sustituir scanf() usamos cin, por ejemplo:
cin >> edad;
Lee los caracteres introducidos y los guarda en la variable edad.
Un programita muy simple:
#include<iostream>
using namespace std;
int main()
{
int edad;
cout<<"Cual es tu edad?: "; cin >> edad;
cout<<"\n\tTu edad es " << edad;
cin.get();cin.get();
return 0;
}
En este caso necesitamos usar dos cin.get para detener el programa. Esto se debe al uso de cin.
La librerÃa <conio.h>, es propiedad de Borland y sólo sus compiladores pueden usarla. Por lo tanto significa que conio.h, no es una librerÃa estandar.
La librerÃa conio se utiliza más que nada por sus comandos: getch(), clrscr(), gotoxy(), textcolor(), y textbackground(), los cuales usamos para darle mejor presentación a nuestros programas. Pero pensandolo bien, ¿en verdad necesitamos que los programas en consola se vean bien? La verdad es que no, lo que importa es que funcionen.
Aún asÃ, algunas funciones de la librerÃa conio.h se pueden sustituir con funciones estándares, por ejemplo.
- Para sustituir getch(), solo necesitamos: cin.get(); la cual está en <stdio.h>. Si no funciona entonces tendremos que ponerla dos veces: cin.get();cin.get();, la cuestión es algo complicada de explicar.
- Para sustituir clrscr(), solo necesitamos escribir system(“cls”); la cual está en <iostream> (es sin .h, se definirÃa asÃ: #include<iostream>).
- Gotoxy() es algo vanal, y además se puede sustituir usando \n (espacio hacia abajo) y \t (espacio hacia la derecha) dentro de un printf();
- Y la verdad es que cualquiera te agradecerá que no le pongas fondo rosa y letras amarillas a tus programas.
Ya dijimos en el post anterior que los ciclos infinitos for son muy parecidos a los ciclos while, pero quedó en duda cómo es un ciclo while.
“While” significa “mientras“, asà que nuestro ciclo while se repetira mientras una cierta condición siga siendo verdadera.El ejemplo del post anterior quedarÃa asÃ:
#include<stdio.h>
#include<conio.h>
int main()
{
char end=0;
while(end!='y')
{
gotoxy(5,5);printf("Ya quieres salir? (y/n): ");scanf("%c",&end);
clrscr();
}
}
En español el programa dice: “Mientras end sea diferente de y voy a seguir preguntando si quieres salir.”
Mas adelante veremos más programas que utilicen ciclos while.
Ya vimos hace poco el ciclo for, y vimos que su estructura era asÃ:
for ( inicio ; fin ; aumento )
¿Qué pasa si no ponemos ni inicio ni fin? Pues obtenemos un ciclo infinito, asÃ:
for(;;)
¿Y cómo se detiene? Pues con un break, asÃ:
for(;;)
{
break;
}
¿Y esto de que me sirve? Pues la idea es repetir las instrucciones hasta que el usuario quiera, es decir:
#include<stdio.h>
#include<conio.h>
int main()
{
char end=0;
for(;;)
{
gotoxy(5,5);printf("Ya quieres salir? (y/n): ");scanf("%c",&end);
if(end=='y')
break;
clrscr();
}
}
Creo que no les habÃa mencionado que si dentro de una condición if sólo va una instrucción no es necesario poner llaves, y también aplica con los ciclos.
Si el usuario no introduce una ‘y’, el programa nunca se detendrá. Luego vamos a ver que las propiedades de un ciclo for infinito son muy parecidas a las del ciclo while que veremos más adelante.
Goto significa ir a y en c++ nos sirve para que mandar al compilador a alguna parte arbitrariamente, es decir nada más porque sÃ. No se suele usar mucho pero nos puede sacar de algunos apuros.
Su uso es más o menos asÃ:
codigo codigo
LUGAR: codigo
mas codigo
codigo
goto LUGAR;
codigo
Primero tenemos que definir un marcador, en este caso yo usé LUGAR (recuerden que ‘LUGAR’ no es lo mismo que ‘lugar’) e inmediatamente después poner dos puntos (:). Cuando sea necesario escribiremos goto seguido de nuestro identificador y punto y como (;).
¿Para qué nos podrÃa servir? Pues en el siguiente post veremos un programa que usa goto.