Programación en C
J. Juan Meza E.
E-mail: jjme29@[Link]
jjme29@[Link] J. Juan Meza E. 1
Lenguaje C++
• B. Stroustrup, mediados de los 80, AT&T
• Paso de la programación tradicional (C) a
estilos de abstracción de datos y orientación
a objetos
• Conserva características del C y añade
nuevos conceptos
jjme29@[Link] J. Juan Meza E. 2
Lenguaje C++
Estandarización
• C con Clases
– Añade objetos a C
– Conservar la eficiencia, portabilidad, y
disponibilidad de C
• Comité ANSI X3J16, 1991
– Última versión adoptada por ISO, julio 1998
jjme29@[Link] J. Juan Meza E. 3
Lenguaje C++
Cambios con respecto a C
Añadir orientación a objetos
Mejorar la seguridad en los tipos
• 'a' es char, no int
• "a" es const char*, no char*
• f() es equivalente a f(void)
• Se pueden utilizar const int como
dimension de arrays
• Las etiquetas de estructuras (Structure tags)
son tipos (type names)
jjme29@[Link] J. Juan Meza E. 4
Lenguaje C++
Cambios con respecto a C
Mejoras en entrada/salida - IOStreams
#include<iostream.h>
using namespace std;
main()
{//begin
cout << “Hello, world” << endl;
}//end
jjme29@[Link] J. Juan Meza E. 5
Lenguaje C++
1. Introducción
2. Tipos de datos Fundamentales
3. Operadores
4. Control del flujo en los Programas
5. Tipos de Datos Compuestos
6. Programación con Funciones
7. Punteros
jjme29@[Link] J. Juan Meza E. 6
Lenguaje C++
Introducción
• Componentes de un Programa C/C++
– Sentencias
– Comentarios
– Ficheros de “include” y “fuente”
– La función main()
jjme29@[Link] J. Juan Meza E. 7
Lenguaje C++
Introducción
• Sentencias C/C++
– Las sentencias contienen
• una o mas expresiones
• llamadas a función,
• operaciones numéricas, etc.
– Terminan con un punto y coma
– Pueden abarcar mas de una línea
jjme29@[Link] J. Juan Meza E. 8
Lenguaje C++
Introducción
• Comentarios C/C++
• C++ agrega un nuevo comentario que se inicia con
dos barras (//) y que llega hasta el final de la línea.
Se pueden usar ambos estilos de comentarios, por
ejemplo para comentar bloques grandes de código :
– /* El comentario de C puede incluir // y se
puede extender sobre varias líneas */ // /* Este
es el estilo de comentarios de C++ */ hasta el
fin de línea
jjme29@[Link] J. Juan Meza E. 9
Lenguaje C++
Introducción
• Ficheros de “include” y “fuente”
– La directiva #include inserta el texto de un
fichero en el flujo de compilación antes de que
comience
– Ficheros de cabecera (.h)
• Generalmente contienen declaraciones de funciones
y definiciones de constantes
• Del sistema
– Los componentes de la biblioteca estándar tienen ficheros
de cabecera (header)
– #include <stdio.h>
• Del usuario (#ifndef .... #define ..... #endif)
– #include "mydefs.h"
– Ficheros de código fuente (.cc, .cpp)
jjme29@[Link] J. Juan Meza E. 10
Lenguaje C++
Introducción
/* first.c: A First Program */
#include <stdio.h>
int main()
{
puts("** Welcome to C/C++ **");
puts("(You'll be glad you came!)");
return 0;
}
** Welcome to C/C++ **
(You'll be glad you came!)
jjme29@[Link] J. Juan Meza E. 11
Lenguaje C++
Introducción
• Componentes de un Programa C
– Un programa C es una colección de funciones.
• procedimientos, subrutinas
• variables globales opcionales
• Puede estar escrito en un solo fichero o en varios
– Una función es una colección de sentencias
delimitadas por { llaves }
– main() es especial
jjme29@[Link] J. Juan Meza E. 12
Lenguaje C++
Introducción
• Construcción de un ejecutable C/C++
F1.h F2.h
F3.h
S1.c S2.c
[Link] [Link]
[Link]
jjme29@[Link] J. Juan Meza E. 13
Lenguaje C++
Introducción
• Módulos
– El concepto de módulo en c++ se refiere a
unidades de compilación separadas.
– Similar al concepto en C.
– El “linker” C++ es mas estricto que el de C
jjme29@[Link] J. Juan Meza E. 14
Lenguaje C/C++
Introducción
• Entrada / salida estándard en C
• Permite E/S de consola, ficheros, y
sobre canales definidos en memoria
• 3 flujos de E/S predefinidos:
– stdin“standard input” (teclado)
– stdout“standard output” (pantalla)
– stderr“standard error” (pantalla)
• Las funciones de consola utilizan
implicitamente stdin o stdout
jjme29@[Link] J. Juan Meza E. 15
Lenguaje C/C++
Introducción
#include <stdio.h>
int main()//avg.c: Promedio 2 enteros
{
/* C: Declarations must be at beginning: */
int num1, num2;
float sum;
puts("Enter the 1st number:");
scanf("%d",&num1);
puts("Enter the 2nd number:");
scanf("%d",&num2);
sum = num1 + num2;
printf("The average is %f\n", sum/2);
return 0;
}
jjme29@[Link] J. Juan Meza E. 16
Lenguaje C/C++
Resultado Introducción
Enter the 1st number: 10
Enter the 2nd number: 23
The average is 16.500000
• Si queremos solo dos decimales:
printf("The average is %.2f\n",
sum/2);
The average is 16.50
jjme29@[Link] J. Juan Meza E. 17
Lenguaje C++
Introducción
• Resumen
– Los programas pueden estar en uno o
mas ficheros de texto
– Los ficheros fuente pueden #include
uno o mas ficheros de cabecera
– Los ficheros fuente contienen una o mas
funciones
– Las funciones contienen sentencias
– 3 flujos de E/S predefinidos
jjme29@[Link] J. Juan Meza E. 18
Lenguaje C++
Tipos fundamentales
• Enteros
• Caracteres
• Números de punto flotante
• Literales y Constantes
• Aritméticas
• Conversiones y “Casts”
jjme29@[Link] J. Juan Meza E. 19
Lenguaje C++
Tipos fundamentales
• Enteros
• Distintos tamaños:
– No necesariamente distintos
– Por defecto tienen signo
• int tamaño de la palabra de la maquina (al
menos 16 bits)
• short int generalmente equivalente a int
en plataformas de 16-bit
• long int Al menos 32 bits. Generalmente
equivalente a int en plataformas de 32-bit
jjme29@[Link] J. Juan Meza E. 20
Lenguaje C++
Tipos fundamentales
• Caracteres
– Son enteros
– La codificación depende de la plataforma
– ASCII, EBCDIC, ISO 8859, Unicode
– char Al menos 8 bits (“byte”)
– wchar_t “Wide character” Generalmente
equivalente a unsigned int (Unicode)
jjme29@[Link] J. Juan Meza E. 21
Lenguaje C++
Tipos fundamentales
• Límites númericos
• Valores importantes para cada tipo
– Mínimo, máximo, etc.
• Los límites para enteros están en
– C-> <limits.h> C++ -> <climits>
• Los límites para punto flotante están en
– C-> <float.h> C++-> <cfloat>
jjme29@[Link] J. Juan Meza E. 22
Lenguaje C++
// limits.c: Límites de enteros
#include <stdio.h> Tipos fundamentales
#include <limits.h> // #include <climits>
int main()
{
printf("char: [%d, %d]\n", CHAR_MIN, CHAR_MAX);
printf("short: [%d, %d]\n", SHRT_MIN, SHRT_MAX);
printf("int: [%d, %d]\n", INT_MIN, INT_MAX);
printf("long: [%ld, %ld]\n", LONG_MIN, LONG_MAX);
return 0;
}
char: [-128, 127]
short: [-32768, 32767]
int: [-2147483648, 2147483647]
jjme29@[Link] long: J. [-2147483648,
Juan Meza E. 2147483647]
23
Lenguaje C++
Tipos fundamentales
• Números decimales
– float “Single precision”
– double “Double precision” por defecto
– long double
• Precisión extendida. Podría ser igual a double
jjme29@[Link] J. Juan Meza E. 24
Lenguaje C++
Tipos fundamentales
int main() { // Definición sin inicialización:
char proteina;
int carbohydratos;
float fibra;
double grasa;
// Definición & inicialización simultanea:
char pizza = 'A', pop = 'Z';
int numero = 100, ecos = 150, alumnos = 200;
float chocolate = 3.14159;
// Notación Exponencial:
double fudge_ripple = 6e-4; } //Se pueden
definir
// variables en cualquier
jjme29@[Link]
sitio.
J. Juan Meza E. 25
Lenguaje C++
Tipos fundamentales
• Enteros sin signo
– Cada tipo entero tiene una versión sin signo
• Palabra clave unsigned
– Se almacenan solamente números no negativos
– Se utiliza el bit de signo en la mantisa
– El valor máximo es el doble respecto a la versión con
signo
– El valor mínimo es cero
– Se suelen utilizar como índice en arrays o para
almacenar tamaños
• size_t
jjme29@[Link] J. Juan Meza E. 26
#include <iostream>
using namespace std; Lenguaje C++
int main() { Tiposunfundamentales
//Cuantos bytes ocupa ….?
char c; unsigned char cu;
int i; unsigned int iu;
short int is; short iis; // Same as short int
unsigned short int isu; unsigned short iisu;
long int il; long iil; // Same as long int
unsigned long int ilu; unsigned long iilu;
float f; double d;
long double ld;
cout << "\n char= " << sizeof(c) << "\n unsigned char = " << sizeof(cu)
<< "\n int = " << sizeof(i) << "\n unsigned int = " << sizeof(iu)
<< "\n short = " << sizeof(is) << "\n unsigned short = " <<sizeof(isu)
<< "\n long = " << sizeof(il) << "\n unsigned long = " << sizeof(ilu)
<< "\n float = " << sizeof(f) << "\n double = " << sizeof(d)
<< "\n long double = " << sizeof(ld) << endl;
jjme29@[Link] J. Juan Meza E. 27
}
Lenguaje C++
Tipos
/* Illustrates unsigned limits */fundamentales
#include <iostream>
#include <climits>
int main()
{
std::cout << "char: [0 " << UCHAR_MAX << "]\n";
std::cout << "short: [0, " << USHRT_MAX << "]\n";
std::cout << "int: [0, " << UINT_MAX << "]\n";;
std::cout << "long: [0, " << ULONG_MAX << "]\n";
return 0;
}
char: [0, 255]
short: [0, 65535]
int: [0, 4294967295]
long: [0, 4294967295]
jjme29@[Link] J. Juan Meza E. 28
Lenguaje C++
Tipos fundamentales
float.c: Illustrates floating-pt. limits */
#include <stdio.h>
#include <float.h>
int main()
{
printf("radix: %d\n", FLT_RADIX);
printf("float: %d radix digits\n", FLT_MANT_DIG);
printf("\t[%g, %g]\n", FLT_MIN, FLT_MAX);
printf("double: %d radix digits\n", DBL_MANT_DIG);
printf("\t[%g, %g]\n", DBL_MIN, DBL_MAX);
printf("long double: %d radix digits\n",
LDBL_MANT_DIG);
printf("\t[%Lg, %Lg]\n", LDBL_MIN, LDBL_MAX);
return 0;
}
jjme29@[Link] J. Juan Meza E. 29
Lenguaje C++
Tipos fundamentales
radix: 2
float: 24 radix digits
[1.17549e-38, 3.40282e+38]
double: 53 radix digits
[2.22507e-308, 1.79769e+308]
long double: 64 radix digits
[3.3621e-4932, 1.18973e+4932]
jjme29@[Link] J. Juan Meza E. 30
Lenguaje C++
Tipos fundamentales
• Distribución No-uniforme
– Densa para valores cercanos al cero
– Spaciada para valores lejanos de cero
- 0 +
jjme29@[Link] J. Juan Meza E. 31
Lenguaje C++
Tipos fundamentales
/* missing.c */
#include <stdio.h>
#include <limits.h>
main()
{
float x = ULONG_MAX; /* [Link] */
double y = ULONG_MAX;
long double z = ULONG_MAX;
printf("%f\n%f\n%Lf\n",x,y,z);
}
4294967296.000000 /* Oops! */
4294967295.000000
4294967295.000000
jjme29@[Link] J. Juan Meza E. 32
Lenguaje C++
• Literales Tipos fundamentales
int i = 9, j = 017, k = 0x7f;
char c = 'a', c2 = 97;
long n = 1234567L;
float x = 1.0F;
double y = 2.3;
long double z = 4.5L;
char string[] = "hello";
jjme29@[Link] J. Juan Meza E. 33
Lenguaje C++
Tipos fundamentales
• Caracteres Literales especiales
'\n' newline – en c++ -> endl
'\t' tab
'\0' null byte (ASCII 0)
'\\' backslash (\)
'\b' backspace
'\r' carriage return
'\f' form feed
'\ddd' octal bit pattern
jjme29@[Link] J. Juan Meza E. 34
Lenguaje C++
Constantes Tipos fundamentales
• En C/C++ => #define Pi 3.1416
• Las constantes deben ser inicializadas
– Inicializada con un literal:
• const int i = 7; //compile-time
• En C estándar existe const pero tiene diferencias con
C++. En C no se puede utilizar como dimensión de
array.
• En C++ se puede usar el modificador const para
declarar que aspectos particulares de una variable (u
objeto) sean constantes.
jjme29@[Link] J. Juan Meza E. 35
Lenguaje C++
Tipos fundamentales
• Aritmética
• Entera vs. Punto flotante
– Aritmética entera trunca cualquier fracción en el
resultado: int i = 2; int j = 3; int k = i/j; /* k
== 0! */
– Aritmética de Punto flotante tiene errores de
redondeo:
– El resultado puede no estar en el conjunto de números
representados por la máquina
– El redondeo es específico de cada plataforma
jjme29@[Link] J. Juan Meza E. 36
Lenguaje C++
Tipos fundamentales
• Promociones & Conversiones
– Todas las operaciones enteras usan int o long
– Una operación numérica asume la precisión del
operando cuyo tipo ofrezca la mayor Los operandos
con precisiones menores son automática y
temporalmente “ampliados” (o “promovidos”)
– Cuidado con las conversiones que disminuyen
precisión: Si el valor no esta en el rango del tipo de
menor precisión, el resultado es indefinido
jjme29@[Link] J. Juan Meza E. 37
Lenguaje C++
Tipos fundamentales
• Casts
– Conversiones explícitas definidas por el programador
– Preceden la expresión con el nuevo tipo entre paréntesis:
• (tipo) expresión: especifica conversión
• tipo(expresión): especifica conversión
• int i = (int)x;
• float r = float(1); // explicito tipo constructor
• char * p = (char *) 0777; //como en C si el nombre
– Para forzar la precisión de una operación, por ejemplo:
• /* Asi se mantiene la fracción: */
– float x = (float)i / j;
jjme29@[Link] J. Juan Meza E. 38
Lenguaje C++
Conversión de Tipos
int main()
{
int b = 200;
unsigned long a = (unsigned long int)b;
}
-------------------------------------------------------------
int main()
{
float a = float(200); // This is
equivalent to:
float b = (float)200;
}
jjme29@[Link] J. Juan Meza E. 39
Lenguaje C++
Conversión de Tipos
static_cast: para todas las conversiones
bien definidas
void func(int) {}
int main() {
int i = 0x7fff; // Max pos value = 32767
long l;
float f;
// (1) Typical castless conversions:
l = i;
f = i;
// Also works:
l = static_cast<long>(i);
f = static_cast<float>(i);
jjme29@[Link] J. Juan Meza E. 40
Lenguaje C++
Conversión de Tipos
// (2) Narrowing conversions:
i = l; // May lose digits
i = f; // May lose info // Says "I know," eliminates warnings:
i = static_cast<int>(l);
i = static_cast<int>(f);
char c = static_cast<char>(i);
// (3) Forcing a conversion from void* :
void* vp = &i;
// Old way produces a dangerous conversion:
float* fp = (float*)vp;
// The new way is equally dangerous:
fp = static_cast<float*>(vp);
// (4) Implicit type conversions, normally performed by the compiler:
double d = 0.0; int x = d; // Automatic type conversion
x = static_cast<int>(d); // More explicit
func(d); // Automatic type conversion
func(static_cast<int>(d)); // More explicit
}
jjme29@[Link] J. Juan Meza E. 41
Lenguaje C++
Conversión
const_cast
de Tipos
para todas las conversiones de constantes y volatile
int main() {
const int i = 0;
int* j = (int*)&i; // Deprecated form
j = const_cast<int*>(&i); // Preferred
// Can't do simultaneous additional casting:
//! long* l = const_cast<long*>(&i); // Error
volatile int k = 0;
int* u = const_cast<int*>(&k);
}
reinterpret_cast : para tipos sin ninguna relación
dynamic_cast : para jerarquias
jjme29@[Link] J. Juan Meza E. 42
Lenguaje C++
Tipos fundamentales
• Expresiones Boleanas
– Tipo bool.
– El tipo bool puede asumir dos estados:
• true o false
– Tanto bool, como true y false son palabras claves.
jjme29@[Link] J. Juan Meza E. 43
Lenguaje C++
Tipos fundamentales
• Resumen
– Los tipos fundamentales son numéricos (y bool)
• Enteros y de punto flotante
• Hay soporte para el concepto de constante
• La aritmética entera trunca las fracciones
• La aritmética de punto flotante es inexacta
• Los operandos son ampliados (precisión) si es
necesario. Conversiones implícitas.
• Se pueden realizar conversiones explícitas (“cast”)
jjme29@[Link] J. Juan Meza E. 44
Lenguaje C++
Operadores
• Matemáticos
• Relacionales
• Lógicos
• De bits
• Operadores de asignación
• Asociatividad y precedencia
jjme29@[Link] J. Juan Meza E. 45
Lenguaje C++
Operadores
• Cardinalidad de los Operadores
– Todos los operadores son unarios o
binarios
– Excepción: El operador “condicional” es
ternario:
max = x > y ? x : y;
Equivalente a:
if (x>y) max = x;
else max = y;
jjme29@[Link] J. Juan Meza E. 46
Lenguaje C++
Operadores
• Matemáticos
– Aditivos: +, -, ++, --
• i = j++; /* i = j; j = j + 1; */
• i = ++j; /* j = j + 1; i = j; */
– Multiplicativos: *, /, %
• i = 10 % 3; /* = 1 */
jjme29@[Link] J. Juan Meza E. 47
Lenguaje C++
Operadores
• Relacionales - ISO646.H
– Igualdad: ==
• if (i == j) …;
• if (i = j) …; /* error! */
– Desigualdad: != - not_eq
– Mayor: >, >=
– Menor: <, <=
jjme29@[Link] J. Juan Meza E. 48
Lenguaje C++
Operadores
• Lógicos -ISO646.H
– AND: && - and
• if (i < n && a[i] == 99) …
– OR: || - or
• if (i == 2 || i == 3) …
– NOT: ! - not
• if (!(i == 2 || i == 3)) …
– Como se evalúa una expresión && ?
– Como se evalúa una expresión || ?
jjme29@[Link] J. Juan Meza E. 49
Lenguaje C++
Operadores
• Uso del tipo bool
Elemento Uso con bool
&& || ! Usan argumentos bool y
producen resultados bool.
< > <= >= == Producen resultados bool.
!=
?: El primer operando se
convierte a bool.
if, for, while, Las expresiones condicionales
do se convierten a valores bool.
jjme29@[Link] J. Juan Meza E. 50
Lenguaje C++
Operadores
• De bits -ISO646.H
• AND: &, &= - bitand, and_eq
• OR: |, |= - bitor, or_eq
• XOR: ^, ^= - xor, xor_eq
• Complemento a 1: ~ - compl
• Desplazamiento a izquierda: <<
• Desplazamiento a derecha: >>
jjme29@[Link] J. Juan Meza E. 51
Lenguaje C++
• Operadores De bits – Ejemplo Operadores
#include <stdio.h>
int main()
{
short int n = 0x00a4; // 00000000 10100100
short int m = 0x00b7; // 00000000 10110111
printf("n & m == %04x\n", n & m);
printf("n | m == %04x\n", n | m);
printf("n ^ m == %04x\n", n ^ m);
printf("~n == %04x\n", ~n);
printf("n << 3 == %04x\n", n << 3);
printf("n >> 3 == %04x\n", n >> 3);
return 0;
}
jjme29@[Link] J. Juan Meza E. 52
Lenguaje C++
Operadores
n = 0000000010100100
m = 0000000010110111
• Operadores De bits – Resultado Ejemplo
n & m == 00a4 (0000000010100100)
n | m == 00b7 (0000000010110111)
n ^ m == 0013 (0000000000010011)
~n == ffffff5b … (1111111101011011)
n << 3 == 0520 (0000010100100000)
n >> 3 == 0014 (0000000000010100)
Con el siguiente formato descartamos
el byte mas significativo de ~n:
printf("~n == %04hx\n", ~n);
~n == ff5b
jjme29@[Link] J. Juan Meza E. 53
Lenguaje C++
• Operadores De bits Ejemplo Operadores
– Los operadores de bits desplazan el signo
#include <iostream>
#include <iomanip> /* #include <stdio.h>*/
int main()
{
unsigned int n = 0x00a4; // 0000 0000 1010 0100
int m = 0x00b7; // 0000 0000 1011 0111
long f = std::[Link](std::ios::hex);
char cf = std::[Link]('0');
std::cout << "~n == " << ~n << std::endl;
std::cout << "~m == " << ~m << std::endl;
std::cout << "(~n) >> 4 == " << std::setw(8) <<
(~n >> 4) << std::endl;
std::cout << "(~m) >> 4 == " << std::setw(8) <<
(~m >> 4) << std::endl;
/*printf("(~n) >> 4 == %08x\n", (~n) >> 4);*/
std::[Link](f);
std::[Link](cf);
return 0; ~n == ffffff5b
} ~m == ffffff48
(~n) >> 4 == 0ffffff5
jjme29@[Link]
(~m) >> 4 == fffffff4
J. Juan Meza E. 54
Lenguaje C++
Operadores
• Operadores de asignación
• La asignación se puede combinar con
otros operadores binarios:
– +=, -=, *=, /=, %=, >>=, <<=,
&=, ^=, !=
– Ejemplo
• i += 5; // i = i + 5;
jjme29@[Link] J. Juan Meza E. 55
Lenguaje C++
Operadores
• Asociatividad
• Señala el orden en el que se ejecutan las
operaciones adyacentes
• Derecha a izquierda:
– Los operadores unarios y de asignación
• i = j = k equivalente a i = (j = k)
• Izquierda a derecha:
– Todos los demás
• i + j + k equivalente a (i + j) + k
jjme29@[Link] J. Juan Meza E. 56
Lenguaje C++
Operadores
• Precedencia
• En general siguen la convención de
matemáticas
– Primero los unarios, luego multiplicativos, luego
aditivos
– Los operadores unarios tiene la mayor prioridad
– La asignación es la operación de menor prioridad
(excepto el operador coma)
– Cuidado con la prioridad en los operadores de bits!
– Ante cualquier duda utilizar paréntesis
jjme29@[Link] J. Juan Meza E. 57
Lenguaje C++ Operadores
jjme29@[Link] J. Juan Meza E. 58
Lenguaje C++
Operadores
• Resumen
– En asignaciones y operaciones algebraicas el lenguaje
lleva a cabo todas las conversiones implícitas que
faciliten el uso y sean seguras.
– El operador módulo (%) proporciona el resto de la
división entera
– El op de igualdad (equivalencia) tiene 2 signos igual
(==)
– Para contextos booleanos existe el tipo bool
– Los operadores unarios y la asignación se evalúan de
derecha a izquierda, el resto de izquierda a derecha
– Cuidado con la precedencia en los operadores de bits
jjme29@[Link] J. Juan Meza E. 59
Lenguaje C++
Operadores
• Resumen
– Operadores y sentencias
• Sentencias
– Misma sintaxis y semántica que las de C
• Operadores idem sentencias excepto:
– new, delete, delete[], ::
– <<, >>
– Sobrecarga
jjme29@[Link] J. Juan Meza E. 60
Lenguaje C++
Control del flujo en los Programas
• Programación Estructurada
• Toma de decisiones
• Repetición
• Bifurcación
jjme29@[Link] J. Juan Meza E. 61
Lenguaje C++
Control del flujo en los Programas
• Programación Estructurada
• En teoría, todo proceso se puede expresar
mediante tres construcciones:
• Secuencias de sentencias
• Selección
• Repetición
• Un número arbitrario de “flags” booleanos
• Muchos lenguajes añaden algunos tipos de
bifurcaciones directas (e.g., goto)
jjme29@[Link] J. Juan Meza E. 62
Lenguaje C++
Control del flujo en los Programas
•Toma de Decisión
• “Selección”
• if-then-else
• switch-case-default
– Caso especial de if-then-else
– Selección de un conjunto de enteros
jjme29@[Link] J. Juan Meza E. 63
Lenguaje C++
Control del flujo en los Programas
• La sentencia if
if(expresión) Las sentencias compuestas se
colocan entre {}
sentencia
if(expression)
{
if(expression) statement1
statement statement2
……
else
}
statement
jjme29@[Link] J. Juan Meza E. 64
Lenguaje C++
Control del flujo en los Programas
• La sentencia switch
• Selecciona de un conjunto de valores de tipo
entero
• Cada “case” puede delimitarse con un break; Si
no se delimita se continua en el siguiente case
• No definir variables dentro de un switch
• default es opcional y se ejecuta si no se pudo
seleccionar ningún case.
jjme29@[Link] J. Juan Meza E. 65
Lenguaje C++
Control del flujo en los Programas
switch(selector) {
case integral-value1 : statement; break;
case integral-value2 : statement; break;
case integral-value3 : statement; break;
case integral-value4 : statement; break;
case integral-value5 : statement; break;
(...)
default: statement; }
Solo funciona con valores enteros
Para selectores de otro tipo se debe utilizar if
jjme29@[Link] J. Juan Meza E. 66
Lenguaje C++
Control del flujo en los
Programas
#include <iostream>
using namespace std;
int main() {
bool quit = false; // Flag for quitting
while(quit == false) {
cout << "Seleccionar a, b, c o q para terminar: ";
char response;
cin >> response;
switch(response) {
case 'a' : cout << “Selecciono 'a'" << endl;
break;
case 'b' : cout << " Selecciono 'b'" << endl;
break;
case 'c' : cout << " Selecciono 'c'" << endl;
break;
case 'q' : cout << “Saliendo del menu" << endl;
quit = true;
break;
default : cout << "Por favor use a,b,c or q!"
<< endl;
}
}
}
jjme29@[Link] J. Juan Meza E. 67
Lenguaje C++
Control del flujo en los Programas
• Repetición: 3 tipos de bucles “loops”
while(expression do
)
statement
statement while(expressio
n);
for(initialization; conditional;
step)
statement
jjme29@[Link] J. Juan Meza E. 68
Lenguaje C++
Control del flujo en los
Programas
• While
// Contar de 1 a n
int i = 1;
while (i <= n) {
cout << i;
i += 1;
}
// versión mas compacta
int i = 1;
while (i <= n)
cout << i++;
jjme29@[Link] J. Juan Meza E. 69
Lenguaje C++
Control del flujo en los
Programas
• Do While
// Contar de 1 a n
int i = 1;
do
cout << i++;
while (i <= n);
• for
// Contar de 1 a n
for (int i = 1; i <= n; i++)
cout << i;
jjme29@[Link] J. Juan Meza E. 70
Lenguaje C++
Control del flujo en los Programas
• Bifurcaciones
break provoca la salida del bucle mas interno o de
switch
continue provoca el comienzo de la siguiente
iteración
goto provoca un salto incondicional a una etiqueta
(:etiqueta). Útil para salir de bucles o switchs
anidados
do while(expression)
statement statement
while(expression);
for(initialization; conditional; step)
statement
jjme29@[Link] J. Juan Meza E. 71
Lenguaje C++
Control del flujo en los Programas
• Bifurcaciones
//Buscar el primer numero impar cuyos dígitos sumen 7.
#include <iostream> //suponer números de 2 cifras
const int SIZE = 5;
int main() {
int nums[SIZE] = {10,21,32,43,54};
for (int i = 0; i < SIZE; ++i){
int dig1, dig2;
if (nums[i]%2 == 0)
continue; // saltamos los números pares
dig2 = nums[i]%10;
dig1 = nums[i]/10;
if (dig1 + dig2 == 7) {
cout << "found“ << endl << nums[i]; // 43
break;// se encontró el primero
}
}
return 0;
}
jjme29@[Link] J. Juan Meza E. 72
Lenguaje C++
Control del flujo en los Programas
• Resumen
• Todos los algoritmos se pueden expresar
con sentencias simples, decisiones, y bucles
(loops)
– Mas algunos “flags”
• Minimizar el uso de bifurcaciones
• Los loops mas habituales son while o for
– Casi siempre se hace primero la comprobación
de la condición
jjme29@[Link] J. Juan Meza E. 73
Lenguaje C++
Tipos de Datos Compuestos
• Enumerados
• Arrays
• Strings
• Structures
jjme29@[Link] J. Juan Meza E. 74
Lenguaje C++
• Enumerados Tipos de Datos Compuestos
– Colocar nombres a números
– Facilita la lectura del código
enum status {error, ok, …..};
• error es la etiqueta asignada a cero, ok la de 1, ….
• Útil para operaciones de selección entre varias opciones
enum status {error = 10, ok, ……};
• error es la etiqueta asignada a 10, ok la de 11, ….
enum formas {circulo = 10, rectangulo = 20, cuadrado = 50};
• Cada etiqueta queda explicitamente asignada
• En C++ el compilador comprueba los enum
– Cada enum pasa a ser una palabra reservada para su unidad
de compilación
jjme29@[Link] J. Juan Meza E. 75
Lenguaje C++
Tipos de Datos Compuestos
• Arrays
– La estructura de datos mas conocida!
– Secuencias Homogéneas, de tamaño fijo (de
cualquier tipo)
– Acceso aleatorio (Random access) via el
operador de indexado - [ ]
– Inserción y borrado a tiempo constante al final.
– Los índices comienzan por 0 (primer elemento)
• El último elemento tiene el índice n-1
jjme29@[Link] J. Juan Meza E. 76
Lenguaje C++
Tipos de Datos
•Arrays – Ejemplo Compuestos
//Prints an input sequence backwards
#include <iostream>
const int SIZE = 20;
int main()
{
int i, n;
int nums[SIZE]; /*Leer numeros. Parar al leer 0 */
for (n = 0; n < SIZE; ++n) {
int input;
std::cin >> input;
if (input == 0)
break;
nums[n] = input;
}
for (i = n-1; i >= 0; --i)
std::cout << nums[i];
return 0;
}
jjme29@[Link] J. Juan Meza E. 77
Lenguaje C++
Tipos de Datos Compuestos
• Arrays – Inicialización
• Se puede utilizar una lista para inicializar :
– int a[] = {10,20,30,40,50};
– La dimensión es opcional. Si se utiliza debe ser >=
que el número de elementos iniciales.
– Si la dimensión es mayor el resto se inicializa a cero
– Si se omite la dimensión esta pasa a ser igual al
numero de elementos de la lista
jjme29@[Link] J. Juan Meza E. 78
Lenguaje C++
Tipos de Datos
Compuestos
• Arrays multidimensionales
– No existen como tales!
– C y C++, permiten “arrays de arrays”
– Se utiliza un par de corchetes para cada dimensión
– Se pueden inicializar con listas de inicialización
anidadas
jjme29@[Link] J. Juan Meza E. 79
Lenguaje C++
Tipos de Datos
Compuestos
• Arrays multidimensionales - Ejemplo
• Array 2d
– Considerar el siguiente array de 3 x 2 :
1 2
3 4
5 6
– C++ lo almacena linealmente: 1 2 3 4 5 6
– El compilador lo interpreta como un array de 3
“arrays de 2 ints”
1 2 3 4 5 6
jjme29@[Link] J. Juan Meza E. 80
Lenguaje C++
Tipos de Datos Compuestos
• Arrays multidimensionales - Ejemplo
// 2d.c: Illustrates a 2-d array
#include <iostream>
int main()
{
int a[][2] = {{1,2}, {3,4}, {5,6}};
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 2; ++j)
std::cout << a[i][j];
std::cout << std::endl;
}
return 0;
}
12
34
jjme29@[Link]
56 J. Juan Meza E. 81
Lenguaje C++
Tipos de Datos
• Arrays 3d Compuestos
• El programa de la próxima transparencia inicializa y
recorre el siguiente array 3d: 2x3x2
12
3 4 == a[0]
56
78
9 0 == a[1]
12
1 2 3 4 5 6 7 8 9 0 1 2
jjme29@[Link] J. Juan Meza E. 82
Lenguaje C++
• Arrays 3d
Tipos de Datos
#include <iostream>
int main()
Compuestos
{
int a[][3][2] = {{{1,2}, {3,4}, {5,6}},
{{7,8}, {9,0}, {1,2}}};
for (int i = 0; i < 2; ++i){
for (int j = 0; j < 3; ++j){
for (int k = 0; k < 2; ++k)
std::cout << a[i][j][k];
std::cout << std::endl;
}
std::cout << std::endl;
}
return 0;
}
jjme29@[Link] J. Juan Meza E. 83
Lenguaje C++
Tipos de Datos Compuestos
• Strings
• Arrays de caracteres
– Terminan con un byte null ('\0')
– literales entre doble comillas proveen
implicitamente el terminal null: "hello“
pasa a ser:
'h' 'e' 'l' 'l' 'o' '\0'
• C++ tiene la clase string
jjme29@[Link] J. Juan Meza E. 84
Lenguaje C++
Tipos de Datos Compuestos
Arrays de caracteres – Ejemplo
#include <iostream>
#include <string.h>
int main()
{
char last[] = {'f','r','o','s','t','\0'};
char first[] = "robert";
std::cout << "last == " << last << std::endl;
std::cout << "first == " << first << "\n";
std::cout << "last has " << strlen(last) << "chars\n";
std::cout <<"first has "<< strlen(first) << " chars\n";
return 0;
}
last == frost
first == robert
last has 5 chars
first has 6 chars
jjme29@[Link] J. Juan Meza E. 85
Lenguaje C++
Tipos de Datos Compuestos
• <string.h>
– Contiene declaraciones de funciones de
procesamiento de texto
– Casi todas estas funciones suponen arrays de
caracteres terminados en null (‘\0’)
– strcpy, strcat, memcpy strcmp, memcmp
strchr, memchr, strrchr, strstr, strtok
jjme29@[Link] J. Juan Meza E. 86
Lenguaje C++
Tipos de Datos Compuestos
• Estructuras
– Registro de Datos
– Palabra clave struct
– Colección Ordenada de variables “Members”
– Acceso a los miembros via el operador ‘.’
– Elementos fundamentales para los objetos y la
abstracción de datos!
– Los datos miembros son los atributos de los objetos
– union {};
jjme29@[Link] J. Juan Meza E. 87
• Estructuras - Ejemplo Lenguaje C++
#include <iostream> Tipos de Datos Compuestos
#include <string.h>
struct Hitter {
char last[16]; // 15 + 1
char first[11]; // 10 + 1
int home_runs;
}; // no olvidar el ';' !!!
int main()
{
Hitter h1 = {"McGwire", "Mark", 70};
Hitter h2;
strcpy([Link], "Sosa");
strcpy([Link], "Sammy");
h2.home_runs = h1.home_runs - 4;
std::cout << "#1 == {" << [Link] << ", " << [Link] <<
", " << h1.home_runs << "}" << std::endl;
std::cout << "#2 == {" << [Link] << ", " << [Link] <<
", " << h2.home_runs << "}" << std::endl;
return 0;
}
#1 == {McGwire, Mark, 70}
#2 == {Sosa, Sammy, 66}
jjme29@[Link] J. Juan Meza E. 88
Lenguaje C++
Tipos de Datos Compuestos
• Estructuras – Ejemplo II
• “Hall of Fame” struct
• Los miembros de una struct pueden ser de
cualquier tipo
• Una struct puede contener struct
jjme29@[Link] J. Juan Meza E. 89
• Estructuras – Ejemplo II
Lenguaje C++
Tipos de Datos Compuestos
// struct2.c: Illustrates nested structures
#include <iostream>
#include <string.h>
struct Hitter {
char last[16];
char first[11];
int home_runs;
int year; // new member
};
struct HallOfFame {
struct Hitter players[10];
int nPlayers;
};
jjme29@[Link] J. Juan Meza E. 90
• Estructuras – Ejemplo II Lenguaje C++
// struct2.c: nested structures Tipos de Datos Compuestos
int main() {
HallOfFame hr;
[Link] = 0; /* Insert first player */
strcpy([Link][[Link]].last, "Ruth");
strcpy([Link][[Link]].first, "Babe");
[Link][[Link]].home_runs = 60;
[Link][[Link]++].year = 1927; /* Insert next player */
strcpy([Link][[Link]].last, "Maris");
strcpy([Link][[Link]].first, "Roger");
[Link][[Link]].home_runs = 61;
[Link][[Link]++].year = 1961; /* Print players in hr: */
for (int i = 0; i < [Link]; ++i)
std::cout << [Link][i].year <<":" << [Link][i].last
<<", " << [Link][i].first
<<", " << [Link][i].home_runs << std::endl;
return 0;
}
1927: {Ruth, Babe, 60}
jjme29@[Link] 1961:J. Juan
{Maris,
Meza E. Roger, 61} 91
Lenguaje C++
Tipos de Datos Compuestos
• typedef
– “definición de tipo”: permite definir sinónimos para
tipos
– Formato : typedef tipo-existente sinónimo
• Un mecanismo de abstracción:
– typedef unsigned int size_t;
• Forma de abreviar
– En C elimina la proliferación de struct
– En C++ implícito para struct
• Ejemplos
– typedef unsigned long ulong;
– typedef struct mi_struc { ……} mi_struc;
– typedef int* IntPtr;
– IntPtr x, y;
jjme29@[Link]
• x e y son del tipo int* J. Juan Meza E. 92
Lenguaje C++
typedef struct {
Tipos de Datos
char c; Compuestos
int i;
float f; int main() {
double d; Structure2 s1, s2;
} Structure2; s1.c = 'a';
s1.i = 1;
s1.f = 3.14;
s1.d = 0.00093;
s2.c = 'a';
s2.i = 1;
s2.f = 3.14;
s2.d = 0.00093;
} //En C++ no es necesario typedef
jjme29@[Link] J. Juan Meza E. 93
Lenguaje C++
Tipos de Datos Compuestos
• Resumen
– Los Arrays comienzan por 0
– Los arrays Multi-dimensionales son “arrays de
arrays”
– Los Strings son arrays de char
• Delimitados por un byte null (\0)
– Las estructuras son colecciones de datos
miembros
– Los Arrays y las estructuras se pueden inicializar
con listas de inicialización delimitadas con llaves
jjme29@[Link] J. Juan Meza E. 94
Lenguaje C++
Programación con
Funciones
• Programación Procedural
• Semántica de Valor
• Prototipos de Función
• “Scope”
• Variables Automáticas, estáticas, y globales
jjme29@[Link] J. Juan Meza E. 95
Lenguaje C++
Programación con
Funciones
• Programación Procedural
– Conjunto de sentencias
– Definidas con una visibilidad a nivel de fichero (file
scope)
– En C deben tener nombre único
– Delimitadas con {braces}
– Realizan operaciones bien definidas
– Pueden tener argumentos
– Pueden retornar un valor
jjme29@[Link] J. Juan Meza E. 96
Lenguaje C++
Programación con
/* fun1.c: a function */
Funciones
#include <iostream>
float avg(int n, int m) {
return (n + m) / 2.0;
}
int main() {
int x, y;
std::cout <<("Enter the first number:");
std::cin >> x;
std::cout << "Enter the second number:";
std::cin >> y;
std::cout<< "The average is " << avg(x,y)<< std::endl;
return 0;
}
Enter the 1st number: 11
Enter the 2nd number: 12
The average is 11.50
jjme29@[Link] J. Juan Meza E. 97
Lenguaje C++
Programación con
Funciones
• Semántica de Valor
– Los argumentos se pasan por valor
– Cada parámetro formal obtiene una copia de
los valores de su argumento
– El valor del argumento no es afectado
– El resultado se retorna por valor
• La expresión que realiza la llamada obtiene el
valor desde una variable temporal:
a = b + avg(c,d);
jjme29@[Link] J. Juan Meza E. 98
Lenguaje C++
Programación con
Funciones
• La palabra clave void
– Para indicar la ausencia de un valor de
retorno, (la función es un procedimiento):
void f(int x, float y) {…}
– Para deshabilitar argumentos:
void title(void) { cout << "Welcome to
…"; }
…
title();
jjme29@[Link] J. Juan Meza E. 99
Lenguaje C++
Programación con
Funciones
• La palabra clave void
//Shows return with void. Also illustrates an array parameter
#include <iostream>
void print_ints(int nums[], int n)
{
int i;
if (n <= 0) return;
for (i = 0; i < n; ++i) {
if (i > 0) std::cout <<',';
std::cout << nums[i];
}
}
int main()
{
int a[] = {9,0,2,1,0};
print_ints(a, 5);
return 0;
}
9,0,2,1,0
jjme29@[Link] J. Juan Meza E. 100
Lenguaje C++
Programación con
Funciones
• Prototipo de una función
– Sinonimo de declaración o “ Signature” (nombre +
parameter tipo de parametros). Tipo del retorno
– Debe existir una correspondencia entre el tipo y número
de los argumentos de la llamada a con los argumentos
formales de la función
– Argumentos por defecto y lista variable
– Al compilar, el compilador puede detectar errores de uso
gracias a la declaración o definición de una función
– Definir o declarar una function antes de utilizarla. En
C++ es obligatorio ( en C opcional)
– Permite definir una función en un fichero y llamarla
desde otro distinto
– Es la base de las bibliotecas reutilizables
jjme29@[Link] J. Juan Meza E. 101
Lenguaje C++
Programación con
Funciones
// Prototipo de una función
#include <iostream>
float avg(int, int); // prototipo - declaración
int main() {
int x, y;
std::cout <<("Enter the first number:");
std::cin >> x;
std::cout << "Enter the second number:";
std::cin >> y;
std::cout<< "The average is " << avg(x,y)<<
std::endl;
return 0;
}
//Definición
float avg(int n, int m) {
return (n + m) / 2.0;
}
jjme29@[Link] J. Juan Meza E. 102
Lenguaje C++
Programación con
Funciones
// Uso de funciones definidas en ficheros distintos
// fichero micodigo.h
float avg(int, int);
…
// fichero [Link]
float avg(int n, int m) {
return (n + m) / 2.0;
}…
/* fichero fun3.c */
#include <iostream.h>
#include "micodigo.h"
int main()
{
…
…
avg(x, y)
…
…
return 0;
}
jjme29@[Link] J. Juan Meza E. 103
Lenguaje C++
Programación con Funciones
• Scope (alcance)
• Zona donde es visible un identificador
• Tres tipos básicos:
– Local (o “block”) scope: cualquier nombre
declarado en un bloque pertenece al bloque. Bloques {}
– File scope: Fichero: declaraciones que no pertenecen
a función o clase alguna
– Program scope
• Class scope: declaraciones asociadas a una clase
• Cada variable tiene un “scope” o un contexto
jjme29@[Link] J. Juan Meza E. 104
Lenguaje C++
Programación con
• Scope (alcance) Funciones
• Local
– Dentro de un bloque ({braces})
– Funciones
– Loops y sentencias if
– Visible desde el punto de declaración hasta el
fin del bloque
• File Scope
– La región fuera de las funciones
– Visible desde la declaración hasta el final del
fichero
jjme29@[Link] J. Juan Meza E. 105
Lenguaje C++
Programación con Funciones
• Variables Automáticas
– Almacenadas en la pila del programa
– Cualquier variable definida en un bloque sin
la palabra clave static
– Reinicializada cada vez que se ejecuta el
bloque
jjme29@[Link] J. Juan Meza E. 106
Lenguaje C++
Programación con Funciones
• Variables de almacenamento Automático
//los parámetros son variables auto
int min(int nums[], int size)
{// variables auto
int i, small = nums[0];
for (i = 1; i < size; ++i)
if (nums[i] < small)
small = nums[i];
return small;
}
jjme29@[Link] J. Juan Meza E. 107
Lenguaje C++
Programación con Funciones
• Variables Static
–Residen en un área especial de datos (Static)
del
segmento de datos
–Cualquier variable definida fuera de un bloque
“File scope”
–Cualquier variable declarada dentro de un
bloque
con la palabra clave static Initializada solo una
vez al comienzo de la ejecución del programa
jjme29@[Link] J. Juan Meza E. 108
Lenguaje C++
Programación con
Funciones
Uso de una variable static en una función Resultado:
#include <iostream> i=1
using namespace std; i=2
void func() i=3
{ static int i = 0; i=4
cout << "i = " << ++i <<endl; i = 5
} i=6
int main() i=7
{ for(int x = 0; x < 10; x++) i=8
func(); i=9
} i = 10
jjme29@[Link] J. Juan Meza E. 109
Lenguaje C++
Programación con
Funciones
• Variables Globales
– Tienen “program scope”
– Accesible desde fuera de su fichero fuente
– Definida con “file scope”
• Sin la palabra clave static
– Usar la palabra clave extern para hacer
referencia a variables globales en otros ficheros
– Static + file scope = privado del fichero
jjme29@[Link] J. Juan Meza E. 110
Lenguaje C++
//Fichero:[Link] Programación con
#include <iostream> Funciones
using namespace std;
int globe; Un fichero desde el que se
void func(); accede a globe como extern:
int main()
{ //Fichero:[Link]
globe = 12; extern int globe;
cout << globe << endl; // (El linker resuelve la
func(); // Modifica globe referencia)
cout << globe << void func() { globe =
endl; } 47; }
Resultado:
12
47
jjme29@[Link] J. Juan Meza E. 111
Lenguaje C++
Programación con
Funciones
• Scope (alcance)
• Operador ::
int x;
void f()
{
int x = 1;
::x = 2;
}
jjme29@[Link] J. Juan Meza E. 112
Lenguaje C++
Programación con
Funciones
• Ocultación de Información – (Information Hiding)
– Utilizando statics a nivel de fichero en C
– Protección de datos
– Separa la interfase de la implementación
• Principio Fundamental de la programación orientada
a objeto
• C++ da mas facilidades
jjme29@[Link] J. Juan Meza E. 113
Lenguaje C++
Programación con Funciones
• Pila: modelo:
• Last in – First out (LIFO)
• top señala el último elemento apilado
top
top D
top C C
top B B B
A A A A
jjme29@[Link] J. Juan Meza E. 114
Lenguaje C++
Pila: Importancia del concepto Programación con Funciones
RAM Memory
Adress Content
System stack (program data)
ai
ai+1
System heap (program data)
v. globales/static
fp ai+n main()
Program Code
jjme29@[Link] J. Juan Meza E. 115
Lenguaje C++
Pila: Importancia del concepto Programación con Funciones
• Ejemplo: pila del sistema local variables - a1
previous frame pointer
fp
return address a1
12
local variables
previous frame pointer fp previous frame pointer
return address main return address main
(a) (b)
System stack after function call main()
{ a1(12);}
jjme29@[Link] J. Juan Meza E. 116
Lenguaje C++
Pila: definición: Programación con Funciones
A = a0, a1, …, an-1 secuencia ordenada de n0 elementos.
La secuencia vacía implica n == 0;
Stack: secuencia ordenada en la que las inserciones y
borrados se realizan por uno de sus extremos
Sea S = (a0, …, an-1 ) una pila. Entonces a0 es el primer
elemento insertado en la pila y an-1 es el último
elemento insertado.
En general, diremos que el elemento ai estará apilado
sobre el ai-1
jjme29@[Link] J. Juan Meza E. 117
Pila Lenguaje C++
• Modelo : last in first out Programación con Funciones
– Inicialización
– Destrucción
– Copia
– Asignación
– Comparaciones
interfase
– Estado
v
– Recorrido (constante) - Propiedades A
• Condiciones excepcionales B p
– Inserción sin espacio. Pila llena.
– Eliminación sin elementos. Pila vacía
– Otras. (inicialización. copia)
• Detalles internos
– Contenedor de datos (secuencia)
– tamaño
jjme29@[Link] J. Juan Meza E. 118
Lenguaje C++
Programación con
Funciones
•Ejemplo: Stack
•stack.h
– Declaraciones de funciones del usuario
•stack.c
– Implementación de funciones
– Definiciones privadas
•tstack.c
– Un programa de test
jjme29@[Link] J. Juan Meza E. 119
Lenguaje C++
Programación con
Funciones
•Ejemplo: Stack
– stack.h
// stack.h: Declaraciones para una pila de enteros //en
C =>#define STK_ERROR –32767
const int STK_ERROR = - 32767; //C++
void stk_push(int);
int stk_pop(void);
int stk_top(void);
int stk_size(void);
int stk_error(void);
jjme29@[Link] J. Juan Meza E. 120
Lenguaje C++
Programación con
•Ejemplo: Stack - stack.c Funciones
/* stack.c: implementation */
#include "stack.h"
/* Private data: */
const size_t MAX= 10; // stack limit
static int error = 0; /* error flag */
static int data[MAX]; // the stack
static int ptr; // stack pointer
// Function implementation
void stk_push(int x)
{
if (ptr < MAX) {
data[ptr++] = x;
error = 0;
} else
error = 1;
}
jjme29@[Link] J. Juan Meza E. 121
Lenguaje C++
Programación con
Funciones
•Ejemplo: Stack - stack.c
int stk_pop(void)
{
if (ptr > 0) {
int x = data[--ptr];
error = 0;
return x;
}
else {
error = 1;
return STK_ERROR;
}
}
int stk_size(void)
{ return ptr; }
jjme29@[Link] J. Juan Meza E. 122
Lenguaje C++
Programación con
•Ejemplo: Stack - stack.c Funciones
int stk_top(void)
{
if (ptr > 0) {
error = 0;
return data[ptr-1];
}
else {
error = 1;
return STK_ERROR;
}
}
int stk_error(void)
{ return error;
jjme29@[Link] } Meza E.
J. Juan 123
Lenguaje C++
Programación con
Funciones
•Ejemplo: Stack - Programa de test: [Link]
#include "stack.h"
#include <iostream>
int main()
{ /* Populate stack */
for (int i = 0; i < 11; ++i)
stk_push(i);
if (stk_error())
std::cout << "stack error"<<std::endl;
std::cout<< "The last element pushed was "<< stk_top()<< "\n";
/* Pop/print stack */
while (stk_size() > 0)
std::cout<< stk_pop();
std::cout<< "\n";
if (!stk_error())
std::cout <<"no stack error"<<"\n";
return 0;
}
jjme29@[Link] J. Juan Meza E. 124
Lenguaje C++
Programación con
Funciones
•Ejemplo: Stack - Programa de test tstack.c
– Resultado
stack error
The last element pushed was 9
9876543210
no stack error
jjme29@[Link] J. Juan Meza E. 125
Lenguaje C++
Programación con
Funciones
• Resumen
• Una función es una colección de sentencias agrupadas
bajo un nombre
– Puede tener argumentos
– Puede retornar un valor
• Las funciones C/C++ utilizan la semántica de
paso/retorno por valor
• Scope es la región en la cual una variable es visible
– Local, fichero, programa
– En C las variables se pueden ocultar en ficheros con
statics. C++ ofrece mas alternativas.
jjme29@[Link] J. Juan Meza E. 126
Lenguaje C++
Punteros I
• Indirección
• Simulando llamada-por-referencia
• Paso de Argumentos por la línea de
Comandos
• Variables en el “Heap”
jjme29@[Link] J. Juan Meza E. 127
Lenguaje C++
Punteros I
• Un puntero, como un entero, es un número
– Interpretado como la dirección de otro objeto
– Se debe declarar asociado a un tipo: e.g.,
“puntero a entero”, “puntero a caracter”, etc.
Útil para:
– Objetos Dinámicos (“allocated from the heap”)
– Acceso directo a la memoria de la máquina
(“mapped memory”)
jjme29@[Link] J. Juan Meza E. 128
Lenguaje C++
Punteros I
• Indirección
– Se denomina indirección al acceso a un objeto
mediante un puntero
– El operador & (dirección-de) obtiene la dirección de
un objeto
– El operador * de de-referencia “de-referencing”
permite referirse al objeto señalado por el puntero
jjme29@[Link] J. Juan Meza E. 129
Lenguaje C++
• Indirección Punteros I
dirección contenido 0
RAM
1
int *puntero; //declaración - se reserva la 2
//celda que está en la dirección 99 para 3
almacenar alguna dirección: &puntero 99 4
puntero
puntero = reinterpret_cast<int *>(5); 5 23
//Inicialización. Hasta este momento en 99 .
puede haber cualquier valor! Método de .
inicialización .
*puntero = 23;//asignamos un valor al .
//contenido de puntero .
int m = *puntero;//declaramos una .
variable //entero m y le asignamos el valor 99 5
que señala //puntero
jjme29@[Link] J. Juan Meza E. 130
Lenguaje C++
• Indirección Punteros I
//indirect.c: Illustrate indirection
#include <iostream>
int main()
{
int i = 7;
int* ip = &i;
std::cout << "Address " << ip <<
" contains " << *ip << "\n";
*ip = 8;
std::cout << "Now address " << ip <<
" contains " << *ip << "\n";
return 0;
}
Address 0012FF88 contains 7
Now address 0012FF88
jjme29@[Link] contains
J. Juan Meza E. 8 131
Lenguaje C++
Punteros I
• Semántica de Referencias
• El parámetro formal es un alias del argumento de
la llamada
– Cualquier cambio en el parámetro cambia el
argumento original
• C no tiene referencias
• C++ tiene referencias
• In C/C++ se pueden utilizar punteros para
conseguir semántica de referencias
jjme29@[Link] J. Juan Meza E. 132
Lenguaje C++
Punteros I
Simulando la Semántica de Referencias
#include <iostream>
void swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int i = 1, j = 2;
swap(&i, &j);
std::cout <<"i == " << i << ", j == "<< j << "\n";
return 0;
}
i == 2, j == 1
jjme29@[Link] J. Juan Meza E. 133
Lenguaje C++
Array de punteros a arrays Punteros I
• Array de arrays de string?
– Mejor array de punteros a strings
char *ps[];
jjme29@[Link] J. Juan Meza E. 134
Lenguaje C++
Punteros I
• Paso de Argumentos por la línea de
Comandos
– Argumentos Opcionales de main
• int main(int argc, char* argv[]) {
…
}
– argv es un array de punteros a string
– argc es la dimensión de argv
• int (*vp) [10]; //puntero a array de 10 enteros
jjme29@[Link] J. Juan Meza E. 135
Lenguaje C++
Punteros I
• Paso de Argumentos por la línea de Comandos
#include <iostream> //[Link]
int main(int argc, char* argv[])
{
int i;
for (i = 0; i < argc; ++i)
std::cout << argv[i]<< " ";
return 0;
}
C:\> .\echo hello there
C:\[Link] hello there
jjme29@[Link] J. Juan Meza E. 136
Lenguaje C++
Punteros I
• El puntero NULL
• Un valor especial
– La dirección 0
• No apunta a nada
• Se puede utilizar para comparar con otros
punteros e.g., como un centinela o variable de
control
• Retornado por algunas funciones de
bibliotecas
• de-referenciar NULL es un error
jjme29@[Link] J. Juan Meza E. 137
Lenguaje C++
Punteros I
• Variables en el “Heap”
– Acceso indirecto mediante un puntero
retornado por malloc()/new
– Residen en un área de datos única llamada el
“heap” o “de almacenamiento dinámico”
– Cuando ya no se necesitan las variables del
heap se deben “liberar” via free()/delete
– Son útiles cuando no se conoce el tamaño
antes de la ejecución, por ejemplo el
tamaño de un array
jjme29@[Link] J. Juan Meza E. 138
Lenguaje C++
Punteros I
• Funciones C para variables en el Heap
• Defined in <stdlib.h>:
– void* malloc(size_t size);
– void free(void *ptr);
– void* calloc(size_t nelems, size_t elem_size);
– void* realloc(void *ptr, size_t size);
– size_t es un entero sin signo
• C++ ofrece dos operadores: new y delete ….
jjme29@[Link] J. Juan Meza E. 139
Lenguaje C++
Punteros I
• El operador sizeof
– Proporciona el tamaño de una variable o tipo en
bytes
– Es un operador de tiempo de compilación
• Cálculo del tamaño de un array:
– int n = sizeof a / sizeof a[0];
• Para el cálculo de tamaño de tipos se debe
utilizar paréntesis:
– float* p = (float *)malloc(sizeof(float));
jjme29@[Link] J. Juan Meza E. 140
Lenguaje C++
Punteros I
• Funciones C++ para variables en el Heap
• Operadores new y delete
– Reemplazo para malloc/free
– int* ip = new int(7);
– delete ip;
– int* iap = new int[10];
– delete [] iap;
• Operadores de tiempo de Compilación
• Cálculo del tamaño de los objetos
• Inicialización & “cleanup” automática
jjme29@[Link] J. Juan Meza E. 141
// reverse2.c: Prints lines in reverse Lenguaje C++
//order from input
#include <stdio.h>
Punteros I
#include <string.h>
const int MAXWIDTH = 81;
const int MAXLINES = 100;
int main() {
char* lines[MAXLINES];//eof from the console: ^Z
char line[MAXWIDTH]; /* Store in an array of pointers*/
for(int n = 0; n < MAXLINES && gets(line) != NULL; ++n) {
if ((lines[n] = new char [strlen(line)+1]) == 0)
exit(1);
strcpy(lines[n], line);
} /* Print in reverse order */
for (int i = 0; i < n; ++i) {
std::cout << lines[n-i-1] << std::endl;
delete [] lines[n-i-1];
}
return 0;
}
jjme29@[Link] J. Juan Meza E. 142
Lenguaje C++
Punteros I
• Estructuras en memoria dinámica (heap)
• En C
– Usar sizeof:
• struct Employee* p = (Employee*)
malloc(sizeof(struct Employee));
• En C++ struct Employee* p = new Employee;
• Para acceder a los miembros: (*p).age = 47;
• Sintáxis alternativa (el operador ->): p->age = 47;
jjme29@[Link] J. Juan Meza E. 143
Lenguaje C++
struct Structure3 { Punteros I
char c; int main() {
int i; Structure3 s1, s2;
float f; Structure3* sp = &s1;
sp->c = 'a';
double d;
sp->i = 1;
}; sp->f = 3.14;
sp->d = 0.00093;
sp = &s2; // Point to a different
//struct object
sp->c = 'a';
sp->i = 1;
sp->f = 3.14;
sp->d = 0.00093;
jjme29@[Link] } Meza E.
J. Juan 144
Lenguaje C++
Una estructura que Punteros I
hace referencia a si
misma a2 sr1
typedef struct SelfReferential 47
{ int i; x1
SelfReferential* sr;
} SelfReferential;
int main() {
SelfReferential sr1, sr2; x0
x1 sr2
[Link] = &sr2; x2 1024
[Link] = &sr1; x3 a2
sr1.i = 47; x4
sr2.i = 1024; } x5
jjme29@[Link] J. Juan Meza E. 145
Lenguaje C++
Punteros I
• structuras como Argumentos
– Conviene el paso de la dirección de la struct
mediante el uso de un argumento tipo apuntador
– Se ahorra tiempo y espacio
• En C++ se puede utilizar también el paso por
referencia
jjme29@[Link] J. Juan Meza E. 146
/* Passes a struct by address */
Lenguaje C++
#include <iostream> Punteros I
struct Date {
int year;
int month;
int day;
};
void printDate(struct Date* p)
{std::cout<< p->day<< "/"<< p->month<<"/"<< p->year;}
int main()
{
struct Date d = {98, 10, 2};
printDate(&d);
return 0;
}
2/10/98
jjme29@[Link] J. Juan Meza E. 147
Lenguaje C++
Punteros I
• Arrays como Argumentos
– Pasar todo el array es ineficiente
– Se pasa un puntero al primer elemento
– char * y char[] es equivalente como
parámetro de una función
jjme29@[Link] J. Juan Meza E. 148
Lenguaje C++
Referencias
• C++ presenta un nuevo tipo de datos: referencia.
– Se pueden considerar "alias" de variables u objetos "reales".
– Como un alias no puede existir sin su contraparte real, no se
pueden definir referencias por si solas.
– Pueden ser constantes (const)
– Las referencias pueden ser usadas como argumentos (paso
de parámetros por referencia) y retorno de funciones
(retornar una referencia a una variable u objeto).
jjme29@[Link] J. Juan Meza E. 149
Lenguaje C++
Referencias
• Para definir una referencia se usa el &.
– int ix; /* ix es la variable "real" */
– int &rx = ix; /* rx es el "alias" de ix */
– ix = 1; /* también rx == 1 */
– rx = 2; /* también ix == 2 */
– const int ci = 10; //ci constante entera
– const int& rci = ci; //rci referencia constante
– void F(int& n); //paso de parámetro por referencia
– void G(const float& fl); //paso por referencia constante
jjme29@[Link] J. Juan Meza E. 150
Lenguaje C++
Referencias
• Al proveer una función con un alias de un argumento real de
llamada de función se puede cambiar el valor del argumento de
llamada de función.
• Paso de parámetros por-referencia :
void mira (int porValor, int &porReferencia)
{ porValor = 42; porReferencia = 42; }
void main ()
{
int ix, jx;
ix = jx = 1;
mira (ix, jx); /* ix == 1, jx == 42 */
} jjme29@[Link] J. Juan Meza E. 151
Lenguaje C++
Referencias
• Paso de parámetros (siempre es por valor)
– Por valor - seguridad
• copiado en el almacenamiento local (pila) de la función
• la función accede a la copia
– Por referencia - velocidad - retornos múltiples
• se copia la dirección del objeto que se esta pasando
• la función accede al objeto
– Por referencia constante - seguridad + velocidad
• Excepción: vectores: paso por referencia
jjme29@[Link] J. Juan Meza E. 152
Lenguaje C++
Punteros II
• Punteros a Punteros
• Aritmética de Punteros
• Punteros y Arrays
• Punteros y const
• Punteros Genéricos (void*)
• Punteros a funciones
jjme29@[Link] J. Juan Meza E. 153
Lenguaje C++
Punteros II
• Punteros a Punteros
– Un puntero puede apuntar a cualquier tipo
incluyendo el tipo puntero
– Se pueden tener hasta 12 niveles de indirección
– El límite en la práctica es de 2 indirecciones
– En C++ se utilizan menos que en C
jjme29@[Link] J. Juan Meza E. 154
Lenguaje C++
• Punteros a Punteros Punteros II
#include <iostream>
using namespace std;
int main()
{
int i = 7;
int* ip = &i;
int** ipp = &ip;
cout << "Address " << ip << " contains " << *ip << "\n";
cout << "Address " << ipp << " contains "<< *ipp << "\n";
cout << " **ipp == " << **ipp << "\n";
return 0;
}
Address 0012FF7C contains 7
Address 0012FF78 contains 0012FF7C
**ipp == 7
jjme29@[Link] J. Juan Meza E. 155
Lenguaje C++
Punteros II
• Aritmética de Punteros
– Se puede sumar/restar un número entero a un
puntero
– El puntero avanza/retrocede ese número de
elementos
• no de bytes
– La resta entre dos punteros es el número de
elementos entre ellos
– Útil para el trabajo con arrays
jjme29@[Link] J. Juan Meza E. 156
Lenguaje C++
•Aritmética de Punteros Punteros II
#include <iostream>
#include <stddef.h>// for ptrdiff_t
int main()
{
float a[] = {1.0, 2.0, 3.0}, *p = &a[0];
ptrdiff_t diff;
std::cout<<"sizeof(float) == " << sizeof(float) << "\n";
std::cout<<"p == " <<p << ", *p == " << *p << "\n";
p += 2;
std::cout<<"p == " <<p << ", *p == " << *p << "\n";
diff = p - a; /* a == &a[0] */
std::cout<<"diff == " << diff <<" \n";
diff = (char*)p - (char*)a;
std::cout<<"diff == " << diff <<" \n";
return 0;
} sizeof(float) == 4
p == 0012FF80, *p == 1
p == 0012FF88, *p == 3
diff == 2
jjme29@[Link] J. Juan Meza [Link] == 8 157
Lenguaje C++
Punteros II
• Punteros y Arrays.
– En muchas expresiones el nombre de un array se
entiende como un puntero a su primer elemento:
– v == &v[0] o también, *v == v[0]
– En general:
– v + i == &v[i] o también *(v + i) == v[i]
– Hasta se podría expresar i[a]!
• Pero no se debería utilizar!
jjme29@[Link] J. Juan Meza E. 158
Lenguaje C++
Punteros II
• Punteros y arrays.
char v[10]; //vector de 10 caracteres (0 a 9)
char *p; // puntero a un carácter
p = &v[3]; //p apunta al cuarto elemento?de v
v p
&v x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 &p
jjme29@[Link] J. Juan Meza E. 159
Lenguaje C++
• Punteros y arrays. Punteros II
#include <iostream>
int min(int* nums, int size)
{ /* or int nums[] */
int* end = nums + size; //past the end
int small = *nums;
while (++nums < end)
if (*nums < small)
small = *nums;
return small; main()
} {
int a[] = {56,34,89,12,9};
std::cout << min(a, 5) << "\n"; // 9
}
Preguntas: qué es sizeof a?
qué es sizeof nums?
jjme29@[Link] J. Juan Meza E. 160
Lenguaje C++
Punteros II
• Punteros y arrays.
int main()
{
int a[10]; // a es un array de 10
enteros
int* ip = a;
for(int i = 0; i < 10; i++)
ip[i] = i * 10;
}
jjme29@[Link] J. Juan Meza E. 161
Lenguaje C++
• Punteros y arrays. Punteros II
void func1(int a[], int size) void func2(int* a, int size)
{ {
for(int i = 0; i < size; i++) for(int i = 0; i < size; i+
a[i] = i * i - i; +)
} a[i] = i * i + i;
}
int main()
{ int a[5], b[5]; // Que valores tienen?
// Inicializar los arrays:
func1(a, 5); func1(b, 5);
func2(a, 5); func2(b, 5);
}
jjme29@[Link] J. Juan Meza E. 162
Lenguaje C++
Punteros II
• Punteros y arrays multidimensionales.
• Considerar
– int a[3][4]:
• a es un array de 3 arrays de 4 ints
– a[i] es un array de 4 ints
– sizeof a[i] == 16
– Como se declara un puntero a a[0]?
a[0] a[1] a[2]
jjme29@[Link] J. Juan Meza E. 163
• Punteros y
Lenguaje C++
arrays multidimensionales.
Punteros II
#include <iostream>
int main()
{
int a[][4] = {{0,1,2,3},{4,5,6,7},{8,9,0,1}};
/* Pointer to array of 4 ints: */
int (*p)[4] = a;
size_t nrows = sizeof a / sizeof a[0];
size_t ncols = sizeof a[0] / sizeof a[0][0];
std::cout << "sizeof(*p) == " << sizeof *p << "\n";
for (int i = 0; i < nrows; ++i) {
for (int j = 0; j < ncols; ++j)
std::cout << p[i][j];
std::cout << std::endl; sizeof(*p) == 16
} 0123
return 0; 4567
} 8901
jjme29@[Link] J. Juan Meza E. 164
• Arrays multidimensionales. Lenguaje C++
#include <iostream>
int main()
Punteros II
{
int a[][3][4] = {{{0,1,2,3},{4,5,6,7},{8,9,0,1}},
{{2,3,4,5},{6,7,8,9},{0,1,2,3}}};
int (*p)[3][4] = a;
size_t ntables = sizeof a / sizeof a[0];
size_t nrows = sizeof a[0] / sizeof a[0][0];
size_t ncols = sizeof a[0][0] / sizeof a[0][0][0];
std::cout << "sizeof(*p) == " << sizeof *p << "\n";
for (int i = 0; i < ntables; ++i) {
for (int j = 0; j < nrows; ++j) {
for (int k = 0; k < ncols; ++k)
std::cout << p[i][j][k]; sizeof(*p) == 16
0123
std::cout << std::endl; 4567
} 8901
std::cout << std::endl;
} 2345
6789
return 0; 0123
jjme29@[Link] J. Juan Meza E. 165
}
Lenguaje C++
Punteros II
• Constantes y punteros
– Evita el cambio de un puntero y/o su contenido
– const antes del asterisco significa que el contenido
es const
– const después del asterisco significa que el puntero
es const
– volatile tiene la misma sintáxis
– const char* p1; // *p1 = ‘c’ ilegal; ++p1 OK
– char* const p2; // *p2 = ‘c’ OK; ++p2 ilegal
– const char* const p3; // no se permite ningún
cambio
jjme29@[Link] J. Juan Meza E. 166
Lenguaje C++
Punteros II
• Constantes y punteros
int i; // declaración de un entero
int *ip; // apuntador no inicializado a entero
int * const cp = &i;// apuntador constante a entero
const int ci = 7; // entero constante
const int *cip; // apuntador a un entero constante
const int * const cicp = &ci; // apuntador constante a
// un entero constante
jjme29@[Link] J. Juan Meza E. 167
Lenguaje C++
Punteros II
•Constantes y punteros
• Las siguientes asignaciones son válidas:
i = ci; // asigna un entero constante a un entero
*cp = ci; // asigna entero constante a una variable
// que está referenciada por un apuntador constante
cip = &ci; // cambia apuntador a entero constante
cip = cicp; // pone el apuntador de entero constante a
// referenciar la variable de apuntador constante a
// entero constante
jjme29@[Link] J. Juan Meza E. 168
Lenguaje C++
Punteros II
• Constantes y punteros
• Las siguientes asignaciones no son válidas:
ci = 8; // no se puede cambiar el valor de un entero
constante
*cip = 7; // no se puede cambiar un entero constante
//referenciado por apuntador
cp = &ci; // no se puede cambiar el valor de un
// apuntador constante
ip = cip; // esto permitiría cambiar el valor del
// entero constante *cip con *ip
jjme29@[Link] J. Juan Meza E. 169
Lenguaje C++
Punteros II
• Constantes y punteros
jjme29@[Link] J. Juan Meza E. 170
Lenguaje C++
• Punteros Genéricos.
Punteros II
• “Puntero a void” (void*)
– Se puede asignar cualquier puntero a /o
desde un void*
– En C++ es necesario el cast para usar el
item apuntado
– No se puede de-referenciar un void*
• Útil para:
– Tratar cualquier objeto como una
secuencia de bytes
– Implementar contenedores genéricos
jjme29@[Link] J. Juan Meza E. 171
Lenguaje C++
• Punteros Genéricos. Punteros II
#include<iostream>
void* memcpy(void* target, const void* source, size_t n)
{ /* Copy any object to another */
char* targetp = (char*) target;
const char* sourcep = (const char*) source;
while (n--)
*targetp++ = *sourcep++;
return target;
}
int main()
{
float x = 1.0, y = 2.0;
memcpy(&x, &y, sizeof x);
std::cout<< x << std::endl;
return 0;
}
2
jjme29@[Link] J. Juan Meza E. 172
Lenguaje C++
• Punteros Genéricos. Punteros II
/* qsort.c: Illustrates qsort */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int comp(const void*, const void*);
int main()
{
char* strings[] ={"how", "now", "brown", "cow"};
const unsigned int nstr = sizeof strings / sizeof strings[0];
unsigned int i;
qsort(strings, nstr, sizeof strings[0], comp);
for (i = 0; i < nstr; ++i)
puts(strings[i]);
return 0;
}
jjme29@[Link] J. Juan Meza E. 173
Lenguaje C++
• Punteros Genéricos. Punteros II
/* qsort.c: Illustrates qsort */
int comp(const void* p1, const void* p2)
{
char* a = *(char **) p1;
char* b = *(char **) p2;
return strcmp(a,b);//-strcmp()
}
brown
cow
how
now
jjme29@[Link] J. Juan Meza E. 174
Lenguaje C++
• Punteros a función
Punteros II
• El nombre de una función sin su lista de
argumentos es un puntero a la función
– Permite pasar la función como argumento a otra
función
– Como en el ejemplo anterior, la función comp
se pasa a la función qsort
• No es necesario la indirección explicita
– No se necesitan los operadores & o *
jjme29@[Link] J. Juan Meza E. 175
Lenguaje C++
• Punteros a función Punteros II
int (*pf) ( char, char *);// pf es un puntero a función
//que tiene como argumentos char, char* y retorna int
/* fptr.c */
#include <stdio.h>
int main()
{
int i = 1;
int (*fp)(const char*, ...) = printf;
fp("i == %d\n", i);
/* or (*fp)(" i == ...); */
return 0;
}
i == 1
jjme29@[Link] J. Juan Meza E. 176
Lenguaje C++
• Punteros a función
Punteros II
• Opciones de Menú y Funciones
– 1) Retrieve
– 2) Insert
– 3) Update
– 4) Quit
jjme29@[Link] J. Juan Meza E. 177
• Punteros a función Lenguaje C++
//menu.c: uses an array of function ptrs Punteros II
#include <stdio.h>
/* You must provide definitions for these: */
extern void retrieve(void);
extern void insert(void);
extern void update(void);
/* Returns keypress: */
extern int show_menu(void);
int main()
{
int choice;
void (*farray[])(void) = {retrieve,insert,update};
for (;;) {
choice = show_menu();
if (choice >= 1 && choice <= 3) // Process request:
farray[choice-1]();
else if (choice == 4)
break;
}
return 0;
}
jjme29@[Link] J. Juan Meza E. 178
Lenguaje C++
• Tipos Incompletos Punteros II
• Tipos cuyo tamaño es desconocido en el
punto de la declaración
• Array de tamaño desconocido:
– extern int a[]; // No es un parámetro
• Estructura que no ha sido declarada
completamente:
– struct foo; //Forward declaration
• Útil para ocultar información
jjme29@[Link] J. Juan Meza E. 179
Lenguaje C++
• Resumen Punteros II
• Los punteros pueden referenciar cualquier
tipo C/C++
• El nombre de un array es también un puntero
al primer elemento
– Excepto cuando se lo utiliza con sizeof
• const puede afectar a un puntero o a lo
referenciado por el mismo
• void* permite argumentos de función
genéricos
• Punteros a función permiten utilizar
funciones como argumentos
jjme29@[Link] J. Juan Meza E. 180
Lenguaje C++
Tipos Incompletos
• Los tipos incompletos
permiten ocultar información
• Ejemplo
• Una “Stack”
• El usuario solo ve el tipo incompleto y las
funciones de interfase
– Las declaraciones en TI_stack.h
• La implementación esta oculta en
TI_stack.cpp
jjme29@[Link] J. Juan Meza E. 181
Lenguaje C++
• Ejemplo Tipos Incompletos
• TI_stack.h: Declaraciones para un stack de ints
const int STK_ERROR = –32767;
/* Tipo incompleto */
typedef struct Stack Stack; //typedef opcional
Stack* stk_create(int);
void stk_push(Stack*, int);
int stk_pop(Stack*);
int stk_top(Stack*);
int stk_size(Stack*);
int stk_error(Stack*);
void stk_destroy(Stack*);
jjme29@[Link] J. Juan Meza E. 182
Lenguaje C++
• Ejemplo Tipos Incompletos
TI_stack.cpp: implementación
#include "TI_stack.h"
#include <stdlib.h>
/* Completar el tipo Stack */
struct Stack {
int *data;
int size;
int ptr;
int error;
};
Stack* stk_create(int stk_size)
{
Stack* stkp = new Stack;
stkp->size = stk_size;
stkp->data = new int[stkp->size];
stkp->ptr = stkp->error = 0;
return stkp;
};
jjme29@[Link] J. Juan Meza E. 183
Lenguaje C++
Tipos Incompletos
• Problemas
•Se tiene que pasar cada vez la dirección del stack como
parámetro a todas las funciones
•Puede conducir a colisión de nombres en las funciones
cuando se utilizan bibliotecas de fabricantes diferentes.
–Principalmente las funciones de creación y destrucción
• Al añadir stk_ al comienzo se disminuye esta posibilidad
• Soluciones
•Colocar las funciones dentro de la estructura
•Estandarizar la inicialización/destrucción de la estructura
jjme29@[Link] J. Juan Meza E. 184
Lenguaje C++
Tipos Incompletos
• Problemas
1. No se garantiza la inicialización/terminación
2. stack de un solo tipo
3. Demasiado “overhead” en las llamadas a función
4. El lenguaje C no tiene gestión de errores
5. El compilador C no controla el encapsulado e.g.,
[Link] = [Link] [0]; /* Violación de la abstracción */
[Link] = [Link]; /* Violación de la abstracción */
jjme29@[Link] J. Juan Meza E. 185
Lenguaje C++
Sobrecargas
• Todo nombre y/o expresión tiene un tipo
asociado.
• La sobrecarga es la capacidad de tener
varios operadores o funciones con un mismo
nombre, a condición de que exista alguna
diferencia en el tipo y/o número de los
argumentos
jjme29@[Link] J. Juan Meza E. 186
Lenguaje C++
Sobrecargas
• Ejemplo: dos funciones max(),
– una que retorne el mayor de dos enteros
– otra que retorne la mayor de dos cadenas:
#include <stdio.h>
int max(int a, int b){ if (a > b) return a; return b;}
char *max(char *a, char * b)
{if (strcmp(a, b) > 0) return a; return b;}
int main()
{
printf("max(19, 69) = %d\n", max(19, 69)); printf("max(abc,
def) = %s\n", max("abc", "def"));
return 0;
}
jjme29@[Link] J. Juan Meza E. 187
Lenguaje C++
Sobrecargas
• void f(); int f(); // ilegal, diferencias en el
tipo de retorno no son suficientes.
• Sobrecarga de los operadores de entrada
salida.
– iostream, cout, cin,
– operator<<,
– operator>>
jjme29@[Link] J. Juan Meza E. 188
Lenguaje C++
Objetos
• En C++ la clase/el tipo determina las operaciones que se le pueden
realizar.
• Ejemplo:
int dato; //declaración o construcción
operaciones: + - / *
dato es un objeto de clase/tipo entero – incluyendo las
operaciones !!!!
El programador puede definir y crear objetos
Ejemplo: números complejos
jjme29@[Link] J. Juan Meza E. 189
Lenguaje C++
Objetos
• Un objeto es cualquier variable que además de almacenar datos
permite que se le solicite la ejecución de determinadas acciones que
involucren a los datos que contiene. Teóricamente se puede representar
cualquier componente conceptual de un problema como un objeto
(gatos, edificios, servicios, etc.).
• Un programa se considera como un conjunto de objetos donde cada
objeto le indica a otros que deben hacer o como deben comportarse
(mensajes). Enviar un mensaje a un objeto significa realizar una
operación que pertenece a dicho objeto (llamar a una función
perteneciente al objeto).
• Cada objeto ocupa un espacio de memoria y en general los objetos
están formados por otros objetos.
jjme29@[Link] J. Juan Meza E. 190
Lenguaje C++
Objetos
• Todo objeto tiene un tipo. Cada objeto es una instancia de
una clase, donde “clase” es sinónimo de tipo. La
característica distintiva mas importante de una clase es:
¿Qué mensajes se le pueden enviar?
• Todos los objetos de un mismo tipo pueden recibir los
mismos mensajes. Uno de los conceptos mas potentes de la
POO es la capacidad de sustituir tipos siempre que estén
relacionados. Por ejemplo uno podría escribir código para
procesar formas geométricas y utilizarlo luego para
procesar círculos. Como un objeto del tipo círculo es un
tipo de forma geométrica, el círculo debería aceptar, al
menos los mismos mensajes que acepta una forma
geométrica.
jjme29@[Link] J. Juan Meza E. 191
Lenguaje C++
Información encapsulada. Objetos
•Nombre del tipo Bombilla
On()
Off()
•Interfase Mas_intensidad()
Menos_intensidad()
Bombilla b;
[Link]();
•Los mensajes que aceptan los objetos de la
clase constituyen la interfase
jjme29@[Link] J. Juan Meza E. 192
Lenguaje C++
Objetos
Reutilizando las implementaciones.
Coche
Motor
jjme29@[Link] J. Juan Meza E. 193
Lenguaje C++
• Basado en clases Objetos
– Structs con funciones miembros.
• Operaciones asociadas ( ==, <)
– Siempre tienen un objeto asociado
• Soporte para el encapsulado de información
– Palabras claves private, protected, public
• Inicialización/destrucción automática (garantizada).
– Constructores/destructores.
• Equivalencia de clases (tipos definidos por el usuario).
– struct s1 { int a; }; != struct s2 {int a;};
– El tipo struct es distinto a cualquier tipo fundamental
jjme29@[Link] J. Juan Meza E. 194
Lenguaje C++
sobrecarga de operadores
• X+Y*Z
class complex {
double re, im;
public:
complex(double r, double i) : re, im(i)
{}
complex operator+(complex);
complex operator*(complex);
bool operator==(complex);
bool operator<(complex);
};
jjme29@[Link] J. Juan Meza E. 195
Lenguaje C++
sobrecarga de operadores
void f()
{ complex a(1, 3.1);
complex b(1.2, 2);
complex c = b;
if(a==b)
a = b + c;
b = b + c * a;
c = a * b + complex(1,2);
}
jjme29@[Link] J. Juan Meza E. 196
Lenguaje C++
sobrecarga de operadores
+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &=
|= << >> >>= <<= == != <= >= && || ++ --
->* -> , [ ] ( ) new new[ ] delete delete[ ]
No se sobrecargan:
::
.
.*
jjme29@[Link] J. Juan Meza E. 197
Lenguaje C++
sobrecarga de operadores
operator= operator[ ] operator( ) y operator->
deben ser funciones miembro no estáticas lo cual
garantiza que sus primeros operandos sean L-values
Los operadores = & y , tienen significados
predefinidos cuando se aplican a objetos de una clase;
pero pueden hacerse inaccesibles o bien redefinirlos
jjme29@[Link] J. Juan Meza E. 198
Lenguaje C++
Objetos
• Los objetos automáticos se crean al llegar a
su definición y se destruyen cuando se sale
del bloque.
• Los objetos globales se crean una sola vez y
se destruyen al terminar el programa.
• Los objetos static son similares a los
globales.
jjme29@[Link] J. Juan Meza E. 199
Lenguaje C++
• Almacenamiento de objetos
– estático (asignada al iniciarse el programa)
– automático (asociada al bloque)
– en la memoria disponible (obtenida con new)
jjme29@[Link] J. Juan Meza E. 200
Lenguaje C++
clases
• Construcción de objetos
– automáticos
• variables locales: se ejecuta su constructor cada vez que el
programa pasa por la declaración
– secuencia de construcción - destrucción
• inicialización y asignación
– estáticos
• utilizada para asegurar la correcta inicialización y destrucción
de objetos de bibliotecas : cin, cout
– en memoria disponible
• new T, delete
jjme29@[Link] J. Juan Meza E. 201
Lenguaje C++
Funciones miembros
• Asociadas a una clase
– Nombre, lista de argumentos, tipo de retorno y cuerpo.
– Otro nivel de sobrecarga
• Dado por la pertenencia a la clase
– inline
• indica al compilador que cualquier llamada debe ser
reemplazada por el código de la función.
• Elimina el tiempo de llamada y de copia de argumentos.
• inline int sum(int a, int b) {return a + b;}
• i = sum (x,12); i = x + 12;
– inline y const ayudan a eliminar #define
jjme29@[Link] J. Juan Meza E. 202
Lenguaje C++
Soporte para abstracción de datos
• Definición de un conjunto de operaciones
asociadas a un tipo.
• Restricción del conjunto de operaciones que se
pueden realizar sobre un tipo a las definidas para
el mismo.
• CLASE
– nombre
– datos miembros
– funciones miembro
– control de acceso
jjme29@[Link] J. Juan Meza E. 203
Lenguaje C++
Soporte para abstracción de datos
• Inicialización y destrucción.
• Inicialización y asignación.
• Patrones.
• Gestión de excepciones.
• Conversiones de tipo
complex a = complex(1);
• Múltiples implementaciones
jjme29@[Link] J. Juan Meza E. 204
Lenguaje C++
Soporte para orientación a objetos
• Encapsulado.
• Funciones virtuales. Polimorfismo.
• Clases abstractas.
• Herencia simple y múltiple.
• Funciones patrón
• Clases patrón.
jjme29@[Link] J. Juan Meza E. 205
Lenguaje C++
clases
• Función miembro const
– El tipo this de la función será const X * const
• Función miembro inline
• Función miembro virtual
• Función miembro virtual pura
jjme29@[Link] J. Juan Meza E. 206
Lenguaje C++
clases
• Constructores
– Funciones con el mismo nombre de la clase
pero que no retornan nada. - Excepciones.
– Constructor de copia
– Constructor por defecto
– Constructores como conversores de tipo
• Destructores
– virtuales
jjme29@[Link] J. Juan Meza E. 207
Lenguaje C++
clases
• Friend
• Calificación de nombres
– operador ::
• Clases anidadas
• Miembros estáticos
• Punteros a miembros
– typedef void (cl::*PFM)(int)
– PFM pf = &cl::f;
jjme29@[Link] J. Juan Meza E. 208
Lenguaje C++
clases
• Construcción de objetos
– como miembros de otro objeto
• sintaxis de inicialización :
• secuencia de llamada a los constructores 1 los miembros
• secuencia de llamada a los destructores 1 el objeto
• uso de punteros a objetos miembros
– vectores de objetos
• los objetos deben tener constructor por defecto
• la destrucción de objetos es implícita si el vector es automático
• la destrucción es explicita cuando se trata de punteros
– delete, delete[]
jjme29@[Link] J. Juan Meza E. 209
Lenguaje C++
• Clases
Objetos
– Tipo abstracto de datos definido por el usuario
– Interface e implementación
X *const this;
// intstack.h: A Stack class for ints
class StackOfInt
{
public:
StackOfInt(int);
void push(int);
int pop();
int top() const;
int size() const;
~StackOfInt();
private:
int *data;
int length;
int ptr;
};
jjme29@[Link] J. Juan Meza E. 210
Lenguaje C++
clases y herencia
• Construcción de objetos
– gestión de memoria espécifica
• sobrecarga de new y delete
• Clases derivadas
• Herencia
– publica, protegida y privada. Datos, funciones, tipos
– conversión de tipo
– class x : public y {};
– construcción - destrucción
jjme29@[Link] J. Juan Meza E. 211
Lenguaje C++
clases y herencia
• Jerarquías
– funciones virtuales
– clases abstractas
• Herencia múltiple
– class a :public b, public c {};
– base múltiple
– base virtual
• Destructores virtuales - size_t de delete
jjme29@[Link] J. Juan Meza E. 212
struct A { class B { Lenguaje C++
private: int i, j, k; Estructuras y clases
int i, j, k; public:
int f();
public:
void g();
int f(); }; //struct A y class B
void g(); //producen el mismo
}; int B::f() { //resultado
int A::f() { return i + j + k;
} int main() {
return i + j + k; A a;
} void B::g() { B b;
void A::g() { i = j = k = 0; a.f(); a.g();
i = j = k = 0; } b.f(); b.g();
}
}
jjme29@[Link] J. Juan Meza E. 213
struct B {
Lenguaje C++
private: Estructuras y clases
char j; visibilidad
float f;
public:
int main() {
int i;
B b;
void func();
b.i = 1; // OK, public
}; b.j = '1'; // Ilegal, private
b.f = 1.0; // Ilegal, private
void B::func() { }
i = 0;
j = '0';
f = 0.0;
};
jjme29@[Link] J. Juan Meza E. 214
struct A {
int i;
Lenguaje C++
char j; Estructuras y clases
float f; visibilidad
void func();
};
void A::func() {} //public
struct B { int main() {
A a; B b;
public:
a.i = b.i = 1;
int i; a.j = b.j = 'c';
char j; a.f = b.f = 3.14159;
float f; [Link]();
void func(); [Link]();
}; }
void B::func() {}
jjme29@[Link] J. Juan Meza E. 215
Lenguaje C++
Array de Objetos
struct ThreeDpoint{ int main() {
int i, j, k; ThreeDpoint p[10];
for(int i = 0; i < 10; i++) {
};
p[i].i = i + 1;
p[i].j = i + 2;
p[i].k = i + 3;
}
}
jjme29@[Link] J. Juan Meza E. 216
Lenguaje C++
#include <iostream>
using namespace std;
Estructuras y clases
class V { constructor por defecto
int i; // private int main()
public: {
V v, v2[10];
int f(void){return i;}//inline
cout << v.f();
}; // No constructor for (int j = 0; j<9;j++)
cout << v2[j].f();
return;
}
Los valores de i que se imprimen en pantalla son singulares
jjme29@[Link] J. Juan Meza E. 217
Lenguaje C++
#include <iostream>
using namespace std;
Estructuras y clases
class V { constructor por defecto
int i; // private int main()
public: {
V v, v2[10];
V() {i = 5;} //constructor
cout << v.f();
int f(void){return i;} for (int j = 0; j<9;j++)
}; cout << v2[j].f();
return;
}
Los valores de i que se imprimen en pantalla son cincos
jjme29@[Link] J. Juan Meza E. 218
Lenguaje C++
#include <iostream>
using namespace std;
Inicialización de tipos
class Integer { primitivos
int i;
const int k; int main()
{
public:
Integer i[100];
Integer(int ii = 0);
for(int j = 0; j < 100; j++)
void print(); i[j].print();
}; }
Integer::Integer(int ii) :
i(ii), k(ii) {} El constructor inicializa
void Integer::print() { cout todos los int del array a
<< i << ' '; } ceros
jjme29@[Link] J. Juan Meza E. 219
Lenguaje C++
Estructuras y clases
#include <iostream> construcción de tipos primitivos
using namespace std;
class B { int main() {
int i; B a(1), b(2);
float pi(3.14159);
public:
[Link](); [Link]();
B(int ii); cout << pi << endl;
void print(); }
};
C:>test
B::B(int ii) : i(ii) {}
1
void B::print() { cout << i << endl; } 2
3.14159
jjme29@[Link] J. Juan Meza E. 220
Representación - Clase Stack
Codificación: Herencia
class intStack : public intvector {
public: intvector
intStack( int s ) : intvector(s) { }
~intStack(){}
void push(int a ){push_back(a);}
void pop() { return pop_front();}
int top() {return front();} intStack
};
La pila se puede considerar un caso particular de un vector.
Funciones como size y empty, se “heredan” del vector.
jjme29@[Link] J. Juan Meza E. 221
Lenguaje C++
clases y herencia
• Constructores virtuales
– no pueden serlo
– se los puede simular
• típicos: por defecto y de copia
• class X { class Y : public X {
public: public:
X(); Y();
virtual X* NewX () X* NewX ()
{ return new X(); } {return new Y(); }
}; };
void f(X * p1, X *p2)
{ X *p3 = p1->NewX(); X *p4 = p2->NewX(); }
jjme29@[Link] J. Juan Meza E. 222