Memoria Dinámica

Tipos de Memoria

La memoria Estética

  • Sin importa nada, ocupa todo el espacio de las variables que declaramos, no le importa si las usamos.

Memoria Dinámica

  • Puede hacerse más más compleja y dar muchos errores.
  • Da la capacidad de modificar tamaño de variables.
  • SIEMPRE se usan punteros.
  • Es mucho más lento un programa que la implemente pues ocupa más instrucciones.

Funciones de Memoria Dinámica

Para poder usarla hay que añadir a librería  

Malloc

  • Esta función sirve para reservar un espacio de memoria tan grande como se especifica dentro de la función.
  • La función malloc() y en general, cualquier función de reserva dinámica de memoria, devuelve un puntero nulo (NULL) si la reserva de memoria no puede realizarse, generalmente por falta de memoria disponible.
  • Por ello, antes de usar un puntero devuelto por la función malloc() es imprescindible comprobar que dicho puntero no es nulo (NULL).

Calloc

  • Esta función sirve para reservar un espacio de memoria tan grande como se especifica dentro de la función y al mismo tiempo inicializa todos a 0.
  • Es mucho más lento que Malloc.

Realloc

  • Redimensiona un tipo de dato que asignamos con Malloc pero conservando sus valores.

Free

La memoria dinámica reservada es eliminada siempre al terminar la ejecución del programa por el propio sistema operativo. Sin embargo, durante la ejecución del programa puede ser interesante, e incluso necesario, proceder a liberar parte de la memoria reservada con anterioridad y que ya ha dejado de ser necesario tener reservada.

Esto puede realizarse mediante la función free(). La función free() tiene la forma:

void free(void *p);

Donde p es la variable de tipo puntero cuya zona de memoria asignada de forma dinámica queremos liberar.


Vectores Dinámicos

Declararlo

tipo *NombreArray;

Donde:

  • tipo Es un tipo de dato (int, char)

Asignarle un tamaño al Vector(Malloc)  

NombreDelVector = (tipo*)malloc( Tamaño*sizeof(tipo) );

Donde:

  • Tamaño Es el número de posiciones que tendrá nuestro vector.
  • Tipo Es un tipo de dato (int, char)

Aquí unos ejemplos:

// == EJEMPLO 1 ==
//Declararlo
int *Vector1;

//Ponerle tamaño al Vector
Vector1 = (int*)malloc(50*sizeof(int));

// == EJEMPLO 2 ==

//Declararlo
double **Vector2;

//Ponerle tamaño al Vector
*Vector2 = (double**)malloc(70*sizeof(double*));

Asignarle un tamaño al Vector(Calloc)

NombreDelVector = (tipo*)calloc( Tamaño*sizeof(tipo) );

Donde:

  • Tamaño Es el número de posiciones que tendrá nuestro vector.
  • Tipo Es un tipo de dato (int, char)

Modificar el tamaño del Vector

NombreDelVector = (tipo*)realloc( NombreDelVector, NuevoTamaño*sizeof(tipo) );

Strings Dinámicos

Para trabajar con ellos es mucho más sencillo genera un string estático y en el meter los valores iniciales y ya luego pasarle los valores  al string dinámico que los conservara.

Declararlo

char NombreDelString;    //Vector Real
char StringAux;          //Vector Auxiliar

Asignarle un tamaño al Vector(Malloc)

NombreDelString = (char*)malloc((strlen(StringAux)+1)*sizeof(char));

Matrices Dinámicos

Declararlo

2D

tipo **NombreDeLaMatriz;

3D

tipo ***NombreDeLaMatriz;

Asignarle un tamaño al Vector(Malloc)

2D

//Genera un array
Matriz = (int **)malloc(filas*sizeof(int *));

//Dentro de cada elemento haz un array
for(i=0; i<filas; i++){
  Matriz[i] = (int*)malloc(columnas*sizeof(int));
}

3D

//Genera un array
Matriz = (int ***)malloc(altura*sizeof(int **));

//Dentro de cada elemento haz un array
for(i=0; i<altura; i++){
  //Genera un array
  Matriz[i] = (int **)malloc(filas*sizeof(int *));

  //Dentro de cada elemento haz un array
  for(j=0; j<filas; j++){
    Matriz[i][j] = (int*)malloc(columnas*sizeof(int));
  }
}

Notación Puntero-Array

Notación

Vector[x]; *(Vector + x);
Vector[x][y]; *(*(Vector+x) + y);
Vector[x][y][z]; *(*(*(Vector+x) + y) + z);
btn1 btn
btn

Estructuras

Una estructura es un conjunto de variables que se referencian bajo el mismo nombre. Permite agrupar muchísimas variables de cualquier tipo.

Declaración

typedef struct {
    int algo1;
    char algo2;
    float algo3;
}NombreDeLaEstructura;

 

 

 

La sintaxis de la declaración de una estructura en lenguaje C es:

Forma Correcta Forma Alterna
struct NombreDeLaEstructura {

     int algo1

     char algo2

     float algo3

}

typedef struct {

     int algo1

     char algo2

     float algo3

} NombreDeLaEstructura

