Curso de C++
Curso de C++
Curso de C++
¡Bienvenidos a mi curso de C++!, en realidad esto es sólo una sección del blog donde pueden
consultar una serie de posts que ya había hecho anteriormente, pero de un forma ordenada,
empezamos desde lo más básico y vamos avanzando poco a poco. Yo se que es muy fácil
darle clic a ‘Siguiente’, pero si de verdad quieren aprender no lo hagan hasta que hayan
comprendido el post y hayan hecho alguna práctica sobre ello.
Recuerden que en el curso no están todos los posts del blog, si alguna entrada les pareció
interesante pueden checar los posts relacionados (abajo de cada post) para leer otros posts
del mismo tema. Y creo que no están ordenados muy muy bien, pero creo que eso ayuda un
poco a hacer menos monótono el aprendizaje :)
Así que aquí abajo está el índice, o pueden dar clic en siguiente (aquí en la barra lateral ->)
para comenzar desde el primero; iré agregando más temas de vez en cuando.
Posts Relacionados
Entendiendo los ciclos en c++
Condiciones (decisiones) en C++ – if, else
Como usar ciclo While en C++
Funciones en C++
Curso de C++
Curso de C++
Hola Mundo, en C++
Comentarios en C++
Variables en C++ 1 – Lo básico
Variables en C++ 2 – Mostrar variables
Operaciones en C++
Operadores lógicos en C++
Pedir datos en C++ – scanf()
Condiciones (decisiones) en C++ – if, else
Entendiendo los ciclos en c++
Ciclos for en C++
if else anidados en c++
El break y el ciclo infinito
Como usar ciclo While en C++
Cómo empezar a usar iostream
Introducción a string.h
Como usar cin.getline en C++
Funciones en C++
Tipos de funciones en C++
Operadores compuestos en C++
Cuando inicializar las variables en cero y cuando no
#define en C++, cómo sí y cómo no
Diferencias entre C y C++
Me han estado llegando comentarios y correos con dudas, correcciones y todo tipo de
insultos (no, eso último no) y decidí responder todos ellos con este post en el que aclararé lo
que es C y lo que es C++ y sus diferencias.
C fue creado en 1972 por Dennis M. Ritchie en los Laboratorios Bell como evolución del
anterior lenguaje B, a su vez basado en BCPL.
C++, por su parte, fue creado a mediados de los años 1980 por Bjarne Stroustrup. La
intención de su creación fue el extender al exitoso lenguaje de programación C con
mecanismos que permitan la manipulación de objetos.
Así que C es el lenguaje original, mientras que C++ es una ampliación de C, por eso el ++.
En C
1#include<stdio.h>
2
3int main()
4{
5 printf ("Hola Mundo");
6 return 0;
7}
En C++
1#include<iostream>
2
3using namespace std;
4
5int main()
6{
7 cout << "Hola mundo";
8 return 0;
9}
Para el tipo de programas que se estarán mostrando en este blog la diferencia más
importante es la entrada y salida de datos. Así que veamos un ejemplo de entrada y salida
de datos de cada programa:
En C
1#include<stdio.h>
2
3int main()
4{
5 int radio;
6 float area, perimetro;
7
8 // SALIDA: mensaje un pantalla
9 printf("Introduce el radio del circulo: ");
10
11 //ENTRADA: recibir dato desde teclado
12 scanf("%d", &radio);
13
14 // calculos
15 area = 3.1416 * radio * radio;
16 perimetro = 3.1416 * radio * 2;
17
18 //SALIDA: resultado en pantalla
19 printf("El area es %.2f y el perimetro %.2f", area, perimetro);
20 getch();
21
22
return 0;
23
}
En C++
1#include<iostream>
2using namespace std;
3
4int main()
5{
6 int radio;
7 float area, perimetro;
8
9 // SALIDA: mensaje un pantalla
10 cout << "Introduce el radio del circulo: ";
11
12 //ENTRADA: recibir dato desde teclado
13 cin >> radio;
14
15
// calculos
16
area = 3.1416 * radio * radio;
17
perimetro = 3.1416 * radio * 2;
18
19
//SALIDA: resultado en pantalla
20
cout << "El area es " << area << " y el perimetro " << perimetro;
21
cin.get();cin.get();
22
23
24 return 0;
}
Lo que noté al hacer estos dos programitas es que pedir un dato en C++ es mucho más simple
que en C. Sin embargo, el asunto de los << y >> puede llegar a ‘asustar’ a los recién iniciados
en la programación.
Pedir un dato en C
scanf("modificador", &nombre de la variable);
Mostrar un dato en C
printf("Dato: modificador", nombre de la variable);
Los modificadores son los siguientes: %d para int, %f para float, %s para string, %c para char.
Librerías en C++
Por simple convención las librerías en C terminan en ‘.h’ (punto hache). Todas las librerías
de C sirven para C++, sin embargo, también por convención, se elimina la terminación ‘.h’ y
mejor se agrega ‘c’ al principio.
math.h cmath
string.h cstring
time.h ctime
etcetera.
El ‘namespace’
C como lenguaje tiene un conjunto de palabras reservadas, como por ejemplo: if, for, while,
int, float, … C++ es una ampliación, por lo tanto tiene que agregar nuevas palabras
reservadas. Éstas palabras reservadas están en un ‘namespace’ (espacio de nombres). En
específico cout y cin están el namespace std (standard).
Si no declaráramos que vamos a usar el namespace std (using namespace std;), cada vez que
quisiéramos usar cout, tendríamos que escribir std::cout.
Espero que a partir de ahora pueden identificar si un programa está en C o en C++. También
espero estar publicando mis programas en ambos lenguajes a partir de ahora.
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í:
#define PI 3.14159265
…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#include<iostream>
2using namespace std;
3
4#define PI 3.14159265
5#define NOF_CHAR 50
6#define pause cin.get();cin.get();
7#define ct cout
8#define cn cin
9#define false true
10
11int main()
12{
13 char name[NOF_CHAR] = {0};
14 ct << "Enter your name: ";
15 cn >> name;
16 ct << "Bye " << name << "." << endl;
17 if(false)
18 ct << "P.S. Pi = " << PI;
19 pause
20}
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.
Como ya repetí dos veces, esto es un blog, lo que significa que los posts más recientes son
los que aparecen al principio. Además, cuando inicié este blog mi propósito era ir avanzando
en dificultad conforme al tiempo, no lo he cumplido mucho pero aun así los posts sobre los
temas más básicos están ‘enterrados’ debajo de los más recientes. Así que me tomé un
tiempo para echarme un clavado de panza en el Codex de WordPress y crear una forma
diferente de navegar en el blog.
Entonces así es como inauguro (siendo las 19:30 del dia… ah no verdad?) el Curso de C++.
Todo lo que tienen que hacer es ir a este índice y comenzar a leer: Curso de C++, Índice.
Luego pueden simplemente dar clic en el link ‘Siguiente’ que aparecerá en la barra lateral (-
>).
Así que espero que les sea de utilidad, si les gusta presúmanlo, si tienen un amigo que
siempre les anda preguntando pues mándenlo aquí y líbrense de él.
Para hacer un programa pequeño (lo que sea que no necesite más de dos
archivos) no se compliquen creando proyectos. Simplemente vayan a: File/New/Empy
File. Luego guarden el archivo con extensión .cpp, preferentemente antes de
empezar a programar (si no lo guardan no tendrán diferentes colores en su código
(Sintax Highlighting)).
Hay tres botones relacionados con ‘correr’ el programa: Build, Run y Build and
Run. El primero solo construye el programa pero no lo corre, el segundo solo lo corre
y el tercero los construye y los corre. Así que cuando queramos probar nuestro
programa el botón indicado es Build and Run, pero si no hemos hecho ningún cambio
y queremos volver a probarlo es más rápido Run.
1. Crear una matriz tipo string de N filas y 2 columnas, la primera columna son las
palabras en inglés; la segunda, en español.
2. Pedir el número de palabras que el usuario quiera memorizar.
3. Obtener ese número de palabras aleatoriamente y mostrarlas.
4. Borrar las palabras y empezar a preguntar el significado de cada una.
5. Comparar la respuesta del usuario con la respuesta correcta.
6. Calcular su calificación y mostrarla.
El código es este:
1#include<cstdlib>
2#include<ctime>
3#include<iostream>
4using namespace std;
5
6int nofw;
7#define N 8 // número de pares de palabras en la matriz
8
9bool checkrep(int n, int num[])
1{
0 for(int i=0; i<nofw; i++)
1 if(n == num[i])
1 return true;
1 return false;
2}
1
3int main()
1{
4 srand(time(NULL));
1 string ans, words[N][2] = {{"hi", "hola"}, {"house", "casa"}, {"water", "agua"},
5 {"roof", "techo"}, {"chair", "silla"}, {"loudspeaker", "bocina"},
1 {"screen", "pantalla"}, {"money", "dinero"}};
6 int n, correct=0, wrong=0;
1 cout << "Numero de palabras?: "; cin >> nofw;
7 // obtener 'nofw' palabras aleatoriamente de nuestra matriz
1 int num[nofw];
8 for(int i=0; i<nofw; i++)
1 {
9 do
2 n = rand() % N;
0 while(checkrep(n, num));
2 num[i] = n;
1 cout << words[n][0] << " -> " << words[n][1] << endl;
2 }
2 cin.get(); cin.get();
2 system("cls");
3 // preguntar el significado de cada palabra
2 for(int i=0; i<nofw; i++)
4 {
2 cout << words[num[i]][0] << " = "; cin >> ans;
5 if(ans == words[num[i]][1])
2 {
6 correct++;
2 cout << ">> Bien :)\n\n";
7 }
2 else
8 {
2 wrong++;
9 cout << ">> Mal :(\n\n";
3 }
0 }
3 cout << "Tuviste un " << (float)correct / (float)nofw * 100 <<
1 "% de respuestas correctas.";
3 cin.get(); cin.get();
2}
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
Como dije antes, es sólo un bosquejo, pero tal vez sea el punto de partida para un buen
proyecto. Para optimizarlo creo que se deberían agregar algunas cosas:
Primero que nada, <cstdlib> es la forma correcta de incluir la librería <stdlib.h> en c++,
igual con <ctime>.
Como ven, usamos una función bool (que retorna falso o verdadero) para checar si el
número aleatorio ya existe en nuestra matriz. Si cualquiera de los números es igual a nuestro
número aleatorio n, la función retorna true, por lo que el ciclo do-while desde el cual
llamamos la función tendrá que repetirse una vez más y hasta que la función retorne false.
Cuando se logra salir del ciclo do-while, guardamos nuestra n en el lugar de la matriz que
corresponda, lo mostramos en pantalla y continuamos con la siguiente posición de la matriz.
Otra cosa. Para decirnos si un número está repetido en la matriz, la función checkrep()
necesita obviamente dos cosas, el número aleatorio y la matriz. Así que le enviamos como
parámetros nuestra matriz y nuestro número aleatorio.
Devolver cambio en C++
¿Han pagado algún recibo en una máquina automática y se han preguntado cómo será el
programa que les devuelve el cambio? Lo más seguro es que no, pero pues resulta que el
profesor de Miguel Ángel le encargó un programa que simulara eso, en sus propias palabras:
“Supón que una máquina de monedas de 10,5,2,1 y 50 centavos. Debes escribir un programa
que decida cuantas monedas dará de cambio, dando prioridad las de mayor denominación.
Debe recibir como entrada la cantidad de dar a cambio. Ejemplo: para $40.50 será 4 de 10,
0 de 5, 0 de 2, 0 de 1 y 1 de 50 centavos.”
Así que el primer problema se presenta con la entrada ¿cómo hacer que el usuario introduzca
sólo cantidades como $50 o $43.50 y no cantidades como $23.45 o $9.70?
Lo que se me ocurrió es pedir la cantidad en una variable float (cambio), en otra variable
convertir esa cantidad a tipo int (cambioint). En ese proceso se perderá la parte decimal del
número, así que si la resta cambio – cambioint es igual a 0 o igual a 0.50, la cantidad que
introdujo el usuario es correcta.
La otra parte es sencilla, sólo se necesita ver si la variable cambio es mayor que 10. Si, se le
restan 10 a la variable y se aumenta un contador. Luego se hace lo mismo con las demás
monedas.
Solo le faltaría darle un poco de formato a la salida, pero pues ya es cuestión de gustos y ya
saben, cualquier duda aquí están los comentarios abajo.
Pues con mi compilador sí lo es, una variable sin inicializar toma valores raros. Pero si se han
fijado en mis programas, yo no siempre inicializo mis variables, ¿por qué? Pues porque no
siempre es necesario.
La regla es bastante simple: “Si la primera instrucción en la que usamos nuestra variable es
de asignación, no es necesario inicializarla.” Por ejemplo:
cin >> var1; // no es necesario inicializarla
var2 = 14; // no es necesario inicializarla
cout << var3; // es necesario inicializarla
var4 = cos(45); // no es necesario inicializarla
var5++; // es necesario inicializarla
if(var6 != 7) // es necesario inicializarla
cin.getline(var7); // no es necesario inicializarla
Podemos seguir inicializando todas las variables que usemos, pero si únicamente
inicializamos las necesarias vamos a dar la impresión de que sabemos lo que estamos
haciendo XD
Nuestro programa sólo pedirá una cantidad en segundos, que será el tiempo que durará en
llenarse nuestra progress bar. A la ventana donde se ejecutan nuestros programas le caben
80 caracteres de largo, así que vamos a decir que nuestra progress bar tiene una resolución
de 80. El único problema es saber cuánto durará cada unidad de esas 80 para que en total se
acumule el tiempo indicado.
Ambas funciones hacen exactamente lo mismo: paran el programa durante una cierta
cantidad de tiempo en milisegundos. Por ejemplo:
printf("Hola\n");
delay(2000);
printf("Hace dos segundos te saludé!");
Ahora sí, para saber cuánto tiempo durará cada unidad de nuestra barra tenemos primero
que convertir los segundos a milisegundos (s*1000), luego dividirlos entre la resolución de la
barra (s*1000/80). Así que nuestro programa queda así:
1#include<windows.h>
2#include<iostream>
3using namespace std;
4
5int main()
6{
7 int s;
8 cout << "Segundos?: "; cin >> s;
9 for(int i=0; i<=79; i++)
10 cout << "_";
11 for(int i=0; i<=79; i++)
12 {
13 cout << "=";
14 Sleep(s*1000/80);
15 }
16}
El primer ciclo es solo por estética, para ver hasta dónde va a llenar la barra. El segundo es
el que imprime la barra con sus respectivas pausas.
Lo que hace la función recursiva es comparar el primer caracter con el último, si son iguales
recortarlos y llamarse; si no, no es palíndromo. Cualquier duda ya saben que los comentarios
están abiertos.
La verdad es que es la función es recursiva de puro milagro. Lo que hice fue transformar el
ciclo que checaba que los caracteres fueran iguales en una función en la que se aumenta una
variable cada vez que se llama a sí misma.
Tal vez una mejor manera de hacerlo sería con una función que recibiera el string a analizar,
comparar el primer y último carácter: si no, no es; si si, eliminar el primer y último carácter
y volver a llamar a la función. Esto hasta que el número de comparaciones ciertas sea igual a
la mitad de la longitud inicial del string. ¿Alguien se anima a hacerlo?
Si tienen problemas para entender cómo obtuvimos los números primos, deberían darle una
revisada a estos posts: Saber si es primo o no y Primos en un rango.
Lo que hicimos es que todo el programa estuviera dentro de un ciclo infinito que se detendrá
cuando nuestra variable que se aumenta cada vez que obtenemos un numero primo np sea
igual a la variable con la cantidad deseada de números primos cnt.
Pero recuerden que donde podemos usar un ciclo infinito, queda mucho mejor un ciclo
while:
1#include<iostream>
2using namespace std;
3
4int main()
5{
6 int cnt,i=0,ii,res,nc=0,np=0;
7 cout << "Introduce la cantidad de numeros: "; cin >> cnt;
8 while(np!=cnt)
9 {
10 i++;
11 for(ii=1;ii<=i;ii++)
12 {
13 res=i%ii;
14 if(res==0)
15 nc=nc+1;
16 }
17 if(nc==2)
18 {
19 cout << i << " ";
20 np++;
21 }
22 nc=0;
23 }
24}
Tengo pruebas para decir que casi nunca me niego a hacer programas pequeños que me
piden por correo o por comentarios, pero cuando me llegan correos pidiendo que les haga un
programa que “lleve el control del inventario de un almacén registrando cada entrada y
salida de producto… pidiendo tipo, cantidad, numero de control, precio… imprimiendo al
final del día el reporte….. y que además haga los cálculos para…. en formato de… y con 7
menús con… con un apartado de ayuda…. para mañana por favor” pues ni les respondo.
La verdad es que no se vale. Durante todo el año estuvieron haciendo programas sencillos
con los que era totalmente válido pedir ayuda, pero no, piden ayuda hasta el final del
semestre cuando les encargan un proyecto final.
Recuerden que yo también soy un estudiante y en estos días también estuve ocupadísimo con
tareas y trabajos. Por eso no había publicado nada. ¡Pero ya estoy de vacaciones!, así que ya
voy a tener un poco más de tiempo para atender mis blogs :)
A nosotros nos sirve para practicar el uso de números random, de matrices y de ciclos.
El programa es este:
1#include<stdlib.h>
2#include<ctime>
3#include<iostream>
4using namespace std;
5int main()
6{
7 int numrnd[10], cls1[10]={0}, cls2[10]={0}, ct1=0, ct2=0;
8 srand(time(NULL));
9 cout << "Los numeros: ";
10 for(int i=0; i<=9; i++)
11 {
12 numrnd[i] = rand() % 51;
13 cout << numrnd[i] << ", ";
14 if(numrnd[i] < 10)
15 {
16 cls1[ct1] = numrnd[i];
17 ct1++;
18 }
19 if(numrnd[i] > 10 && numrnd[i] < 20)
20 {
21 cls2[ct2] = numrnd[i];
22 ct2++;
23 }
24 }
25 cout << endl << "Menores que 10: ";
26 for(int i=0; i<ct1; i++)
27 cout << cls1[i] << ", ";
28 cout << endl << "Mayores que 10 y menores que 20: ";
29 for(int i=0; i<ct2; i++)
30 cout << cls2[i] << ", ";
31}
Para dudas respecto a la generación de números random está este post: Obtener
números aleatorios en C++.
Para dudas respecto a la declaración y uso de matrices está este otro post: ¡Ah
nunca he escrito sobre matrices!, voy a tener que ponerme a ello.
Para dudas con respecto a los ciclos for, sí tengo un post: Ciclos for en C++.
Las variable ct1 y ct2 se encargan de ir cambiando los índices de las matrices cls1 y cls2
respectivamente, por lo que sólo deben aumentar cuando en realidad sea necesario.
Después lo único necesario es mostrar nuestras dos matrices. Como cada matriz puede tener
un número de elementos diferentes cada vez, tenemos que hacer dos ciclos, uno para cada
matriz con ct1 o ct2 como límite.
Como última aclaración sólo digo que, tal como dice el problema, el número 10 nunca va a
quedar clasificado en algún rango porque el 10 no es menor que 1o y tampoco es mayor que
10.
El programa es este:
#include <iostream>
using namespace std;
int main()
{
int sec, hr, min;
cout << "Introduce los segundos: "; cin >> sec;
cout << sec << " segundos son ";
hr = sec / (60*60);
sec %= 60*60;
min = sec / 60;
sec %= 60;
cout << hr << " horas " << min << " minutos y " << sec << " segundos" <<
endl;
}
Primero dividimos los segundos sec entre 60*60 (3600) para obtener los horas y lo guardamos
en hr. Noten que la variable sec no cambia.
Luego obtenemos el residuo de dividir sec / 60*60 (es lo que el operador % hace) y lo
guardamos en la misma variable. En este paso sí modificamos la variable sec, ahora contiene
los segundos iniciales menos las horas que ya obtuvimos en el paso anterior.
Ahora dividimos nuevamente la variable sec / 60 para obtener los minutos y lo guardamos en
hr. La variable sec no cambia.
Luego obtenemos el residuo de dividir sec / 60 (es lo que el operador % hace) y lo guardamos
en la misma variable. En este paso sí modificamos la variable sec, ahora contiene los
segundos iniciales menos las horas menos los minutos.
Ahora, si somos de los que nos preocupamos por el lenguaje, veremos que a veces hay
errores de ortografía como “1 minutos”. Para solucionar eso sólo necesitamos unos cuantos
ifs:
#include <iostream>
using namespace std;
int main()
{
int sec, hr, min;
cout << "Introduce los segundos: "; cin >> sec;
cout << sec << " segundos son ";
hr = sec / (60*60);
sec %= 60*60;
min = sec / 60;
sec %= 60;
cout << hr << " hora";
if(hr != 1) cout << "s";
cout << " " << min << " minuto";
if(min != 1) cout << "s";
cout << " y " << sec << " segundo";
if(sec != 1) cout << "s";
}
+ Suma
- Resta
* Multiplicación
/ División
% Módulo (residuo de la división)
Otros son los lógicos (&&, ||), los relacionales (<, >, !=, ==), etc. Pero en este post, como
dice el título, vamos a ver los operadores compuestos en c++.
¿Cómo haríamos para sumarle a una variable int, por ejemplo, 3 unidades? Alguien que nunca
hubiera programado escribiría algo así:
mivar + 3;
Sabemos que eso no es válido porque una suma retorna un valor (el resultado) y ese valor
tiene que ser almacenado en una variable. En el código anterior ese valor no se almacena en
ninguna variable, por lo tanto ERROR. Sabiendo esto último podemos escribir esto:
mivar = mivar + 3;
En la variable mivar, guardamos el contenido de esa misma variable más tres. Todo bien ¿no?
eso es perfectamente válido y normal, sin embargo los operadores compuestos nos permiten
hacer lo mismo con menos código:
mivar += 3;
Bueno, para ver un poco de la utilidad de estos operadores y haciéndole un favor a un tal
Víctor, vamos a ver un programa que imprima los múltiplos de un cierto número (introducido
por el usuario) que haya desde 1 hasta otro cierto número (introducido por el usuario):
#include<iostream>
using namespace std;
int main()
{
int num, lims, m=0;
cout << "Numero?: "; cin >> num;
cout << "Limite superior?: "; cin >> lims;
while(lims >= (m+=num))
{
cout << m << ", ";
}
}
Primero pedimos el número del cual queremos obtener múltiplos (num), luego el límite
superior (lims). m obtendrá el valor de los múltiplos y lo tenemos que igualar a 0 al inicio.
Luego tenemos un ciclo while. En español dice: “Me mantendré ejecutando mientras el lims
sea mayor o igual a m más num“. Dentro del ciclo mostramos la variable m.
Aquí podría poner un otro programa aún más útil para usar los operadores compuestos, pero
mejor lo dejo para el siguiente post. Ah y si tú eres Víctor, entonces tal vez te interese este
post: Cómo contar el número de veces que sucede algo.
Una función, como les decía, puede hacer (o no) dos cosas: 1 – Recibir datos y 2 – Retornar
datos. De esto surgen los cuatro tipos de funciones:
1. No reciben ni retornan
2. Reciben y no retornan
3. No reciben y retornan
4. Reciben y retornan
Vamos a hacer un programa que sume dos números, usando los cuatro tipos de funciones:
No reciben ni retornan
Las más sencillas. Para usarlas sólo tenemos que saber cómo crearlas y cómo llamarlas. Una
función se crea de esta forma general:
tipo nombre(){}
El ‘tipo’ se refiere al tipo de dato (int, float, void, char) y en las funciones que no retornan
siempre es void.
El ‘nombre’ es el nombre de la función: cualquiera que empiece con una letra, que sea
significativo y que no sea una palabra reservada.
Para llamarlas sólo hay que escribir el nombre de la función seguido de sus paréntesis y un
punto y coma (;).
nombre();
void sumar()
{
int num1, num2, r;
cout << "Numero 1: "; cin >> num1;
cout << "Numero 2: "; cin >> num2;
r = num1 + num2;
cout << "La suma es " << r;
}
int main()
{
sumar();
}
Como ven, todo lo que habríamos puesto en nuestro main mejor los pusimos en una función y
desde el main la llamamos. Una función siempre, siempre, siempre tiene que ir antes del
main.
Una función de este tipo que hemos usado muchas veces es getch();
Reciben y No Retornan
¿Cómo haríamos para pedir los dos números en el main y que la función haga la suma? Para
eso tenemos que hacer una función capaz de recibir datos, entonces la sintaxis cambia un
poco:
tipo nombre(tipo_var1 nombre_var1, tipo_var2 nombre_var2){}
Si queremos recibir una variable hasta ahí es suficiente, si queremos otra variable ponemos
una coma (,) y declaramos la siguiente variable.
Para llamar la función hay que poner las variables que vamos a enviar dentro del paréntesis
en el mismo orden en que las declaramos en la función:
nombre(var1, var2);
int main()
{
int num1, num2;
cout << "Numero 1: "; cin >> num1;
cout << "Numero 2: "; cin >> num2;
sumar(num1, num2);
}
Pedimos los dos números en el main, los enviamos a la función, ésta los suma y los muestra.
Una función de este tipo que hemos usado muchas veces es el odiado por muchos, amados
por otros, gotoxy(x,y);
Retornan y No Reciben
¿Y si ahora queremos lo contrario? Pedir los números en la función, pero mostrar el resultado
en el main. Para eso necesitamos una función que retorne.
Recibir es enviar datos del main a la función. Retornar es enviar datos de la función al main.
Para retornar datos hay que hacer dos cosas: no usar void como tipo y usar return.
De forma general:
El ‘tipo’ tiene que ser del tipo de variable que queremos retornar, si nuestra variable
retorna una variable int, pues el tipo de la función es int.
Para indicar qué variable estamos retornando usaremos la palabra return seguido de la
variable. Usualmente esto va al final de la función.
Para llamar a la función hay que preparar un colchón en donde caiga la variable que está
retornando.
var = nombre();
La variable que está retornando nuestra función se va a almacenar en la variable ‘var’. Este
es un buen momento para recordarles que las variables declaradas entre dos llaves {}
únicamente existen entre esas dos llaves. O sea que la variable ‘var’ de la función no es la
misma que la variable ‘var’ de la función; sin embargo la var del main está adquiriendo el
valor de la var del main. Un poco confuso lo sé, no se preocupen.
int sumar()
{
int num1, num2, r;
cout << "Numero 1: "; cin >> num1;
cout << "Numero 2: "; cin >> num2;
r = num1 + num2;
return r;
}
int main()
{
int r;
r = sumar();
cout << "La suma es " << r;
}
Reciben y Retornan
Ahora queremos que nuestra función únicamente sume, el main se va a encargar de pedir los
números y sumar los resultados. Para eso necesitamos que nuestra función reciba las
variables y además retorne el resultado. ¡Wow! ¿Es acaso eso posible? Claro que sí.
Es sólo cuestión de combinar las funciones que reciben y no retornan con las que retornan y
no reciben.
int main()
{
int num1, num2, r;
cout << "Numero 1: "; cin >> num1;
cout << "Numero 2: "; cin >> num2;
r = sumar(num1, num2);
cout << "La suma es " << r;
}
Las funciones de la librería math.h son en su mayoría de este tipo. sqrt(); pow(); sin();
En principio puede parecer que las funciones sirven únicamente para organizar el código, lo
cual es cierto, pero no sólo eso. ¿Se imaginan si tuviéramos que escribir todo el código detrás
de un simple gotoxy();? Ah verdad…
int main()
{
int num1, num2;
cout << "Numero 1: "; cin >> num1;
cout << "Numero 2: "; cin >> num2;
cout << "La suma es " << sumar(num1, num2);
}
:D
Funciones en C++
Supongo que ya es hora de retomar el blog y ponerme a hablar de funciones en c++. Una
función es un pedazo de código fuera del main, con un nombre y que puede ser ‘llamado’
desde otra parte de nuestro programa.
Imagínense que están entrenando a su perro a hacerse el muertito. Cada vez que ustedes
dicen ‘muertito‘, el perro se tira de espaldas en el suelo, cierra los ojos y saca la lengua. En
programación, el contenido de la función sería tirarse de espaldas, cerrar los ojos y sacar la
lengua; el nombre de la función sería muertito; y cada vez que nosotros decimos muertito
estamos llamando a la función.
Jajaja, bueno, bueno. Ya en serio vamos a hacer un clásico Hola Mundo pero usando una
función:
#include<iostream>
using namespace std;
void hola()
{
cout << "Hola Mundo!";
}
int main()
{
hola();
}
Como ven, esta función es muy estúpida. No nos beneficia en nada y nos hace escribir más
código del necesario, pero nos sirve para ver cómo actúa una función: al momento de llamar
a la función, el compilador se brinca a la función, la ejecuta y cuando termina, vuelve al
punto desde donde brincó.
int main()
{
char nombre[50];
cout << "Cual es tu nombre?: "; cin.getline(nombre, 50, '\n');
hola(nombre);
}
No se preocupen, si nunca habían visto una función tal vez no entiendan la sintaxis, pero el
objetivo de este post es que sepan qué es una función y para qué se puede usar. En el
siguiente post voy a explicar la sintaxis de los cuatro tipos de funciones en c++.
int matriz[4];
fx(matriz);
Si el arreglo es de dos dimensiones…
int matriz[4][3];
… pues es lo mismo:
fx(matriz);
Si la función retorna una matriz…
int matriz[4];
… se declara normal:
matriz[4] = fx(matriz);
Este programa pide tres números, los almacena en una matriz, le suma 1 a cada elemento y
los muestra, usando para cada acción una función. Así que tenemos funciones que reciben
matrices y que retornan matrices. Chéquenlo.
#include<iostream>
using namespace std;
int main()
{
int matriz[3]={0}, len = sizeof(matriz)/sizeof(int);
pedir(matriz, len-1);
matriz[3] = sumar(matriz, len-1);
mostrar(matriz, len-1);
return 0;
}
A mi parecer, para graficar por ejemplo la función seno, hacen falta 3 pasos:
1. Hacer un ciclo de 0 a 360º (con aumentos de 5 queda muy bien) con for, algo muy normal.
2. Calcular, obviamente, el seno de cada valor. Para esto la librería math.h nos regala la
función sin(). Su uso es el obvio, pero el asunto es que todas las funciones trigonométricas
que usa c++ trabajan en radianes. Es decir que primero tendremos que convertir nuestro
ángulo en radianes y luego ya sacar el seno. Si la variable ‘i’ contiene el ángulo y tenemos ya
definida la constante PI, la función quedaría así:
sin(i/180*PI)
3. Luego viene la parte más rara, convertir ese valor en un entero que pueda meter
como coordenada en un gotoxy. Si tenemos una variable int y y la igualamos a
nuestra función anterior podría quedar bien si multiplicamos por 10:
Nos quedaría nuestra gráfica en una escala 1:10, pero al correr el programa veremos que
hay muchos valores de seno que son 10 (por el redondeo) y por lo tanto la gráfica se ve
achatada.
Para mejorar un poco eso (de todos modos queda un poco fea) podemos usar la función ceil()
incluida también en la librería math.h que nos redondea los decimales. Y esta vez
multiplicamos por 20, redondeamos, dividimos entre 2 y convertimos a int. Nos vuelve a
quedar escala 1:10 (¿o 10:1 …? no se) pero ya no hay tantas cantidades amontonadas en el 10
y -10.
El programa ya listo para graficar seno está aquí abajo, obviamente para graficar coseno sólo
hay que cambiar la función sin por cos, y copiar, pegar y hacer un menú no debe ser difícil.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define PI 3.14159265
int main()
{
int x=2, y;
for(float i=0; i<=360; i+=5)
{
y = ceil(sin(i/180*PI)*20)/2;
gotoxy(x, 12-y);printf("o");
x++;
}
getch();
return 0;
}
Calcular ángulos de un triángulo en C++
En el post anterior vimos cómo saber si un triángulo es rectángulo, acutángulo u
obtusángulo en C++, y les anticipé que haría una nueva versión del mismo programa pero
que nos calculara además los ángulos del triángulo.
El programa es este.
#include<math.h>
#include<iostream>
using namespace std;
cin.get();cin.get();
}
Para calcular los ángulos utilizamos la ley de cosenos, de hecho en el anterior también lo
utilizamos pero no completamente (la ley de cosenos es una ‘ampliación’ del teorema de
pitágoras). La ley de cosenos la vemos comúnmente como:
a2 = b2 + c2 -2(b*c)*cos(A)
A = arccos(b2 + c2 - a2 / 2(b*c))
Que es lo que utilizamos calcular los ángulos, lamentablemente la función que nos da C++ en
su librería math.h, acos() nos devuelve el resultado en radianes. Para convertirlo a grados
solo tenemos que multiplicar el resultado por 180/PI. Ahora que ya tenemos los tres ángulos
de nuestro triángulo, es facilísimo saber cuándo es cada tipo de triángulo.
La función acos() está en la librería math.h y sirve para encontrar el arco coseno. En esta
librería hay muchas funciones muy útiles: math.h
Otro detalle sencillo pero que no habíamos visto es el asunto de PI. Al principio del programa
nos encontramos con:
#define PI 3.14159265
Esto significa que estamos declarando una constante con el nombre PI y con un valor de
3.14159265. Una constante, como su nombre lo indica, nunca cambia a lo largo del
programa.
El programa resulta bastante sencillo, pero para deducir cómo hacerlo está un poco
complicado. Veamos la siguiente imagen:
El triángulo 1 es un clásico triángulo rectángulo. Si aumentáramos el lado c de 5 a 6
obviamente el ángulo aumentaría y por lo tanto sería un triángulo obtusángulo (2). Si por el
contrario, disminuyéramos el lado de c 5 a 4, el ángulo disminuiría y por lo tanto sería un
triángulo acutángulo (3).
Sabiendo esto veamos cómo se comporta Pitágoras en cada caso (o sea no él, su teorema):
32 + 42 - 52 = 0
¡Listo!, ya sabemos que el triángulo es rectángulo, porque el teorema de Pitágoras sólo sirve
para triángulos rectángulos.
Ahora con el triángulo 2 (obtusángulo):
32 + 42 - 62 = -11
¡Un número negativo! Con los triángulos obtusángulos el teorema de Pitágoras da números
negativos.
Y por último el triángulo 3 (acutángulo):
32 + 42 - 42 = 9
¡Un número positivo! Con los triángulos acutángulos el teorema de Pitágoras da números
positivos.
Ahora que ya sabemos cómo identificar cada triángulo nos surge otro problema: El usuario
sólo va a introducir tres lados cualquiera, ¿cómo saber cual es a, cual es b y cual es c? Pues
no hay forma de saberlo, hay que hacer cada paso tres veces tomando el teorema como a 2 +
b2 – c2, luego a2 + c2 – b2 y al final b2 + c2 – a2.
int main()
{
int a, b, c, A, B, C;
cout << "Introduce lado 1: "; cin >> a;
cout << "Introduce lado 2: "; cin >> b;
cout << "Introduce lado 3: "; cin >> c;
A = (b*b+c*c-a*a);
B = (a*a+c*c-b*b);
C = (a*a+b*b-c*c);
if(A == 0 || B == 0 || C == 0)
cout << "El triangulo es rectangulo. ";
if(A > 0 && B > 0 && C > 0)
cout << "El triangulo es acutangulo. ";
if(A < 0 || B < 0 || C < 0)
cout << "El triangulo es obtusangulo. ";
¿Cómo ven el programita? Está sencillo ¿no? Tal vez después haga una modificación para que
además te calcule los ángulos del triángulo.
Para esto vamos a usar una variable tipo int (entero) que va a ir aumentando una unidad
cada vez que ocurra ese ‘algo’ que queremos contar. Veamos como funcionaría un contador
dentro de un ciclo:
#include<iostream>
using namespace std;
int main()
{
int contador=0;
for(int i=0; i<10; i++)
contador++;
cout << contador;
}
Obviamente esto muestra un 10 en pantalla. Porque la variable ‘contador’ aumenta una
unidad cada vez que el ciclo da una vuelta.
int main()
{
int contador=0;
for(int i=0; i<10; i++)
{
if(i==5)
contador++;
}
cout << contador;
}
Esto obviamente muestra en pantalla un 1, porque solo una vez i vale 5. Ahora con una
condición más complicada:
#include<iostream>
using namespace std;
int main()
{
int contador=0;
for(int i=0; i<10; i++)
{
if(i%2==0)
contador++;
}
cout << contador;
}
Con el operador % se obtiene el residuo de la división de los dos números entre los que está.
Si la condición es que i/2 tenga residuo un de 0, significa que estamos dejando pasar sólo los
números pares, por lo que deberá mostrarse en pantalla un 5.
Qué fácil no?, ahora nuestro amigo ya tiene todo lo necesario para armar su programa.
delay(variable_tipo_int);
es decir:
int secs=10;
delay(secs);
delay(numero_entero);
es decir:
delay(12);
int main()
{
int sec;
cout << "Segundos a pausar?: "; cin >> sec;
delay(sec);
}
Para poder usar la función delay de esta forma es necesario ponerla en todos los programas
en donde necesitemos usarla (ahora me doy cuenta que no he escrito mucho sobre
funciones) e incluir siempre la librería #include<time.h> o #include<ctime>.
Teniendo esto claro, es muy fácil generar un números aleatorios (que representas letras)
para llenar cada elemento del arreglo que es nuestro string. Veamos:
#include<stdlib.h>
#include<time.h>
#include<iostream>
using namespace std;
int main()
{
char strrnd[10];
srand(time(NULL));
for(int i=0; i <= 9; i++)
strrnd[i] = 33 + rand() % (126 - 33);
cout << strrnd;
cin.get();
}
Si tienen duda con los números aleatorios pueden checar este post: Obtener número
aleatorios en c++. Aquí pueden ver el código ASCII.
Si quieren que muestre, por ejemplo, solo letras minúsculas, tendrían que modificar la
fórmula del random para que generara números entre el 97 y 122.
Así que ya saben, si no quieren desperdiciar tiempo, sólo chequen el blog cada tres días o
suscríbanse por mail o por feed (allá en la sidebar están los links, soy un flojo).
Esto es muy sencillo si usamos la función cin.getline(); Esta función necesita tres datos o
parámetros:
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í:
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();
}
El caso es que para obtener el triángulo de pascal en c++ hay muchas formas, pero la que
está a continuación yo la considero especial porque está basada en su propia definición.
#include<iostream>
using namespace std;
int factorial(int n)
{
if(n<2)
return 1;
else
return n * factorial(n-1);
}
int main()
{
for(int i=0; i<=6; i++)
{
for(int ii=0; ii<=i; ii++)
cout << combinacion(i, ii) << " ";
cout << endl;
}
return 0;
}
Vamos analizándolo:
C(n,r) = n! / r!(n-r)!
Y pues así es, el que me diga que no tiene forma de triángulo está ciego, porque si es
triángulo, lo que pasa es que no es isósceles.
Pues mi primera respuesta es no. Pero hay una forma muy burda de aproximarse a él. El
siguiente programa es para calcular si un número es primo o no sin ciclos y es infalible
hasta el 168, a partir de ahí puede que le atine o puede que no.
#include<iostream>
using namespace std;
int main()
{
int n;
cout << "Introduce un numero: "; cin >> n;
if(n!=2 & n%2==0)
cout << "No es primo";
else
{
if(n!=3 & n%3==0)
cout << "No es primo";
else
{
if(n!=5 & n%5==0)
cout << "No es primo";
else
{
if(n!=7 & n%7==0)
cout << "No es primo";
else
{
if(n!=11 & n%11==0)
cout << "No es primo";
else
{
cout << "Es primo";
}
}
}
}
}
}
Con eso obtenemos un buen número de números en los que estamos seguros que no
fallaremos. Si agregamos el 13, agrandamos esa cantidad; y aún mas con el 17, el 19, …
como en esta versión optimizada, que tiene su primer error con el 1681 (que no es primo)
#include<iostream>
using namespace std;
int main()
{
int n;
cout << "Introduce un numero: "; cin >> n;
if((n!=2 & n%2==0)||(n!=3 & n%3==0)||(n!=5 & n%5==0)||(n!=7 & n%7==0)||
(n!=11 & n%11==0)||(n!=13 & n%13==0)||(n!=17 & n%17==0)||(n!=19 & n
%19==0)||
(n!=23 & n%23==0)||(n!=29 & n%29==0)||(n!=31 & n%31==0)||(n!=37 & n
%37==0))
cout << "No es primo";
else
cout << "Es primo";
}
Pero pues de eso no se trata, los ciclos son para evitar las cantidades interminables de ifs,
así que usémoslos.
Si llegaste aquí buscando un programa para saber si un número es primo o no, sigue el link
que está al principio del post.
Introducción a string.h
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..
…y mostrarla
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;
}
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.
Bueno, usando gotoxy sería mas fácil, pero este blog promueve el no uso de la librería
conio.h (Cómo dejar de usar conio.h) así que lo vamos a hacer como les dije.
#include<iostream>
#include<string.h>
using namespace std;
int main()
{
char str[100];
cout << "Una frase: "; cin.getline(str, 100, '\n');
int numofch = strlen(str);
for(int i=1; i<(40-(numofch/2)); i++)
cout << " ";
cout << str;
cin.get();
return 0;
}
A la consola le caben 80 caracteres a lo largo, su mitad son 40; enseguida tenemos que
averiguar el numero de caracteres que tiene la frase que se acaba de introducir y dividirlo
entre dos. Supongamos que la frase es “hola”:
Si quieren utilizar gotoxy, el proceso es el mismo hasta el último paso, donde guardarían el
valor obtenido en una variable y luego lo pondrían en el lugar adecuado de la función.
La función strlen está en la librería string.h y nos devuelve el número de caracteres que
tiene una cadena, viene de string length.
A propósito me he dado cuenta que no he hablado casi nada de la librería string.h, voy a ver
si hago unos cuantos posts sobre ella.
int i=0;
for(i=0; i<=10; i++)
{
printf("%i", i);
}
…que esto:
int main()
{
int num,fact=1;
cout << "::FACTORIAL::" << endl;
cout << "Introduce un numero: "; cin >> num;
for(int i=2; i<=num; i++)
{
fact = fact * i;
}
cout << "Su factorial es: " << fact;
cin.get();cin.get();
return 0;
}
Otro algoritmo raro. Lo que sabemos es que si tenemos 1 disco el número de movimientos es
1 y que ese es nuestro caso base (si n==1 retorna 1), a partir de ahí el número de
movimientos se puede calcular si multiplicamos por dos el número de movimientos para n-1 y
le sumamos 1, o sea: 2 + hanoi(n-1) + 1
Este es uno de esos algoritmos recursivos raros o, mejor dicho, difíciles de comprender, mi
cerebro estuvo un buen rato echando humo tratando de comprender la lógica con que lo
armaron y mi conclusión es que funciona de pura rana. Bueno, al final si supe como funciona
pero no porque.
Recursividad aplicada: Serie de Fibonacci
0, 1, 1, 2, 3, 5, 8, 13, 21, …, la serie de Fibonacci es bastante interesante e incluso aparece
en la naturaleza. Comienza con un 0, luego un 1 y a partir de ahí cada número es la suma de
los dos siguientes. Eso último nos indica recursividad. Veamos como mostrar n números de la
serie de Fibonacci de forma recursiva en C++.
#include<stdio.h>
int fibonacci(int n)
{
if (n<2)
return n;
else
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
int num=0,res=0;
printf("::NUMEROS DE FIBONACCI::\n");
printf("Introduce el numero de numeros: ");scanf("%i",&num);
printf("\t");
for(int i=0;i<=num-1;i++)
{
res = fibonacci(i);
printf("%i ", res);
}
printf("\n");
return 0;
}
Es la primera vez que vemos un la llamada a la función dentro de un ciclo. Eso es porque la
función calcula el n-ésimo número de la serie, y para mostrarlos todos tenemos que hacer un
ciclo que repita la función tantas veces como sea necesario.
Está basado en el método que usamos para convertir un número decimal a binario “a mano”:
dividir el número entre dos hasta que quede 0 y apuntar los residuos del último al primero.
Explicación
El caso base es que cuando n valga 1 o 0 retorna un 1, de lo contrario retorna la
multiplicación de n * el factorial del numero anterior n-1. Supongamos que introducimos el
número 3, cuyo factorial es 6 (3*2*1 = 6).
#include<stdlib.h>
srand(time(NULL));
*Actualización: No se porqué con algunos IDE’s tira error con la función time. Solo hay que
utilizar además la librería time.h:
#include<time.h>
Luego guardar el número aleatorio en alguna parte:
num=rand();
Eso es básicamente. Para ajustar el rango de número aleatorios podemos hacer varias
cosas.
num=rand()%51;
num=1+rand()%(101-1);
num=250+rand()%(421-250);
Así que un programa que muestre 10 números aleatorios entre 1 y 10 quedaría así:
#include<stdlib.h>
#include<iostream>
using namespace std;
int main()
{
int num,c;
srand(time(NULL));
for(c=1;c<=10;c++)
{
num=1+rand()%(11-1);
cout<<num<<" ";
}
cin.get();
}
51-60 ***
61-70 **
71-80 ***
80-91 *
91-mas *****
int main()
{
int n,c,c2,peso[500],cat[5]={0},lim;
// n -> numero de personas
// c y c2 para ciclos
// peso[500] arreglo para guardar el peso de las personas
// cat[5] arreglo para guardar el número de personas en cada categoria de
peso
srand(time(NULL)); // Inicializa los números aleatorios
cout<<"Introduce el número de personas: ";cin>>n;
for(c=0;c<=n-1;c++)
{
peso[c]=51+rand()%(120-51); //guarda un número aleatorio del 51 al 120 en
cada elemento del arreglo
// según su valor se aumenta un elemento de nuestro otro arreglo
if(peso[c]>50 && peso[c]<=60)
cat[0]++;
if(peso[c]>60 && peso[c]<=70)
cat[1]++;
if(peso[c]>70 && peso[c]<=80)
cat[2]++;
if(peso[c]>80 && peso[c]<=90)
cat[3]++;
if(peso[c]>90)
cat[4]++;
}
cout<<"\n";
for(c=0;c<=4;c++)
{
switch(c)
{
// segun cada caso imprime algo diferente
case 0:
cout<<"51-60\t";
break;
case 1:
cout<<"61-70\t";
break;
case 2:
cout<<"71-80\t";
break;
case 3:
cout<<"81-90\t";
break;
case 4:
cout<<"90- \t";
break;
}
lim=cat[c]; // no podemos usar un arreglo como limite del ciclo (la
verdad
// no se porque), entonces lo pasamos a una variable normal
for(c2=1;c2<=lim;c2++)
cout<<"*";
cout<<"\n\n";
}
cin.get();cin.get(); // detiene la ejecución al final (es como getch();)
}
int main()
{
char cadena[50],cadenaf[50]={0},*parte;
int c,len,pal=0;
cout<<"Introduce un palíndromo: "; cin.getline(cadena,50,'\n');
parte=strtok(cadena," "); //
strcat(cadenaf,parte); // quita los espacios de 'cadena' y
while((parte=strtok(NULL," ")) != NULL) // guarda el resultado en 'cadenaf'
strcat(cadenaf,parte); //
len=strlen(cadenaf);
for(c=0;c<=len-1;c++)
{
if(cadenaf[len-1-c]==cadenaf[c]) // comparación del primer caracter con el
pal++; // último, el segundo con el penúltimo, etc
}
if(pal==len) // si todos las caracteres coinciden, sí es palíndromo
cout<<"Sí es palíndromo!";
else
cout<<"No es palíndromo";
cin.get();
}
/*Creado por THEbatzuk*/
int ordenar(int[],int);
int imprimir(int[]);
int main()
{
int c,lista[9],ord;
for(c=0;c<=9;c++)
{
cout<<"Numero "<<c+1<<": "; cin>>lista[c];
}
cout<<"\nAscendente 1\nDescendente 2\n--> Opción: "; cin>>ord;
if(ord==1 || ord==2)
{
ordenar(lista,ord);
imprimir(lista);
}
}
int main()
{
char frase[100], *parte, frasef[100]={0};
int lng,spc=0;
cout<<"Introduce una frase: "; cin.getline(frase, 100, '\n');
parte=strtok(frase," ");
strcat(frasef,parte);
while((parte=strtok(NULL," ")) != NULL)
{
strcat(frasef,parte);
spc++;
}
lng=strlen(frasef);
cout<<"Tu frase tiene "<<lng<<" letras y "<<spc<<" espacios";
cin.get();cin.get();
return 0;
}
/*Creado por THEbatzuk*/
int main()
{
int num,c,res,nc=0;
cout<<"Introduce un número: "; cin>>num;
for(c=1;c<=num;c++)
{
res=num%c;
if(res==0)
nc++;
if(nc>2)
break;
}
if(nc==2)
cout<<"Es primo";
else
cout<<"No es primo";
cin.get();cin.get();
}
En sí, es lo mismo que el anterior. Para darle mas presentación podemos hacer que no se
salga a la primera, sino hasta que se introduzca, por ejemplo, un cero. Esto se hace con un
ciclo do while.
#include<iostream>
using namespace std;
int main()
{
int num=1,c,res,nc=0,rep=0;
while(num!=0)
{
cout<<"Introduce un número: ";
if(rep==1)
{
cout<<" --> Para salir oprime cero: ";
}
rep++;
cin>>num;
for(c=1;c<=num;c++)
{
res=num%c;
if(res==0)
nc++;
}
if(nc==2)
cout<<"Es primo\n\n";
else
cout<<"No es primo\n\n";
nc=0;
}
}
int main()
{
int n=0,c=0,c2=0,res=0,nc=0;
cout<<"Introduce el limite de numeros: "; cin>>n;
for(c=1;c<=n;c++)
{
for(c2=1;c2<=c;c2++)
{
res=c%c2;
if(res==0)
{
nc=nc+1;
}
}
if(nc==2)
{
cout<<" "<<c;
}
nc=0;
}
}
El operador % obtiene el residuo de la división de dos números. Por ejemplo:
10 % 3 = 1
Explicación:
1. El primer ciclo lleva la cuenta de los números de 1 a n de uno por uno en la
variable c
2. Luego se inicia un ciclo de 1 a c en la variable c2. Este ciclo se hará n veces
porque está dentro de el primer ciclo
3. En la variable res se guarda el residuo de dividir c / c2
4. Si el residuo es cero, se incremento al contador nc
5. Si al terminarse el segundo ciclo el contador nc es igual a 2, significa que el
número es primo y lo imprime
Recuerden que los números primos son los que únicamente se dividen (sin dejar residuo)
entre 1 y entre si mismos
int main()
{
int n_num=0,num=0,elmayor=0,c=0;
cout <<"Introduce el numero de numeros: "; cin >> n_num;
for(c=1;c<=n_num;c++)
{
cout <<"\nIntroduce el numero " << c <<": "; cin >> num;
if(num>elmayor)
{
elmayor=num;
}
}
cout <<"\n\tEl numero mayor fue el " << elmayor;
cin.get();cin.get();
return 0;
}
Una parte importante es la estructura del ciclo:
for(c=1;c<=n_num;c++)
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;
}
En este caso necesitamos usar dos cin.get para detener el programa. Esto se debe al uso de
cin.
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.
“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.”
¿Qué pasa si no ponemos ni inicio ni fin? Pues obtenemos un ciclo infinito, así:
for(;;)
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.
Programa: Porcentaje de Hombres y Mujeres
Supongamos que nos preguntan qué porcentaje de hombres y qué porcentaje de mujeres
hay un salón de clases. Lo primero que tenemos que hacer es preguntar el total de personas
que hay, luego hacer un ciclo que en cada iteración pregunte el sexo de cada alumno. En
base a esos datos se calculan los porcentajes.
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.
¿Y como para qué? Pues hay algunas situaciones que así lo requieren. Por ejemplo:
Seguir leyendo…
int main()
{
int x=0;
for(x=1;x<=80;x++)
{
gotoxy(x,1);printf(".");
gotoxy(x,22);printf(".");
gotoxy(4,23);printf("Nombre: Programa: Numero: ");
gotoxy(x,24);printf(".");
if(x<=24)
{
gotoxy(1,x);printf(".");
gotoxy(80,x);printf(".");
}
}
getch();
}
Modifíquenlo, échenle imaginación. Yo use puntos (.), pero ustedes pueden usar cualquier
otro caracter.
int main() {
int ascii=0,col=1,ren=1;
for(ascii=1;ascii<=256;ascii++) {
gotoxy(col,ren);printf("%i: %c ",ascii,ascii);
if(ren==24) { ren=0; col+=12; }
if(col>=80) { getch(); clrscr(); ren=0; col=1; }
ren++;
}
getch();
}
Variables:
Cuando ren==24, los renglones comienzan en cero de nuevo y se empieza en una nueva
columna; cuando col>=80, se detiene el transcurso del ciclo, luego se limpia la pantalla y se
reinician los renglones y las columnas.
La pantalla de C++, tiene 24 renglones y 80 columnas, por lo que los valores que le pongamos
a nuestro gotoxy no deberán pasar de esos valores.
Así, si queremos que un mensaje salga en la parte inferior de la pantalla, nuestro programa
sería el siguiente:
#include<stdio.h>
#include<conio.h>
int main() {
gotoxy(5,24);printf("Hola mundo");
getch();
}
Como ven, necesitamos una variable exclusiva para el ciclo (en este caso ‘x’) y éste empieza
con la palabra for, su sintáxis es la siguiente:
Por partes:
x=0 -> Indica el inicio del ciclo. Puede ser cualquier variable y cualquier valor
de inicio.
x<=5 ->Indica el fin del ciclo. Cuando la condición deja de cumplirse el ciclo
termina. Cuando el ciclo no es menor o igual a 5 el ciclo termina.
x++ -> Indica que la variable ‘x’ aumenta de uno en uno. Para aumentar de dos
en dos: x+=2, de tres: x+=3.
Como les dije en el programa anterior (¿Aprobó o no aprobó?), los ciclos son algo que un
buen programador debe tener muy bien dominado. Pero…
¿Qué es un ciclo?
Un ciclo, aquí y en China, es algo que se repite constantemente. Por ejemplo:
Si vamos a la papelería y sacamos 5 copias de una hoja, cada vez que se imprime
una hoja se completa un ciclo y se repite hasta completar las cinco repeticiones
Si saben algo de guitarra, abran oído del ‘círculo de sol’; son cuatro acordes que
se repiten constantemente a lo largo de una canción, cada vez que tocas los cuatro
acordes se completa un ciclo
Si ponen un CD de música en un reproductor, cada vez que suenen todas las
canciones del disco se completa un ciclo
{
imprimir
}
tocar Sol
tocar Mi menor
tocar La menor
tocar Re 7
Para tocar CD
{
tocar canción x
Los primeros dos están muy fáciles de entender: las acciones dentro de las llaves {} se
repiten determinado número de veces y ese valor puede ser constante (como las copias) o
variable (como el fin de la canción). El tercer ejemplo tiene algo complicado, pero que es la
‘escencia’ de los ciclos.
tocar canción 1
tocar canción 2
tocar canción 3
tocar canción 4
tocar canción 5
O así:
Como el promedio puede ser una valor con decimales, tenemos que declarar las variables
como tipo float.
#include<stdio.h>
#include<conio.h>
int main()
{
float calif_1=0,calif_2=0,calif_3=0,promedio=0;
printf("\nIntroduce tu primera calificacion: ");scanf("%f",&calif_1);
printf("\nIntroduce tu segunda calificacion: ");scanf("%f",&calif_2);
printf("\nIntroduce tu tercera calificacion: ");scanf("%f",&calif_3);
promedio=(calif_1+calif_2+calif_3)/3;
if(promedio<6)
{
printf("\n\tLo siento, tu promedio de %.2f no es aprobatorio",promedio);
}
else
{
printf("\n\tFelicidades, pasaste con un %.2f",promedio);
}
getch();
}
Aquí estamos asumiendo que la calificación mínima aprobatoria es de 6, pero ¿y si quiero que
este dato también sea variable? Entonces el programa quedaría así:
Seguir leyendo…
Para esto vamos a usar condiciones en C++ para comparar los lados de nuestro triángulo.
Un tríangulo equilátero tiene sus tres lados iguales, por tanto, la condición quedaría así:
Un tríangulo isósceles tiene solo dos lados iguales, por tanto, la condición quedaría así:
Un tríangulo escaleno tiene sus tres lados diferentes, por tanto, la condición quedaría así:
//Hacer comparaciones
if(lado1==lado2 && lado2==lado3)
{ printf("\n\tEs equilatero"); }
if(lado1==lado2 && lado2!=lado3 || lado2==lado3 && lado3!=lado1 || lado3==lado1
&& lado1!=lado2)
{ printf("\n\tEs isosceles"); }
if(lado1!=lado2 && lado2!=lado3 && lado3!=lado1)
{ printf("\n\tEs escaleno"); }
//Pausa
getch();
}
Es un software excelente, muy actual, con una buena interfaz y funciona a la perfección. El
único problema es que no podremos usar la librería <conio.h> (porque es propiedad de
Borland) a menos que sigamos las siguientes instrucciones: conio en Dev-C++.
Ya por último les pongo la captura de pantalla de Dev-C++ con lo básico que debrían de
saber:
Condiciones (decisiones) en C++ – if, else
¿Cómo harían para saber si alguien es mayor o menor de edad? Creo que los pasos serían:
1. Preguntarle su edad
2. Si tiene 18 o más entonces es mayor de edad
3. Si no, es menor de edad
1. scanf(“%d”, &edad);
2. if(edad>=18) { printf(“Es mayor de edad”); }
3. else { printf(“Es menor de edad”); }
if significa si y else significa si no
edad>=18 es una comparación. Si la variable ‘edad’ es mayor o igual a 18, se hacen las
instrucciones que están entre las llaves {} del if; si no es así, se realizan las instrucciones
que están entre las llaves del else.
Un if no tiene que tener un else ‘a fuerzas’, es opcional. Es muy importante que se fijen muy
bien en las llaves, cada if tiene su llave de apertura y de cierre, al igual que el else.
Ejemplo:
#include<stdio.h>
#include<conio.h>
int main()
{
int edad=0;
printf("Cual es tu edad? ");scanf("%d",&edad);
printf("Tu tienes %d anios", edad);
getch();
}
El scanf() guarda en la variable indicada todo lo que introduzcas desde el teclado hasta que
oprimas ‘enter’. Su sintáxis tiene que ser exacta:
Bueno, talvéz los operadores de igual (==) y diferente (!=) no los hayan visto escritos así,
pero en C++ así se representan.
Una expresión con operadores de relación (por ejemplo: a<b, a!=b) únicamente nos dice si la
evaluación es verdadera (true) o falsa (false).
Sirven para relacionar dos o más operaciones lógicas. Al usar && (y), las dos operaciones
tienen que ser verdaderas para que arroje un resultado verdadero, si no, es falso. Al usar ||
(o), las dos operaciones tienen que ser falsas para que arroje un resultado falso, si no, es
verdadero.
Ejemplos
Si a=4 y b=5 entonces,
a==b es false
a>b es false
a!=b es true
a==b && a<b es false
a==b || a<b es true
Operaciones en C++
Bien, ya sabemos declarar y mostrar variables, ahora solo falta saber cómo hacer
operaciones matemáticas con ellas. Una suma sería así:
#include<stdio.h>
#include<conio.h>
int main()
{
int num1=5, num2=10, resultado=0;
resultado=num1+num2;
printf("El resultado es: %i", resultado);
//Esto mostrará en pantalla: El resultado es: 15
getch();
}
Como ven, siempre hay que tener una variable para guardar el resultado de cualquier
operación. En algunos casos se puede usar la misma variable:
#include<stdio.h>
#include<conio.h>
int main()
{
int num1=5;
num1=num1+6;
printf("El resultado es: %i", num1);
//Esto mostrará en pantalla: El resultado es: 11
getch();
}
+ para suma
- para resta
* para multiplicación
/ para división
() también indican multiplicación
Para mostrar el valor de una variable en pantalla con printf() se usan los caracteres de
sustitución. Vean este programa:
#include<stdio.h>
#include<conio.h>
int main() //Esta es la función main, va en todos los programas
{
int numero=7; //A la variable numérica 'numero' le asignamos un valor de 7
printf("El numero es %i", numero); //Esto mostrará en pantalla: El número es 7
getch(); //Hace una pausa
}
Como ven, el valor de la variable aparece en lugar de %i, cada tipo de dato tiene su propio
caracter de sustitución.
Otros ejemplos:
#include<stdio.h>
#include<conio.h>
int main()
{
int edad=17;
float altura=1.67;
printf("Edad: %i años, altura: %f metros", edad, altura);
//Esto mostrará en pantalla: Edad: 17 años, altura: 1.670000 metros
getch();
}
%f mostrará 0.000000
%.2f mostrará 0.00
%.1f mostrará 0.0
%.f mostrará 0
Una variable no puede tener espacios, caracteres especiales (acentos, signos), tiene que
empezar con una letra.
Las variables se usan para almacenar valores que cambian dinámicamente en el transcurso
del programa.
Como declarar una variable en C++
C++ maneja varios tipos de variables: numéricas, de caracteres y boolean (cierto o falso)
esencialmente.
Para declarar una variable numérica llamada altura que inicie con un valor de 0, escribimos
esto:
int altura=0;
Para declarar una variable numérica llamada distancia que inicie con un valor de 2.67,
escribimos esto:
float distancia=2.67;
Para declarar una variable de caracter llamada inicial, con un valor de R, escribimos esto:
char inicial='R';
Para declarar una variable boolean llamada terminado, que empiece como falso, escribimos
esto:
bool terminado=false;
En resumen:
Comentarios en C++
Un comentario es una nota que puedes poner en cualquier parte de tu programa y que será
totlamente ignorada a la hora de correr el programa. Son bastante útiles para que otras
personas, o tú mismo después de algún tiempo, sepan qué hace alguna parte de tu código.
Por ejemplo:
/* Autor: Raúl Rivas
Fecha: Agosto de 2009 */
#include<stdio.h>
#include<conio.h>
int main()
{
//Aquí declaro mis variables
int numero1=10;
printf("%i",numero1); //esto mostrará: 10
getch();
}
Facil ¿no?
La primera y segunda líneas son librerías. Una librería es el lugar en dónde están
definidas cientos de funciones que utilizaremos continuamente. stdio.h y conio.h son
las librerías que vamos a estar usando continuamente.
main() es la función principal, todo el programa se desarollará a partir de ella.
Esta función está seguida de una llave de apertura ({), y al final hay una de cierre (}).
Esto significa que todo lo que está entre las llaves pertenece a main().
printf(); es una función para imprimir (mostrar) datos en pantalla. Entre
comillas escribimos lo que queremos mostrar. Está definida en stdio.h
getch(); es una función definida en conio.h que detiene la ejecución del
programa para que el usuario pueda apreciar los resultados.
Hay que tener muy presente que las funciones ‘menores’ siempre terminan con punto y
coma (;). Este símbolo marca el final de toda sentencia.
Curso de C++
¡Bienvenidos a mi curso de C++!, en realidad esto es sólo una sección del blog donde pueden
consultar una serie de posts que ya había hecho anteriormente, pero de un forma ordenada,
empezamos desde lo más básico y vamos avanzando poco a poco. Yo se que es muy fácil
darle clic a ‘Siguiente’, pero si de verdad quieren aprender no lo hagan hasta que hayan
comprendido el post y hayan hecho alguna práctica sobre ello.
Recuerden que en el curso no están todos los posts del blog, si alguna entrada les pareció
interesante pueden checar los posts relacionados (abajo de cada post) para leer otros posts
del mismo tema. Y creo que no están ordenados muy muy bien, pero creo que eso ayuda un
poco a hacer menos monótono el aprendizaje :)
Así que aquí abajo está el índice, o pueden dar clic en siguiente (aquí en la barra lateral ->)
para comenzar desde el primero; iré agregando más temas de vez en cuando.
De seguro mas uno te ha dicho: “¿C++?, eso ya está obsoleto”, pero la realidad es muy
distinta.
Imagínense que programar es como escribir. En un lenguaje de alto nivel (visual) tienes
todas las palabras del mundo pre-escritas, listas para que las agarres y las uses. En un
lenguaje de nivel medio (como c++), tienes todas las letras del alfabeto listas para que
formes la palabra que quieras. En un lenguaje de bajo nivel (ensamblador) tendrías tu mismo
que ‘hacer’ cada letra.
Cada uno tiene sus ventajas, pero la verdad es que para empezar a aprender a programar,
C++ es perfecto.
Y si todavía tienes dudas, acuérdate que sistemas operativos como Linux, Unix e incluso
Windows (anteriormente), se escriben casi por completo en C.
Cada post tendrá un programa en C++ explicado lo más detallado posible y además varias
formas de hacerlo. Posibles problemas y errores serán tomados en cuenta y los comentarios
estarán siempre abiertos para que cada quien exprese sus dudas.