|
|
| Línea 1: |
Línea 1: |
| = [[Estructuras]] = | | = [[Estructuras]] = |
| | = [[Punteros]] = |
|
| |
|
| = Variables = | | = Variables = |
| unsigned signed uint8_t byte int long char | | unsigned signed uint8_t byte int long char |
|
| |
| = Estructuras =
| |
| == Definicion ==
| |
| *Permiten agrupar diferentes tipos de datos: int, long, char, ...
| |
| *Cada elemento de la estructura se llama miembro
| |
| == Declaracion ==
| |
| <pre>
| |
| struct nombre{<br/>
| |
| int variable1;<br/>
| |
| long variable2;<br/>
| |
| char variable3[40];<br/>
| |
| };
| |
|
| |
| struct nombre pedro; //En C es obligatorio usar la palabra struct en la declaracion de un objeto struct, en C++ no lo es.
| |
| </pre>
| |
| El objeto pedro es un struct de tipo nombre.<br/>
| |
| <br/>
| |
| Otra forma de declarar:<br/>
| |
| <pre>
| |
| struct nombre{
| |
| int variable1;
| |
| long variable2;
| |
| char variable3[40];
| |
| }pedro;
| |
| </pre>
| |
| Para inicializar la variable pedro se hace como con los arrays,
| |
| <pre>
| |
| pedro = {2, 40, "hola"};
| |
| </pre>
| |
| Esto solo se usa en C, porque en C++ se pueden usar los constructores.<br/>
| |
| <br/>
| |
| En algunos compiladores es posible que se exiga poner antes de struct la palabra static.
| |
|
| |
| == Acceder a la información ==
| |
| *Se utiliza el operador de selección (.) --> pedro.variable1
| |
|
| |
| == Punteros ==
| |
| === Punteros a Estructuras ===
| |
| *Se declara un estructura normalmente
| |
| *Al declarar el objeto se pone el * para crear el puntero
| |
| *Para acceder a los miembros se utiliza el perador "->" en vez del el "."
| |
| <pre>
| |
| //Se declara una estructura
| |
| struct estructura {
| |
| char variable1[30];
| |
| char varaible2[40];
| |
| int entero;
| |
| };
| |
|
| |
| //Se crea un objeto y se inicializa
| |
| struct estructura dato = {
| |
| "hola",
| |
| "adios",
| |
| 30
| |
| };
| |
|
| |
| //Se declara un puntero
| |
| struct estructura *p_dato;
| |
|
| |
| int main(){
| |
| //Se apunta p_dato al objeto creado
| |
| p_dato = &dato;
| |
|
| |
| printf( "%s\n", p_dato->variable1 );
| |
| printf( "%s\n", p_dato->variable2 );
| |
| printf( "%s\n" , p_dato->entero );
| |
| }
| |
| </pre>
| |
|
| |
| === Punteros a Arrays de Estructuras ===
| |
|
| |
| <pre>
| |
| struct estructura {
| |
| char variable1[30];
| |
| char varaible2[40];
| |
| int entero;
| |
| };
| |
|
| |
| struct estructura dato[] = {
| |
| "hola", "adios", 30,
| |
| "perro", "casa", 20,
| |
| "Coche", "moto", 4
| |
| };
| |
|
| |
|
| |
| struct estructura *p_dato;
| |
|
| |
| int main(){
| |
|
| |
| //Se pueden usar estas dos formas para apuntar. Las dos significan lo mismo
| |
| p_dato = dato;
| |
| p_dato = &dato[0];
| |
|
| |
| int i;
| |
| for(i=0; i<3; i++){
| |
| printf( "%s\n", p_dato->variable1 );
| |
| printf( "%s\n", p_dato->variable2 );
| |
| printf( "%s\n" , p_dato->entero );
| |
| p_dato ++ //Con esto avanzamos al siguiente elemento del array
| |
| }
| |
| }
| |
| </pre>
| |
|
| |
| == Pasar Estructuras a Funciones ==
| |
| *Se pasan igual que las variables
| |
| <pre>
| |
| void nombre_función ( struct nombre_de_la_estructura nombre_de_la variable_estructura ){
| |
| }
| |
| </pre>
| |
| *Al pasar la estructura a la función se hace mediante copia, es decir, que el valor original de un miembro de la estructura no cambia si dentro de la función lo modificamos
| |
| *Se puede pasar la estructura mediante punteros
| |
|
| |
| struct estructura {
| |
| char variable1[30];
| |
| char varaible2[40];
| |
| int entero;
| |
| };
| |
| int main(){
| |
| struct estructura dato = {"hola", "adios", 10};
| |
| int numero;
| |
| '''numero = sumale_10(&dato);'''
| |
| }
| |
| int sumale_10('''struct estructura *dato'''){
| |
| '''return dato->entero+10; //Ahora en vez de poner el operador "." se pone el "->"'''
| |
| }
| |
|
| |
| == Funciones dentro de las estructuras ==
| |
| *Aplicable a C++.
| |
| *Son funciones que manipulan los datos de dentro de la estructura.
| |
| === Constructor ===
| |
| *Es una función sin retorno y con el mismo nombre que la estructura
| |
| *Los valores no iniciados con los constructores contendran "basura"
| |
| *Se pueden definir varios constructores
| |
|
| |
| Forma 1:
| |
| <pre>
| |
| struct Punto {
| |
| int x, y;
| |
| Punto() {x = 0; y = 0;} // Constructor
| |
| } Punto1, Punto2;
| |
| </pre>
| |
| Forma 2:
| |
| <pre>
| |
| struct Punto {
| |
| int x, y;
| |
| Punto(); // Declaración del constructor
| |
| } Punto1, Punto2;
| |
|
| |
| // Definición del constructor, fuera de la estructura
| |
| Punto::Punto() {
| |
| x = 0;
| |
| y = 0;
| |
| }
| |
| </pre>
| |
|
| |
| === Destructor ===
| |
| *Es igual pero con el simbolo ~ delante.
| |
| === Funciones ===
| |
| *Se pueden incluir otras funciones que se declaran y definen como las funciones normales.
| |
| <pre>
| |
| struct stPareja {
| |
| int A, B;
| |
| int LeeA() { return A;} // Devuelve el valor de A
| |
| int LeeB() { return B;} // Devuelve el valor de B
| |
| void GuardaA(int n) { A = n;} // Asigna un nuevo valor a A
| |
| void GuardaB(int n) { B = n;} // Asigna un nuevo valor a B
| |
| } Par;
| |
|
| |
| int main() {
| |
| Par.GuardaA(15);
| |
| Par.GuardaB(63);
| |
| cout << Par.LeeA() << endl;
| |
| cout << Par.LeeB() << endl;
| |
|
| |
| return 0;
| |
| }
| |
| </pre>
| |
|
| |
| == Arrays de estructuras ==
| |
| Funcionan como los demas arrays
| |
|
| |
| == Asignación de estructuras ==
| |
| Ver apartado en [http://c.conclase.net/curso/?cap=011#inicio Curso de C++ - con Clase]
| |
|
| |
| == Documentación ==
| |
| [http://c.conclase.net/curso/?cap=011#inicio Curso de C++ con clase]<br/>
| |
| [http://www.elrincondelc.com/cursoc/cursoc14.html Curso de C - El Rincón de C]<br/>
| |
|
| |
|
| = Punteros = | | = Punteros = |
Variables
unsigned signed uint8_t byte int long char
Punteros
- Un puntero no es más que una variable estática cuyo contenido es una dirección de memoria
- Para obtener la dirección de memoria de una variable se usa el operador de dirección"&"
int i;
printf("direccion de memoria de la variable: %d", &i);
- Para acceder al contenido de una posición de memoria se utiliza el operador de indirección "*"
- Cuando se define un puntero se hace según un tipo de variable. Ese puntero solo puede apuntar a ese tipo de varaibles
- Los operadores "& y *" tiene mas prioridad que los operadores binarios (+, -, ...)
- Se pueden asignar punteros entre ellos:
int a = 8;
int *p = &a;
int *q;
q = p;
Operaciones con Vectores
- Podemos manipular la dirección de memoria del puntero
int *p;
int a[10];
p=&a;
printf("%d", *(p+0)); //Primera posicion del vector a ;
printf("%d", *(p+1)); //Segunda posicion del vector a;
- Lo mismo se puede hacer restando
Punteros y Vectores
Todos los vectores son en realidad punteros
int a[10];
int *p;
p = a; //Ahora p puede acceder a las "casillas de a". Se escribe así porque la variable a, es un puntero
//Estos dos printfs son equivalentes
printf("%d", a[0]);
printf("%d", *p);
//Estos dos printfs son equivalentes
printf("%d", a[1]);
printf("%d", *(p+1)); //Sumamos 1 a la dirección de memoria haciendo que p apunte al siguiente elemento del vector
//En este ejemplo vemos que para imprimir un caracter y asignarle un valor lo hacemos normalmente:
char *c;
char b = 'H';
c = &b;
printf("%c", *c); //Cuando se imprime se pone el * para imprimir el dato que hay en la casilla a la cual apunta c.
//Aqui vemos que en una cadena de caracteres las operaciones de imprimir y asignar un valor son diferentes a como se hacen con el caracter y son similares a como se hacen con vectores de cadenas.
//Esto es por lo dicho anteriormente, los vectores de cadena son punteros.
//Estos dos ejemplos son equivalentes, los dos imprimiran Fran
char *cadena;
cadena = "Fran";
printf("%s", cadena);
char cadena2[]="Fran";
printg("%s", cadena2);
//Printfs equivalentes. Estos dos imprimiran F
char cadena[]="Fran";
printf("%c", cadena[0]);
printf("%c", *cadena);
Explicación:
Ejemplo1 Ejemplo2
char cadena2[]="Fran"; == char *cadena = "Fran";
printf("%s", cadena2); == printf("%s", cadena);
Con estos dos ejemplos vemos que cuando se hace la declaracion de una cadena de caracteres y luego se imprime es igual que como se hace con un puntero.
Cuando se imprime un puntero que apunta a un vector lo que se imprime es la primera posicion del vector. Para poder ir recorriendo el vector se le va sumando +1 al contenido de la memoria, asi si va desplazando entre las casillas.
Por tanto cuando ponemos en el printf la cadena lo que hacemos es pasarle al printf la dirección de memoria y con el operador %s indicamos que es un vector de caracteres y que tiene que ir recorriendolo todo.
Sabiendo esto y sabiendo de operaciones de punteros podemos hacer las equivalencias:
char cadena="Fran";
printf("%c", cadena[0]) == printf("%c", *cadena); //Primera posicion del vector
printf("%c", cadena[1]) == printf("%c", *(cadena+1); //Segunda posicion del vector
Documentación
Punteros en C
Otros
typedf -> cambia nombre del tipo a otro nombre personalizado. Ej. typedef strcut contacto contacto_t; //Ahora escribiendo contacto_t estoy escribiendo en realidad struct contacto.