Creación de una instancia de tipo estructura:

NombreDeLaEstructura NombreDeLaInstancia;

Creación de ambos al mismo tiempo:

struct NombreDeLaEstructura {
  int algo1
  char algo2
  float algo3
} NombreDeLaInstancia

Para referenciar un elemento de una estructura se realiza de la siguiente forma:

NombreDeLaInstancia.algo;

Typedef

El lenguaje C permite mediante el uso de la palabra reservada typedef definir nuevos nombres para los tipos de datos existentes, esto no debe confundirse con la creación de un nuevo tipo de datos. La palabra clave typedef permite solo asignarle un nuevo nombre a un tipo de datos ya existente. La sintaxis general de uso de typedef es:

typedef tipo nombre;

Donde tipo es cualquier tipo de datos permitido, y nombre es el nuevo nombre que se desea tenga ese tipo. Veamos algunos ejemplos:

typedef int entero;

typedef struct{
  unsigned código;
  char nombre[40];
  char apellido[40];
}cliente;

Y entonces podrían crearse nuevas variables de la forma:

entero a;

cliente b,*c;

Estructuras y Funciones

Para trabajar con una estructura dentro de una función es muy común usar punteros, que se verían de esta manera:

NombreFuncion(&NombreDeLaInstancia);

donde:

tipo NombreFuncion(*NombreDeLaInstancia){
  NombreDeLaInstancia->algo //Que es igual a: NombreDeLaInstancia.algo
}
btn1 btn
btn

Funciones

Las funciones son similares a las de cualquier otro lenguaje, pero, tal y como citamos en la introducción, al no ser un lenguaje estructurado por bloques, no es posible declarar funciones dentro de otras funciones.

funtion

Son bloques de código que podemos ejecutar una y otra vez.

Sintaxis de la Función:

tipo NombreFuncion(tipo Data1, tipo Data2, ...){
  cuerpo de la función
  return tipo;
}

Donde:

  • tipo Es un tipo de dato como int o void
  • Data Es el nombre de una variable

Prototipos

Los prototipos de funciones son una característica de C y se suelen declarar al incio del código.

Un prototipo es una declaración que toma la forma:

Sintaxis del Prototipo:

tipo NombreFuncion(tipo Data1, tipo Data2, ...);

Donde:

  • tipo Es un tipo de dato como int o void
  • Data Es el nombre de una variable

Ejemplo:

int fact(int v);
int mayor(int a, int b );
void final();

Argumentos

Los argumentos o parámetros son usados para poder pasar los valores de variables entre funciones.

Si tenemos algo así dentro de main:

...
int x,y;

Funcion(x,y);
...

Entonces el prototipo y la funcion en si podrían ser correspondientemente de estas maneras:

//Prototipo
Tipo Funcion(int x, int y);

//Funcion
Tipo Funcion(int x, int y){
  sentencias
  ...
}

Aunque tambien podrian tener otro nombre los parámetros y funcionaria igual:

//Prototipo
Tipo Funcion(int a, int b);

//Funcion
Tipo Funcion(int a, int b){
  sentencias
  ...
}

Return

Return permite, en primer lugar, salir de la función desde cualquier punto de la misma, y en segundo lugar, devolver un valor del tipo de la función, si ello es necesario (no se devuelve ningún valor si la función es de tipo void).


Paso por Valor y por Referencia

Pasar por Valor

Son cuando se genera una nueva variable dentro de la función, es decir:

  • Lo que se pasa a la funcion es el valor de X
  • Las variables que genera la funcion y las originales, son independientes y ningún cambio en ninguna de ellas afecta a la otra.
Funcion(x,y);

Pasar por Referencia

Son cuando se  envía la dirección de la variable original a la función, es decir:

  • Se proporciona a la función una referencia, la dirección de X.
  • Las variables que genera la funcion y las originales, son dependientes y todo cambio afecta a la otra.
Funcion(&amp;x,&amp;y);

Aquí estaría la función:

tipo Funcion(int *a, int *b){
  sentencias
  ...
}

Recuerda que al hacer usar punteros ya no es necesario usar el & en funciones como scanf:

int funcion(int *vector){
     int i;
     for(i=0; i<n ;i++){
      scanf(“%i”, (vec+i))
     }
}

A diferencia de otros lenguaje, el lenguaje C, sólo permite pasar parámetros a las funciones por valor. Si se desea que los cambios efectuados en una función sobre una variable afecten fuera del alcance de la función, es posible simular un paso por referencia mediante el uso de punteros.

En efecto, si a una función le pasamos como argumento la dirección de una variable, cualquier modificación que se realice en esa dirección, afectará, lógicamente, al valor que tiene la variable original, y con ello, conseguiremos el mismo efecto que un paso por referencia.

Ejemplo:

void Alfa(int *val,float pos){
*val=5;
pos=7.7;
}

void Beta(int val,float *pos){
val=10;
*pos=14.7;
}

int main(void){
int a=6;
float b=9.87;
printf(“Al principio valen a=%d b=%f\n”,a,b);
Alfa(&a,b);

printf(“Después de Alfa valen a=%d b=%f\n”,a,b);
Beta(a,&b);

printf(“Después de Beta valen a=%d b=%f\n”,a,b);
}

