Professional Documents
Culture Documents
El lenguaje C/C++
Arrays, Cadenas, Estructuras y Punteros
Contenidos
Diferencias principales Arrays Cadenas Bibliotecas de funciones Estructuras Punteros Memoria dinmica Argumentos a funciones Constantes Punteros y arrays Punteros a funciones Convivencia de funciones C++ y C
C es el lenguaje original con el que se cre Unix y l mayora la d de di dispositivos ii d de comunicaciones i i se programan en l
o
pero tienen distintas bibliotecas de funciones (y clases en el caso de C++) Esta documentacin est basada en el estndar C99. Ya hay un estndar C11 que lo acerca ms a C++ (C++11)
ficheros .c c (con sintaxis C pura!) -> > utiliza gcc ficheros .cpp (con C++ y/o C) -> utiliza g++
En C++
o o o
En C puro
o o
l lectura d de teclado l d
scanf("lista de comodines (%s%d...)", direcciones_a_variables); //es una funcin que utiliza punteros a variables
Los arrays de C
Inicializacin:
tipo nombre[tamao] = {const, const, .. const}; tipo nombre[] = {const, const, .. const};
NOTA: la asignacin de un arrays a otro array es ilegal en C char array1[50]; char array2[50]; array1 = array2; //ERROR (se ver la causa ms adelante)
Acceso a un elemento:
nombre[ndice] (donde ndice est entre [0 , tamao 1])
Ejemplo de arrays de C
#include <iostream> using namespace std; int main(){ const int TAM_ARRAY = 10; int arr[TAM_ARRAY]; t in; ; int for (int i=0; i < TAM_ARRAY ; ++i) arr[i] = i; // inicializacion con valores for (int i=0; i < TAM_ARRAY ; ++i) cout << arr[i]; // impresion del array por pantalla cout << "\nIntroduce el numero a buscar: " << endl; cin >> in; int j=0; while( (j < TAM_ARRAY) && ( arr[j] != in) ){ j++; } if (j == TAM_ARRAY) cout << "El numero " << in << "no esta en el array" << endl; else cout << "El numero " << in << "esta en la posicion " << j-1 << endl; return 0;
C++:
C:
#include <tr1/array> // o <array> en C++11 const t int i t TAM_ARRAY TAM ARRAY = 50; 50 //declaracin con tamao e inicializacin std::tr1::array<int, TAM_ARRAY> mi_array = {{1,2,3}}; //ojo a la doble llave //asignacin elemento a elemento mi_array[0] i [0] = 0; 0 //definicin como tipo typedef std::tr1::array<int, TAM_ARRAY> TipoArray; TipoArray otro_array; // //consulta lt d del lt tamao d del l array (cuantos ( t elementos l t tiene ti en uso) ) otro_array.size();
const int TAM_ARRAY = 50; //d l //declaracin i con tamao e inicializacin i i i li i int mi_array[TAM_ARRAY] = {1,2,3}; //quedan 47 huecos libres //declaracin sin tamao (lo resuelve el compilador) int mi_array2[] = {1,2,3}; //este tiene slo 3 elementos // i //asignacin i elemento l t a elemento l t mi_array[0] = 0; //definicin como tipo typedef int TipoArray[TAM_ARRAY]; Ti A TipoArray otro_array; t //NO es posible consultar el tamao ocupado de un array en C (lo cual es peligroso)
Cadenas de caracteres de C
El acceso se hace como un array normal, normal aunque existen tambin funciones especiales
cadena[0] = 'U';
La diferencia entre un array de C y una cadena es el terminador '\0', \0 , que ocupa una posicin, y permite entender el array de caracteres como texto
longitud de la linea actual maxima longitud actual linea actual linea mas larga
while(1){ cin getline(linea MAXLINE); cin.getline(linea, len= strlen(linea);//calcula la longitud en bytes de la cadena (sin contar '\0') cout << linea << ": " << len << endl; if(len > max){ max = len; copia(longest, linea); } cout << "La mas larga es de " << max << " caracteres: " << longest << endl; } return 0; } //sigue...
11
//no confundir con la clase std::string Si se usa C++: #include <cstring> En C puro: #include <string.h> Esta cabecera declara un conjunto j de funciones p para manipular p cadenas de caracteres Funciones tpicas:
Copia: memcpy, memmove, strcpy y strncpy Concatenacin: strcat y strncat Comparacin: memcmp, strcmp y strncmp Bsquedas q : memchr, strchr, strstr y strtok Otras: memset, y strlen
12
C++: #include <cstdlib> C: #include <stdlib.h> Esta cabecera declara un conjunto de funciones de propsito general Funciones: u c o es
o o o o o o
13
C++: #include <cctype> yp C: #include <ctype.h> Esta cabecera declara un conjunto de funciones para clasificar y transformar caracteres individuales Funciones:
o o o o o o o o o o o
iscntrl isspace isupper islower isalpha isdigit isxdigit i l isalnum ispunct isgraph i isprint i t
14
Definicin de estructuras
En C/C++, una estructura puede utilizarse como una variable (asignacin, paso como parmetro, valor de vuelta de una funcin) L estructuras Las t t no se pueden d comparar
15
Tamao de datos
En C y C++ existe un operador unario sizeof que devuelve el nmero de bytes que ocupa una variable o un tipo de dato en memoria
o
La longitud la devuelve como natural positivo, en un tipo denominado size_t size_t longitud = sizeof(int); int var_entera; var entera; size_t size t longitud = sizeof(var_entera); sizeof(var entera);
Ejemplos:
o o
16
CUIDADO: SU VALOR PUEDE SER MAYOR QUE LA SUMA INDIVIDUAL DEL TAMAO DE SUS CAMPOS
Se usan para ahorrar espacio de almacenamiento, pero depende d d d del l compilador il d cmo se almacena l la l estructura en memoria (su tamao real)
struct t t Permisos{ P i { unsigned int lectura : 1; //un bit
unsigned int escritura : 1; //un bit unsigned int ejecucion : 1; //un bit };
Uniones
Superposicin en memoria de elementos h heterogneos Solo existe un espacio de memoria (el del campo con mayor sizeof) Sin embargo, el acceso a ese espacio de memoria se hace indistintamente con cualquier campo, campo como en una estructura
union i N b Nombre { tipo1 elemento1; p elemento2; tipo2 ... } variables; c.ival = 20; i C tid d { Cantidad union int ival; float fval; } c;
18
Repaso de punteros
p 10 x
p 20 x
new reserva memoria para almecenar una variable de un tipo concreto en el heap new devuelve el puntero a esa variable u objeto, o cero si no fue capaz de hacer la reserva Tambin en versin array:
tipo *p = new tipo[50]; // p apunta a la primera casilla // se accede a los contenidos con p[x]
o
En C++, por seguridad, se recomienda utilizar std::vector, td t que reserva directamente di t t sus elementos l t en el Heap
22
Por cada llamada a new, debe haber una (y slo una) a delete. delete libera el espacio que ocupaba el objeto/variable en memoria En versin array:
23
C++
new, new [] delete, delete[]
o
o bien: be
#include <cstdlib> int * p = (int *)malloc(50*sizeof(int)) free(p);
C:
#include <stdlib.h> stdlib.h int * p = (int *)malloc(50*sizeof(int)) //alternativa: int * p = (int *)calloc(50,sizeof(int)); //si usas calloc el contenido de memoria se pone a cero! free(p);
24
El operador "->"
struct MisDatos{ int dato1; int dato2; }; MisDatos *p = new MisDatos; // Acceso a campos: (*p).dato1 = 5; // Es equivalente a: p->dato1 = 5;
25
void pinta() void pinta() { { MisDatos *p = new MisDatos; MisDatos p; p->dato1 = 5; p p.dato1 = 5; p //... //... } }
27
Qu es una referencia?
Un alias, otro nombre para una variable int x = 5; int &y y = x; // y es una // referencia a x y = 10; Qu pasa con x? Qu pasa con y? Las referencias SLO existen en C++, no en C
28
29
30
31
No es eficiente pasar zonas de memoria grandes (arrays) por valor a una funcin, puesto que se copian en su contexto de ejecucin El compilador pasa los arrays a una funcin siempre como punteros
void funcion(char array[]) //es equivalente a o void funcion(char *array)
o
El l programador d d debe b h hacer l lo mismo i si i piensa i mover grandes cantidades de datos entre funciones Y en C no existen las referencias: f(tipo &var)
o o
solo se vern prototipos de la forma: f(tipo *var) pero ya se ha visto que no es exactamente equivalente!
35
El modificador const
void imprimeDoble(const ( int& i){ ) i = i+i; No compila! cout t << i << endl; dl } int main(){ int i = 5; imprimeDoble(i); }
36
37
Punteros y arrays
38
#include <iostream> int main () { int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) std::cout << numbers[n] << ", "; ; return 0; }
Cuando se utiliza un std::string o std::array de C++, se puede obtener un p p puntero a sus datos en memoria, , para p manipularlos en modo C:
std::array<int,200> mi_array; int * p = mi_array.data();
Ejemplo:
39
#include <iostream> #include <cstring> cstring #include <array> int main () { const char* cstr = "Test Test string"; string ; std::array<char,12> charray; std::memcpy (charray.data(),cstr,12); std::cout << charray charray.data() data() << '\n'; \n ; return 0; }
Ejemplo:
Pero si no se est utilizando un compilador con el estndar C++11 esto NO est aconsejado Se recomienda el mtodo c c_str(), str() que devuelve un puntero a la cadena constante en formato C (SLO PARA OPERACIONES DE LECTURA)
40
#include <stdio.h> #include <string> int main () { std::string td t i str t ("H ("Hola l mundo d C!") C!"); printf("Contenido: %s\n",str.c_str()); return 0; }
41
Punteros a funciones
Se puede apuntar a la memoria donde comienza un segmento de cdigo (funcin) Se puede usar el puntero como el de una variable
42
Punteros a funciones
int (*pf)(); /* puntero a funcin que devuelve un entero */ void (*pv)(); /* puntero a funcin que devuelve void */ int (*pf2)(int,float); /*puntero a una funcion que devuelva int y acepte como argumentos a gu e tos int t y float*/ oat / int (*pf3[2])(int); /* array de dos punteros a funciones que devuelvan int y acepten como argumentos int*/ int (*pv2[2][3])(); /*array de 2x3 punteros a funciones que devuelvan int */
Ej Ejemplo: l
int f(){ /*esta funcion no tiene argumentos y devuelve un entero*/ return 0; } pf = &f; p pf(); //asignacion g del p puntero a funcion //ejecucin de la funcion! (es equivalente a poner directamente f());
43
Sin parmetros:
int main(){ return 0; }
int main(int argc, char *argv[]){ argv[]){ for(int i=0;i<argc; ++i) cout << argv[i] << endl; } argc es el argumento que contiene el nmero de palabras (parmetros) que se pasan al ejecutable (incluyendo el nombre del programa) argv es un array de cadenas de caracteres, donde cada casilla contiene un parmetro (argv[0] contiene el nombre del programa) Ejemplo: ./miprograma param1 param2
44
argc vale 3 argv es un array de 3 casillas. En argv[0] est la cadena "miprograma", en argv[1] est "param1" y en argv[2] est "param2"
Un fichero con extensin .hpp est pensado para incluirse en ficheros C++ de extensin .cpp. Sin embargo, si se programa en C puro (y con ficheros de extensin .c y .h), y luego se quiere reutilizar las funciones C definidas all en otros mdulos C++ (ficheros .cpp), cpp) los prototipos de las funciones tienen que incluir esta notacin en su .h:
#ifdef __cplusplus p p extern "C" { #endif //aqui van todos los prototipos de las funciones void f(int i, char c, float x); //... #ifdef __cplusplus } # dif #endif 45
Ms en:
http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html