Programación C y C++

De Proyectos
Ir a la navegación Ir a la búsqueda

Variables

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

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.

El objeto pedro es un struct de tipo nombre.

Otra forma de declarar:

struct nombre{
  int variable1;
  long variable2;
  char variable3[40];
}pedro;

Para inicializar la variable pedro se hace como con los arrays,

pedro = {2, 40, "hola"};

Esto solo se usa en C, porque en C++ se pueden usar los constructores.

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 "."
//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 );
}

Punteros a Arrays de Estructuras

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
  }
}

Pasar Estructuras a Funciones

  • Se pasan igual que las variables
void nombre_función ( struct nombre_de_la_estructura nombre_de_la variable_estructura ){
}
  • 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:

struct Punto { 
   int x, y; 
   Punto() {x = 0; y = 0;} // Constructor
} Punto1, Punto2;

Forma 2:

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; 
}

Destructor

  • Es igual pero con el simbolo ~ delante.

Funciones

  • Se pueden incluir otras funciones que se declaran y definen como las funciones normales.
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; 
}

Arrays de estructuras

Funcionan como los demas arrays

Asignación de estructuras

Ver apartado en Curso de C++ - con Clase

Documentación

Curso de C++ con clase
Curso de C - El Rincón de C

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 "&"
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;

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 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
 char *cadena;
 cadena = "Fran";
 printf("%s", cadena);

 char cadena2[]="Fran";
 printg("%s", cadena2);

 //Printfs equivalentes
 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 imprimiendolo 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.