Este programa mostrará en pantalla:

  • Al principio valen a=6  b=9.87
  • Después de Alfa valen a=5  b=9.87
  • Después de Beta valen a=5  b=14.7

Ello es, pues a Alfa se le pasa la variable a por “referencia” (se le pasa &a, o sea, un puntero a la variable a), y la variable b por valor, mientras que en Beta sucede al revés.


Arrays y Funciones

Un aspecto a tener muy en cuenta es que C no permite el paso de un array por valor a una función, un array es siempre pasado por “referencia”, pues en la llamada, lo que se pasa es la dirección del primer elemento del array (recuérdese que el nombre de un array es un puntero al primer elemento). Por valor tan solo es posible pasar por valor elementos individuales del array, pero no el array completo.

Recursividad

Una función de C puede llamarse a sí misma. Este proceso recibe el nombre de recursividad. Los ejemplos de recursividad abundan, siendo uno de los más habituales la función factorial:

unsigned Factorial(unsigned num){
if (num==0) return 1;
return num*Factorial(num-1);
}

La recursividad es una poderosa herramienta de programación, sin embargo, presenta dos problemas:

  • La velocidad de ejecución de un algoritmo programado de forma recursiva es mucho más lento que el programado de forma iterativa.
  • La recursividad, si es excesiva, puede ocasionar el desbordamiento de la pila, y con ello, el fallo en la ejecución del programa.

 

 

btn1 btn
btn

Punteros

Punteros, punteros, punteros, el tema más difícil de C, pero ya no más.

Vamos a ver en esta lección todo lo relacionado a ellos para que todo sea más fácil para ti en el futuro, así que … Comenzamos

Cada variable tiene un espacio en la memoria RAM. Los punteros son una de las poderosas herramientas que ofrece el lenguaje C a los programadores.

array

Sin embargo, son también una de las más peligrosas, el uso de punteros sin inicializar es una fuente frecuente de errores en los programas de C, y además, suele producir fallos muy difíciles de localizar y depurar.

Podemos distinguir entre 2 tipos:


Parámetro de Indirección

*X

  • Un puntero es una variable que contiene una dirección de memoria
  • Un Puntero regresa el valor de una dirección de una variable.

Por lo cual se suele decir que el puntero “apunta” a la otra variable.

La sintaxis de la declaración de una variable puntero es:

tipo *nombreDelPuntero;

Donde tipo puede ser int, float,char, ect…


Parámetro de Dirección

&x

Un parámetro de dirección regresa la dirección de la variable a la que apuntamos.

Cuando usamos el símbolo estamos asignando o refiriendo a una dirección, es decir cuando escribimos &X estamos diciendo la dirección de X.

Es decir el operador & devuelve la dirección de una variable de memoria.

Crear un Puntero

int *puntero;

Asignar a un puntero una dirección de memoria

nombrePuntero = &variableParaApuntar;

Que un puntero regrese el valor al que apunta

variable = *nombrePuntero;


Ejemplos:

int *a
int b,c;

//Si hacemos:
b=15;
a=&amp;b;
c=*a;

Entonces c contendrá el valor 15
Pues *a devuelve el valor de la dirección que sigue (a la que “apunta” la variable puntero), y con anterioridad hemos hecho que a contenga la dirección de memoria de la variable b usando para ello el operador &.

int *a
int b;

//Y hacemos:
a = &amp;b;

La variable puntero a contendrá la dirección de memoria de la variable b.


Operaciones con Punteros

Asignación de Punteros

Es posible asignar el valor de una variable de tipo puntero a otra variable de tipo puntero.Por ejemplo:

int *a,*b
int c;
a=&amp;c;
b=a;

Entonces b contiene el valor de a, y por ello, b también “apunta” a la variable c.


Aritmética de Punteros

Sobre las variables de tipo puntero es posible utilizar los operadores +, -, ++ y —

Estos operadores incrementan o decrementan la posición de memoria a la que “apunta” la variable puntero. El incremento o decremento se realiza de acuerdo al tipo base de la variable de tipo puntero, de ahí la importancia del tipo del que se declara la variable puntero.


Comparaciones de Punteros

Sobre las variables de tipo puntero es posible realizar operaciones de comparación entre ellas. Veamos un ejemplo:

int *a,*b;
if (a&lt;b) printf(“a apunta a una dirección más baja que b”);

Arrays  como Punteros

Otra manera de acceder a una parte contigua de la memoria, en lugar de con un arreglo, es con un puntero.

Ya que estamos hablando acerca de las cadenas, las cuales se componen de caracteres, estaremos usando punteros a caracteres, o más bien:

char *string;

Después hacemos que apunte a la dirección de memoria del array

string = &amp;(array[0]);

Ahora estas sentencias son iguales:

  • array[7];
  • *(string+7);

Existe una estrecha relación entre los punteros y los arrays. Consideremos el siguiente fragmento de código:

char str[80],*p;

p=str;

int str[80],*p;

p=&str[4];

Este fragmento de código pone en la variable puntero p la dirección del primer elemento del array str. Entonces, es posible acceder al valor de la quinta posición del array mediante str[4] y *(p+4) (recuérdese que los índices de los arrays empiezan en 0).

Esta estrecha relación entre los arrays y los punteros queda más evidente si se tiene en cuenta que el nombre del array sin índice es la dirección de comienzo del array, y, si además, se tiene en cuenta que un puntero puede indexarse como un array unidimensional, por lo cual, en el ejemplo anterior, podríamos referenciar ese elemento como p[4].

Notación

Vector[x]; *(Vector + x);
Vector[x][y]; *(*(Vector+x) + y);
Vector[x][y][z]; *(*(*(Vector+x) + y) + z);

Sin embargo, los punteros sólo tienen una dirección, no pueden contener todos los caracteres de una matriz de caracteres. Esto significa que cuando usamos un char * para realizar un seguimiento de una cadena, debe existir el arreglo de caracteres que contiene la cadena.

btn1 btn
btn

Arreglos ó Arrays

En la práctica es frecuente que enfrentemos problemas cuya solución sería muy difícil de hallar si utilizáramos tipos simples de datos para resolverlos.

Es decir, datos que ocupan una sola casilla de memoria como los enteros o flotantes.

Sin embargo, muchos de estos problemas se podrían resolver fácilmente si aplicaramos en cambio tipos estructurados de datos, los cuales ocupan un grupo de casillas de memoria y se identifican con un nombre.


Array

Un arreglo unidimensional permite almacenar N elementos del mismo tipo (enteros, reales, caracteres, cadenas de caracteres, etc.) y acceder a ellos por medio de un índice. En los arreglos unidimensionales se distinguen dos partes fundamentales: los componentes del índice.

Un vector sería algo muy similar a una lista, ademas que siempre se usan junto con bubles. En C, un array unidimensional se declara como:

Sintaxis

//Aqui solo lo declaras
tipo nombre[tamaño];

//Aqui solo lo declaras y le das valores
tipo nombre[tamaño] = {valor1, valor2, valor3 ...};

En C, el primer elemento de un array es el que posee el índice 0, por lo tanto, un array de 20 elementos posee sus elementos numerados de 0 a 19.

array

Sin embargo, el lenguaje C no comprueba el tamaño de los arrays. ¡Porque C nos odia!

array

Aquí unas notas importantes para las próximas lecciones incluso si ahora no lo entiendes.

Nota:

  • Para usar un array como parámetro de una función basta con nombre
  • Para el prototipo de la misma funcion deberia ponerse nombre[]

Por lo cual, podemos escribir:

Aquí estan unos ejemplos:

float vector[3]={-3.0,5.7,-7.5};
int secuencia[3] = {0,1,2};

También es posible inicializar arrays sin ponerles el tamaño, el compilador cuenta el número de caracteres de inicialización y reserva el tamaño necesario de forma automática. Por ejemplo:

float vector[]={-3.0,5.7,-7.5};
char cadena[]=“Esto es una cadena”;

Matriz

Un conjunto de arrays o arreglos.

Así de simple : )

La declaración de arrays de más de una dimensión se realiza de forma parecida a la de una dimensión, la sintaxis de la declaración de un array multidimensional es:

//Aqui solo lo declaras
tipo nombre[tamaño1][tamaño2]...[tamañoN];

//Aqui solo lo declaras y le das valores
tipo nombre[tamaño][tamaño2] = {{var1,var2..},{var3,var4...},{var5,var6...}};

String

Una cadena, también llamada string, es un tipo especial de array unidimensional. Una cadena es un array de caracteres (char) que termina con un carácter especial (el carácter ‘\0’).

En esto el string es diferente a un arreglo de char, que tiene un final.

Es por ello, que la declaración de una cadena de caracteres se realiza exactamente igual que la declaración de un array unidimensional de caracteres:

//Aqui solo lo declaras
char cadena[tamaño];

Como toda cadena debe terminar en el carácter ‘\0’, es por ello que si se quiere usar una cadena de 20 caracteres, debe declararse de tamaño 21 (20 caracteres + carácter terminador).


Arrays  como Punteros

Otra manera de acceder a una parte contigua de la memoria, en lugar de con un arreglo, es con un puntero.

Ya que estamos hablando acerca de las cadenas, las cuales se componen de caracteres, estaremos usando punteros a caracteres, o más bien:

char *string;

Después hacemos que apunte a la dirección de memoria del array

string = &(array[0]);

Ahora estas sentencias son iguales:

array[7];
*(string+7);

Existe una estrecha relación entre los punteros y los arrays. Consideremos el siguiente fragmento de código:

¡Ambos son exactamente igual para la máquina!

char str[80],*p;

p=str;

int str[80],*p;

p=&str[4];

Este fragmento de código pone en la variable puntero p la dirección del primer elemento del array str. Entonces, es posible acceder al valor de la quinta posición del array mediante str[4] y *(p+4) (recuerda que los índices de los arrays empiezan en 0).

Esta estrecha relación entre los arrays y los punteros queda más evidente si se tiene en cuenta que el nombre del array sin índice es la dirección de comienzo del array, y, si además, se tiene en cuenta que un puntero puede indexarse como un array unidimensional, por lo cual, en el ejemplo anterior, podríamos referenciar ese elemento como p[4].

Notación

Vector[x]; *(Vector + x);
Vector[x][y]; *(*(Vector+x) + y);
Vector[x][y][z]; *(*(*(Vector+x) + y) + z);

Sin embargo, los punteros sólo tienen una dirección, no pueden contener todos los caracteres de una matriz de caracteres. Esto significa que cuando usamos un char * para realizar un seguimiento de una cadena, debe existir el arreglo de caracteres que contiene la cadena.


Funciones – Arrays

El lenguaje de programación C utiliza parámetros por referencia para pasar los arreglos a las funciones. Cualquier modificación que se realice a los arreglos á las funciones afecta su valor original.

En la llamada a la función sólo se debe incluir el nombre del arreglo, que es un apuntador. No se deben incluir los corchetes porque ocasionan un error de sintaxis.

void NombreFuncion(NombreArray){
...
}

 

Hemos usado algo pero no hemos tenido de explicarlo, los punteros, así que…

¿Me acompañas?

btn1 btn
btn

Funciones del Sistema (scanf & printf)

En este post vamosa ver el I/O (Osea como introducir datos en nuestros programas y cómo enviar cosas a la pantalla)

O más bien en vez de enviar, debería decir…imprimir :3

Printf

  • Es la función más básica para imprimir texto por la salida estandar (osea la pantalla) .
  • Para poder ocupar necesitas la libreria stdio.h

Sintaxis Básica:

printf("Aqui va el mensaje");

¿Y que pasa si quiero escribir en la pantalla el valor de ciertas variables?

Muy fácil, simplemente sigue esta métrica:

Sintaxis con Variables:

printf("Aqui va el texto normal %Letra", NombreVariable);

Para usarse con la Variables se necesita usar el %Letra, donde Letra es:

  • %d Entero con signo
  • %o Octal
  • %x  Hexadecimal
  • %e Notación científica
  • %i Int Entero sin signo
  • %f Float / Double
  • %c Char
  • %s  String

Aquí unos ejemplos:

//Ejemplo 1
int x = 3;
printf("X vale %d", x);

//Ejemplo 2
float pi = 3.1416;
printf("Esto :%f es lo que vale pi", pi);

Dando Saltos de línea

Algo también muy útil de saber es que podemos dar saltos de línea desde este comando, mira:

//Salto de linea
printf("Texto en linea uno \n Texto en linea 2")

Controlando el Punto Flotante

Pasa algo muy cool con los números flotantes o con punto decimal y es que podemos decirle a la máquina con cuantos puntos decimales los queremos.

Así con codigo así:

float numero = 543.232;

printf("Prueba uno %f");   //Mostrará 543.232000
printf("Prueba uno %.3f"); //Mostrará 543.232
printf("Prueba uno %.1f"); //Mostrará 543.2
printf("Prueba uno %.f");  //Mostrará 543

 printf


Scanf

Si printf era nuestra manera de sacar variables a la pantalla scanf es nuestra forma de meter información desde el teclado, pero hay que dejar algo muy claro.

¡scanf es muy fácil de HACKEAR!

  • Así que usar solo para aprender.
  • Requiere que incluyamos la librería stdio.h.

Permite obtener texto del teclado introducido por el usuario, es decir escanea lo que nosotros metemos por teclado.

Sintaxis:

scanf(“%Algo", &Variable);
  • Donde esto es muy importante.
  • Donde Algo tiene que ser:
    • %i Int
    • %f Float / Double
    • %c Char

Aquí unos ejemplos:

scanf(“%i", &x);
scanf(“%f", &NumeroFlotante);

índice.jpeg


Fgets

Mucho mejor que Fgets para obtener strings.

Permite obtener texto del teclado introducido por el usuario, es decir escanea lo que nosotros metemos por teclado.

Sintaxis:

fgets(Nombre,Tamaño,Input);

Donde:

  • Nombre: Nombre del String donde se guardará el texto que recoja.
  • Tamaño: Número máximo que recoge de caracteres.
  • Input: Lugar donde recogerá esos datos, para el teclado es stdin.

Aquí unos ejemplos:

fgets(stringEjemplo,14,stdin);

Nota: Siempre, siempre al intentar recoger más de 2 strings usar, porque permite limpiar el buffer:

fflush(stdin);

Números Aleatorios

Esto es más un pequeño procedimiento muy usado, así que quise compartirlo. Esto sirve para crear número aleatorio.

Procedimiento:

#include <time.h>             //Importamos la biblioteca necesaria

srand(time(NULL));            //Plantamos una semilla de tiempo

int aux = rand()%NumeroMaximo //Guardamos en aux un número aleatorio
btn1 btn
btn

Sentencias de Control

Las sentencias de control son una manera fancy de hablar de los bucles (secciones de nuestro código que se repiten muchas veces)  y las selectivas (cuando el programa decide ejecutar una u otra sección dependiendo de una decisión) así que empecemos por la primera ¿va?

meme.jpeg

Sentencias Selectivas

IF

La más famosa y fundamental es los IF´s, estos permiten al programa con base si una condición es cierta ejecutar un bloque de código o no hacerlo.

Se ven así:

Diferentes sintaxis de IF

//FORMA BÁSICA
if(condicion){
  sentenciasSiEsVerdad;
}

//COMO OPERADOR TERNARIO
(condicion)? sentenciaVerdad:sentenciaFalsa;

//FORMA IF-ELSE
if(condicion){
  sentenciasSiEsVerdad;
}
else{
  sentenciasSiEsFalso;
}

//FORMA IF-ELSE IF- ELSE
if(condicion1){
  sentenciasSiEsVerdad1;
}
else if(condicion2){
  sentenciasSiEsVerdad2;
}
else if(condicion3){
  sentenciasSiEsVerdad3;
}
else{
  sentenciasSiEsFalsoTodo;
}

Operadores de Comparación

Lo que va dentro de condición, es muy fácil, es una pregunta que tu le harás a la máquina que podrá contestar como un sí o un no.

Deja primero mostrarte qué operadores pueden comparar:

  • != No igual
  • == Igual
  • < Menor que
  • > Mayor que
  • && And
  • || Or
  • <= Menor o igual que
  • >= Mayor o igual que

Otra cosa muy útil de saber es que para C, cualquier valor que sea distinto de cero es verdadero, siendo por tanto falso sólo si el valor cero.

Por lo tanto será verdad siempre que el valor de la variable x sea distinto de cero, sea cual sea el tipo de la variable x.

Por lo tanto podemos terminar con algunos ejemplos de condiciones:

//Ejemplo 1
double pi = 3;
int variableBasura;

if(pi < 4){
  variableBasura = 0;
}

//Ejemplo 2
int numero = 3;

if( numero != 3 ){
  printf("Nunca se va a ejecutar esto");
}

//Ejemplo 3
int condicion = 0;

if(condicion!){
  printf("Esto siempre se va a ejecutar");
}

Así es como la mayoría de los programas que conoces funcionan, veamos ahora la siguiente:

Switch

Son básicamente igual a los if, simplemente que con otra sintaxis (si, se que hay más diferencias técnicas pero no importa), aquí su sintaxis:

switch (variable){
  case const1:
    sentencia;
    ...
    break;

  case const2:
    sentencia;
    ...
    break;

  ...

  default:
   sentencia;
}

Y si, eso es un switch, (¿Ves que no muerde?), total, esta sintaxis de ahí arriba se puede entender muy fácil si te muestro un código con if´s que haría exactamente lo mismo, se vería así:

if(variable == const1){
    sentencia;
    ...
}
else if(variable == const1){
    sentencia;
    ...
}
else if(variable == const2){
    sentencia;
    ...
}
else{
    sentencia;
    ...
}

Ahora vamos a ver un segundo tipo de sentencias de control, los bucles : 3


Bubles

WHILE

Este es sin menor duda la forma más básica de un bucle, lo único que hace es que ejecuta un bloque de código una y otra vez mientras una condición sea verdad.

while (condicion){
  sentencias;
}

No puede ser tan fácil, ¿o sí?…
La verdad es que lo es, es por eso que es el bucle más poderoso, pero la verdad es que mucha gente lo acaba usando es un estilo más o menos así:

int i = 0;             //Este es nuestro contador
while (i < tope){   //Lo vamos a seguir haciendo tope veces
  sentencias;          //Ejecutamos algo
i++;                   //Aumentamos el contador en uno
}

Pero el problema es que como te das cuenta resulta poner mucho código para repetir cosas, por eso se inventó un nuevo bucle.

FOR

Este es lo mismo que el bucle while, simplemente con otra sintaxis, es más esta es la sintaxis:

for (inicialización; condición; incremento){
  sentencia;
}

Así el último código que vimos con los whiles, se vería así con for:

for (i=0; i<tope; i++){
  sentencia;
}

Mucho más bonito y organizado ¿verdad?

Perfecto, ya casi terminamos, ya solo falta el final, te mostraré el último bucle, el do while.

DO WHILE

Al contrario que los bucles for y while que comprueban la condición en lo alto de la misma, el bucle do/while comprueba la condición en la parte baja del mismo, lo cual provoca que el bucle se ejecute como mínimo una vez. La sintaxis del bucle do/while es:

do{
  sentencia;
}
while(condicion);

Break y Continue

Las sentencias de control break y continue permiten modificar y controlar la ejecución de los bucles anteriormente descritos.

  • La sentencia break provoca la salida del bucle en el cual se encuentra y la ejecución de la sentencia que se encuentra a continuación del bucle.
  • La sentencia continue provoca que el programa vaya directamente a comprobar la condición del bucle en los bucles while y do/while, o bien, que ejecute el incremento y después compruebe la condición en el caso del bucle for.
btn1 btn
btn

Tipos de Datos y Sintaxis

Esta lección es rara : /

Por un lado hoy toca aprender básicamente toda la teoría que veremos en el curso (cosa que puede llegar a ser bastante aburrida), así que mientras vemos todo eso de teoría te ire contando como hacer tu primer programa en C.

¿Lo recuerdas?

//Hola Mundo C:
#include &lt;stdio.h&gt;

int main(void) {
  printf(“Hola Mundo”);
  Return 0;
}

 hola-mundo

Bueno, pues la primera línea que ves ahí es un comentario, así que empecemos por ahí:

Comentarios

Antes que nada (y ya para quitarme eso de encima), aquí esta como se escriben los comentarios en C:

//Comentario de una línea para algo rápido

*/ Comentario largo,
ideal para la Documentación */

Espera, espera…

¿Qué es un comentario? Ahhh, muy buena pregunta, es básicamente un pequeño texto que tienes en tu código fuente y que la computadora ignora, te sirve para poderte dejar notas para ti o para otros para que entiendan que estas haciendo.


Tipos de Datos

Los tipos de datos son como la máquina interpreta ceros y unos.

En C existen cinco tipos de datos:

Tipo de Dato Descripción
char ·  Almacenan: Carácter ASCII

· Tamaño: 1 Byte

· Usan comillas simples   ‘a’.

int ·  Almacenan: Entero entre -32.768 y 32.767.

· Tamaño: 2 Bytes

float ·  Almacenan: Decimales

· Tamaño: 4 Bytes

·  Siempre llevan un f al final

double ·  Almacenan: Decimales con presición

· Tamaño: 8 Bytes

·  Siempre llevan un lf al final

void ·  Uso especial


Variables

Las variables son pequeños trozos de memoria RAM que tu programa va a ocupar para llenarlos de información ( básicamente de “1” y “0” ) y los tipos de datos son cómo es que tu computadora interpreta esos “1” y “0”.

Declarar una variable es algo que hacemos en algunos lenguajes de programación, y que básicamente sirve para decirle a tu computadora: Reserva espacio de memoria para que yo pueda guardar un número o una letra o cualquier cosa.

En C, toda variable, antes de poder ser usada, debe ser declarada, especificando con ello el tipo de dato que almacenará. Toda variable en C con estas sintaxis:

Forma Basica

TipoDeDato NombreDeDato;

O también puedes declarar varias variables al mismo tiempo (¡No es asombroso!)

TipoDeDato Dato1, Dato2, Dato3;

También puedes ponerte más abusado y declararlas e inicializarlas (¡Todo en una misma línea, esto es asombroso!):

TipoDeDato Dato1 = Valor;
TipoDeDato Dato2 = Valor2, Dato3 = Valor3;

Así que ya que te sabes todas las formas de declarar variables en C, podemos empezar con algunos ejemplos:

float a;
char letra, otraLetra;
int salon = 1200, dinero = 22;

Variables Globales y Locales

En C, las variables pueden ser declaradas en cuatro lugares del módulo del programa:

  • Fuera de todas las funciones del programa, son las llamadas variables globales, accesibles desde cualquier parte del programa.
  • Dentro de una función, son las llamadas variables locales, accesibles tan solo por la función en las que se declaran.
  • Como parámetros a la función, solo existen dentro de la función.

Variables Estáticas

En C, una variable estática es una que sin importar por ejemplo que esté dentro de una función mantendrá su valor entre invocaciones.

int funcionEstupida(){
   static int numeroQueNoSeBorra = 3;
}

Modificadores

Modificador Tipos de actuación Tipos de actuación
signed char int Con signo (por defecto)
unsigned char int Sin signo
long int double Largo
short int Corto
const Todos Variable de valor constante
volatile Todos Variable cuyo valor es modificado externamente

Por lo tanto, podemos crear algo como lo siguiente:

long int NumeroMuyGrande;
long long int NumeroMuyMuyGrande;

Códigos

Código Significado
\b Retroceso
\f Alimentación de hoja
\n Nueva línea
\r Retorno de carro
\t Tabulador horizontal
\” Doble comilla
\’ Simple comilla
\0 Nulo – Final de Cadena
\\ Barra invertida
\o Constante octal
\x Constante hexadecimal

Operadores Matemáticos

Símbolo Operación
+ Suma
Resta
* Multiplicación
% Módulo

Resto de división

Simplificaciones

Forma Simple Forma Compleja
x += y x = x+y
x -= y x = x-y
x *= y x = x*y
x /= y x = x/y
x++ x = x+1
x– x = x-1

Lógicos

Operador Significado
!      NOT
>      Mayor que
<      Menor que
==     Igual
&&      AND
||      OR
>=      Mayor o igual que
<=      Menor igual que
!=      No igual


Preprocesador

En un programa escrito en C, es posible incluir diversas instrucciones para el compilador dentro del código fuente del programa. Estas instrucciones dadas al compilador son llamadas directivas del preprocesador y, aunque realmente no son parte del lenguaje C, expanden el ámbito del entorno de programación de C. El preprocesador, definido por el standard ANSI de C, contiene las siguientes directivas:

#if, #ifdef, #ifndef, #else, #elif, #endif
#include, #define, #undef, #line, #error, #pragma

DEFINE

Son una instrucción para el compilador de manera que siempre que vea este texto lo sustituye con el otro valor que le damos.

Sintaxis:

 #define PalabraABuscar PalabraASustituir;

Ejemplo:

#define pi 3.1416;

INCLUDE

La directiva #include fuerza al compilador a incluir otro archivo fuente en el archivo que tiene la directiva #include, y a compilarlo.

Sintaxis:

 #include

Ejemplo:

#include &lt;stdio.h&gt;;

Bibliotecas

Una biblioteca es un archivo en C del que nuestro programa puede usar su codigo, podemos hablar de 2 elementos muy importantes:

Biblioteca.c

Biblioteca.h

El primer archivo que tenemos es donde se encuentran las funciones que vamos a ocupar mientras que en el segundo tenemos los encabezados, de ahí el .h

Las más comunes son:

stdio.h Biblioteca estándar para entrada / salida
time.h Biblioteca usada para controlar el tiempo
math.h Biblioteca usada para usar funciones de matemáticas
stdlib.h Biblioteca usada para funciones estandar (memoria dinámica)

Así que has llegado hasta el final, estoy muy orgulloso de ti mi pequeño aprendiz, ahora si que estas listo para entender tu primer programa:

¿Lo recuerdas?

//Hola Mundo C:           -&gt;Comentario
#include &lt;stdio.h&gt;;     //-&gt;Biblioteca

int main(void) {       //-&gt;Aqui esta el main, dentro haremos todo
  printf(“Hola Mundo”);//-&gt;Muestra por pantalla el Hola mundo
  return 0;            //-&gt;Regresa un cero
}                      //-&gt;Fin del programa

 

 ¿No entiendes nada?

No te preocupes, no esperaba que lo hiciera, como te has dado cuenta incluso un programa básico tiene muchas partes, y cosas muy raras como ese int o printf ¿Qué significan?

No te preocupes, ya llegaremos a eso, por ahora nos falta solo una lección y podrás ya entender por fin ese codigo, ¡aguanta!

Da click aquí para seguir

btn1 btn
btn

Introducción a C

 

Fuentes.png

Historia y Datos útiles de C

denis.jpg

Adora a tu nuevo Dios ¡De rodillas!

C fue creado por Dennis Rietchie. C es el resultado de un proceso de desarrollo que comenzó con un lenguaje anterior, el BCPL, o mejor conocido simplemente como B.

Por eso se llama C….porque el lenguaje anterior era B (Sip, esa es la explicación más estúpida que se me ocurre tambien a mi).

 


¿Y porque es tan importante ese tal Dennis?

Cita.png

Mi humilde traducción a este:

dennis_ritchie

Precioso meme

El es uno de los padres de la computación actual, si hoy en día tenemos celulares en nuestras casas, ordenadores, o demás es porque el motivado el gran boom! del software.

El al crear C,  que es lo que ha hecho crecer al mundo de los ordenadores, hablando de fechas, el creo C en 1972 mientras trabajaba para Bell Labs junto con Kerrigan todo el equipo estaba trabajando en el desarrollo de un nuevo sistema operativo….UNIX. C fue creado con un solo propósito: CREAR Y TRABAJAR en UNIX.

unix

 

Además, el lenguaje C no es rígido en la comprobación de tipos de datos, permitiendo fácilmente la conversión entre diferentes tipos de datos y la asignación entre tipos de datos diferentes.

//Por lo tanto puedo hacer cosas como:

int arreglo[10];
arreglo[11] = 4;

C es un lenguaje sensible al contexto, por lo cual, C diferencia entre mayúsculas y minúsculas, y por tanto, diferencia entre una palabra escrita total o parcialmente en mayúsculas y otra escrita completamente en minúsculas.

//Esto para la maquina es diferente:
int VARIABLE;
int Variable;
int variable;


¿Es C un lenguaje de “alto nivel”?

Pues tiene todas las características de un lenguaje de alto nivel, pero la gran ventaja de C es que nos permite estar cerca del procesador y hacer más cosas orientadas a hardware que las de los demás lenguajes, justo por eso usan este lenguaje para PIC o aparatos parecidos.

¿Cómo programo en C?

Todo programa de C consta (sin ponernos de complejos) de un conjunto de funciones, y una función llamada main (por favor, por favor, nunca olviden poner el main), la cual es la primera que se ejecuta al comenzar el programa, llamándose desde ella al resto de funciones que componen nuestro programa.

Pero bueno, basta ya de aburrirlos con muchas palabras, es hora de aprender algo de verdad divertido: ¡Las variables!

Así que si, es hora de empezar a ver un poco de Sintaxis.

Pero antes es hora de que me lo quite de encima, así es como se ve el programa mínimo en c.


Formato de un Programa Básico

//Hola Mundo C:
#include <stdio.h>

int main(void) {
  printf(“Hola Mundo”);
  Return 0;
}

 ¿No entiendes nada? No te preocupes, ese es el objetivo de la siguiente lección.

Da click para seguir

btn1 btn
btn