C¶
Última edición el día 2020-12-14 a las 20:52.
Esta es la documentación que he recopilado para trabajar con C, un lenguaje clásico que veo oportuno aprender primero antes que cualquier otro lenguaje que utilices pra trabajo o para proyectos personales.
Índice
Elementos básicos del lenguaje¶
Comentarios¶
Los comentarios se pueden realizar de dos tipos:
Comentarios de una sola línea:
// comentario de una linea
Comentarios multilínea:
/*
Comentario multilínea
donde puedes escribir
en mas de una línea obviamente
*/
Estructura en C¶
La estructura de C ha inspirado a la mayoría de lenguajes de programación que le precedieron:
// en la primera línea importamos la librería estandar de C:
#include <stdio.h>
// creamos la función principal main que no retorna nada (void):
void main (void){
printf("Hola mundo!\n"); // con \n hacemos un salto de línea
}
Extensión¶
La extensión utilizada por los archivos C es c
Una vez se compila su extensión pasa a ser h
Compilación y Ejecución¶
Para poder compilar un programa escrito en C debemos instalar un compilador, yo personalmente utilizo en linux GCC y el comando para instalarlo es: sudo apt install build-essential
El comando para compilar un programa en C con GCC es gcc -o nombre script.c
La compilación nos devolverá un programa llamado hola
que ejecutamos en Linux como ./hola
Preparación del script¶
Cuando programamos en C la primera línea que escribimos siempre es la importación de la librería principal:
#include <stdio.h>
Palabras reservadas de C¶
En C existen las siguientes palabras reservadas:
auto
break
case
char
const
continue
default
do
double
else
enum
extern
float
for
goto
if
int
long
register
return
short
signed
sizeof
static
struct
typedef
union
unsigned
void
volatile
while
Variables y tipos de datos¶
Variables¶
En C por convención se declara la variable y cuando se requiere necesario la asignación en la misma línea.
Ejemplo:
int edad = 22;
Constantes¶
Las constantes en C se pueden declarar de dos formas, al comienzo del código con la palabra reservada #define
o en la función main con la palabra const
Ejemplo de declaración con #define:
// justo despues de las importaciones asignamos con #define:
#define PI 3.1415
Ejemplo de declaración con #define:
// Dentro de la función main:
const PI = 3.1415;
En el caso de C, se suele utilizar mas amenudo #define
Tipos de datos primitivos¶
Los tipos de datos mas comunes son los siguientes:
Tipo de dato |
Denominación |
Ejemplo |
---|---|---|
int |
Número Entero |
20, 5, -3, 0 |
float |
Número con decimales |
20.53, 12.5, -18.353 |
double |
Número con decimales preciso |
11.3938, 35.23903, 23.33292 |
char |
Almacena uno o varios caracteres |
«a», «z», «17», «hola» |
Ejemplos:
int numero = 27;
float decimal = 11.38;
double preciso = 3.1415161820;
char letra[1] = "a"; // importante definir la cantidad de caracteres que pueden haber en la variable.
Especificadores de Formato¶
En C existen los especificadores de formato cuya finalidad se da en la entrada o salida de datos para especificar donde va a ir un dato:
Tipo de dato |
Denominación |
---|---|
%d |
Número Entero (int) |
%f |
Número con decimales (float, decimal) |
%c |
Caracter o caracteres (char) |
%s |
Cadenas de texto (string) |
Entrada y Salida de datos¶
C utiliza para entrada de datos la función scanf()
y para la impresión de estos por consola printf()
Entrada de datos:
// acompañamos con un printf esta sentencia que solo lleva el tipo de dato y el enlace a la variable:
scanf("%d", &edad);
Salida de datos:
printf("cadena de salida");
veamos un ejemplo donde escribimos nuestra edad:
#include <stdio.h>
void main(void) {
int edad;
printf("Escribe aquí tu edad:\n");
scanf("%d", &edad);
printf("Tu edad es de %d años\n", edad);
}
Enumeradores y estructuras de datos¶
Enumeradores¶
Los enumeradores nos sirven para generar un tipo de dato utilizando typedef
y enum
, por ejemplo en el ejemplo generamos y usamos un tipo Booleano.
Ejemplo:
#include <stdio.h>
// creamos el enum y lo llamamos BOOLEAN:
typedef enum{
false,
true,
} BOOLEAN;
void main(void){
// creamos una variable de tipo BOOLEAN
BOOLEAN b_var;
// esta variable solo aceptará los valores true o false
b_var = false;
if(b_var == true){
printf("Verdadero\n");
}else{
printf("Falso\n");
}
}
Estructura de datos¶
La estructura de datos se genera también con typedef
junto a struct
#include <stdio.h>
typedef struct{
int inval1;
int inval2;
int outval;
} MY_DATA;
void add(MY_DATA *d){
d->outval = d->inval1 + d->inval2;
}
void main(void){
MY_DATA data;
data.inval1 = 5;
data.inval2 = 7;
add(&data);
printf("La suma de %d y %d es %d\n", data.inval1, data.inval2, data.outval);
}
Operadores¶
Operadores Aritméticos¶
Los operadores aritméticos que se presentan en C son los siguientes,
+, -, *, /, %
Estos podemos utilizarlos del siguiente modo:
// asignación:
int suma = 2 + 2;
// salida de datos:
printf("%d\n", 3-2);
Operadores Relacionales¶
Los operadores relacionales en C son muy comunes en la mayoría de lenguajes de programación:
Operador |
símbolo |
---|---|
Mayor que |
> |
Menor que |
< |
Igual que |
== |
Distinto que |
!= |
Mayor igual que |
>= |
Menor igual que |
<= |
Cuando hablamos del uso de un solo =
nos referimos a la asignación de un valor en una variable.
Como en muchos lenguajes, si imprimimos por consola la relación entre un valor y otro el resultado será 0 o 1 (false o true):
// comparamos un valor en una variable tipo booleana:
bool num = 3 < 2;
// imprimimos el resultado que será 0 o 1:
cout << num << endl;
Operadores de Incremento¶
Este tipo de operador suma o resta 1 a la cantidad asignada, se utiliza sobre todo en bucles:
Incremento positivo:
a++
,++a
Incremento negativo:
a--
,--a
Operadores de Incremento al asignar¶
Los operadores de incremento realizan una operación aritmética al asignar un número nuevamente:
Operador |
símbolo |
---|---|
Sumar |
|
Restar |
|
Multiplicar |
|
Dividir |
|
Sacar resto |
|
Menor igual que |
|
Ejemplo de uso:
#include <stdio.h>
void main(void) {
int numero = 10;
numero += 15;
printf("%i\n", numero);
}
Operadores Lógicos¶
En C existen los operadores lógicos AND y OR:
Operador |
símbolo |
condición |
---|---|---|
&& (and) |
&& |
La condición se cumple si todos son verdaderos |
|| (or) |
|| |
La condición se cumple si al menos uno es verdadero |
Ejemplos:
#include <stdio.h>
void main(void){
int edad = 67;
// pregunta con AND:
if(edad > 18 && edad >= 65){
printf("con %d años eres un anciano\n", edad);
}
//pregunta con OR:
if(edad > 18 || edad >= 65){
printf("con %d años eres mayor de edad\n", edad);
}
}
Estructuras de control¶
Las estructuras de control en C son el modelo a seguir por sus predecesores.
Condicional if¶
En C las condiciones if han servido de ejemplo para los futuros lenguajes.
#include <stdio.h>
void main(void){
int a = 0;
if(a == 0){
printf("a es igual a 0\n");
}
}
Disponemos de una salida alternativa si no se cumple la condición con else
:
#include <stdio.h>
void main(void){
int a = 0;
if(a == 0){
printf("a es igual a 0\n");
}else{
printf("a es distinto a 0\n");
}
}
Condicional else-if¶
Las condiciones compuestas nos ofrecen varios caminos posibles:
#include <stdio.h>
void main(void){
int a = 0;
if(a == 0){
printf("a es igual a 0\n");
}else if(a == 1){
printf("a es igual a 1\n");
}else{
printf("a es un numero desconocido\n");
}
}
Condicional Switch¶
El condicional Switch nos ofrece varios caminos como if-else
pero de forma mas visual:
#include <stdio.h>
void main(void){
int a = 0;
switch(a){
case 0:
printf("a es igual a 0\n");
break;
case 1:
printf("a es igual a 1\n");
break;
default:
printf("a es desconocido\n");
}
}
Bucle for¶
El bucle for en C se presenta muy similar a sus predecesores:
#include <stdio.h>
void main(void){
int a;
for(a = 0; a < 5; a++){
printf("a es igual a %d\n", a);
}
printf("a es igual a %d y hemos acabado\n", a);
}
Bucle while¶
Con while podemos ejecutar un bucle que termina al cumplir la condición o hacerlo infinito.
Ejemplo:
#include <stdio.h>
void main(void){
int a = 0;
while(a < 5){
printf("a es igual a %d\n", a);
a++;
}
printf("a es igual a %d y hemos terminado\n", a);
}
Bucle Do-while¶
Con do while creamos un bucle que siempre va a ejecutar al menos una sola vez aunque no se llegue a cumplir la condición:
#include <stdio.h>
void main(void){
int a = 0;
do{
printf("a es igual a %d\n", a);
a++;
}while(a == 0);
printf("a es igual a %d y hemos terminado\n", a);
}
Romper un bucle¶
Podemos romper el funcionamiento de un bucle for o while con la palabra reservada break
:
#include <stdio.h>
void main(void){
int a = 0;
while(1){
printf("a es igual a %d\n", a);
a++;
if(a == 5){
break;
}
}
printf("a es igual a %d y hemos acabado/n", a);
}
Estructuras de datos¶
Arrays¶
Existen varios tipos de arrays, y son un poco raros de manejar en C.
Ejemplo de uso con enteros:
#include <stdio.h>
void main(void){
int a[10];
int count;
for(count = 0; count <10; count++){
a[count] = count;
printf("Repetición número %d\n", a[count]);
}
}
Strings¶
En C para hacer trabajar con Strings tenemos que utilizar la librería <string.h>
Unir dos strings:
#include <stdio.h>
#include <string.h>
void main(void){
// creamos tres cadenas de caracters y rellenamos las dos primeras:
char str1[10] = "Primera";
char str2[10] = "Segunda";
char str3[20];
// añadimos a la tercera la primera cadena:
strcpy(str3, str1);
// concatenamos un espacio en blanco:
strcat(str3, " ");
// y concatenamos la segunda cadena con la tercera.
strcat(str3, str2);
printf("%s + %s = %s\n", str1, str2, str3);
}
comparar dos strings:
#include <stdio.h>
#include <string.h>
void main(void){
char str1[10] = "hola";
char str2[10] = "saludo";
if(strcmp(str1, str2) == 0){ // si da 0 son iguales y si es != distinto no.
printf("Las dos cadenas son idénticas.\n");
}else{
printf("Son cadenas diferentes.\n");
}
}
entrada de datos tipo string:
#include <stdio.h>
void main(void){
int val;
char string[10] = "250";
sscanf(string, "%d", &val);
printf("El valor en el string es %d\n", val);
}
medir la longitud de un string:
#include <stdio.h>
#include <string.h>
void main(void){
char str1[10] = "Primero";
printf("La longitud de la cadena %s es %ld\n", str1, strlen(str1));
}
Funciones¶
Las funciones en C son la referencia para muchos lenguajes que le han precedido:
#include <stdio.h>
int sum(int a, int b){
int res;
res = a + b;
return res;
}
void main(void){
int y = 2;
int z = sum(5, y);
printf("La suma de 5 y %d es %d\n", y, z);
}
Punteros¶
Un puntero es una dirección de memoria que apunta a una variable y su propósito es el ahorro de memoria. Se usa comunmente en llamadas a funciones, manejo de strings y arrays.
Ejemplo de uso:
#include <stdio.h>
void main(void){
int a;
// declarar un puntero:
int *ptr_a;
// asignar variable a un puntero:
ptr_a = &a;
a = 5;
printf("El valor de a es %d\n", a);
// modificar un puntero:
*ptr_a = 6;
printf("El valor de a es %d\n", a);
}
Punteros en arrays:
#include <stdio.h>
void main(void){
int a[10];
int count;
for(count = 0; count <10; count++){
a[count] = count * 10 + count;
}
printf("El primer y segundo elemento son %d y %d\n", a[0], a[1]);
printf("Y con sus punteros son, %d y %d\n", *a, *(a+1));
}
Punteros en strings:
#include <stdio.h>
void main(void){
char str1[10] = "primero";
char str2[10] = "segundo";
char str3[20];
char *src, *dst;
src= str1;
dst = str3;
while(*src != 0){
*dst = *src;
src++;
dst++;
}
src = str2;
while(*src != 0){
*dst = *src;
src++;
dst++;
}
*dst = 0;
printf("%s + %s = %s\n", str1, str2, str3);
}
Punteros en funciones:
#include <stdio.h>
// declarando un parametro puntero:
int operacion(int a, int b, int *res){
int sum;
sum = a + b;
*res = a - b; // utilizando el puntero para almacenar el resultado de la operacion
return sum;
}
void main(void){
int b = 2;
int diff;
printf("La suma de 5 y %d es %d\n", b, operacion(5, b, &diff));
printf("La diferencia de 5 y %d es %d\n", b, diff);
}
Manejo de Archivos¶
En C existe la posibilidad de manejar archivos de modo que podemos leer, editar y crear nuevos:
Escritura de archivos¶
Para escribir un nuevo archivo desde cero utilizamos el modificador wb
:
#include <stdio.h>
void main(void){
FILE *fp;
int value;
fp = fopen("entrada.txt", "wb");
if(fp){
for(value = 48; value < 58; value++){
fputc(value, fp);
}
fclose(fp);
}
}
Añadir un texto formateado con la función
fprintf()
:
#include <stdio.h>
void main(void){
FILE *fp;
int value;
fp = fopen("entrada.txt", "wb");
if(fp){
fprintf(fp, "Esto es un texto.\n");
fprintf(fp, "Esto es otro texto.\n");
fclose(fp);
}
}
Lectura de archivos¶
Si queremos leer un archivo usamos el modificador rb
:
#include <stdio.h>
void main(void){
FILE *fp;
int value;
fp = fopen("entrada.txt", "rb");
if(fp){
while(1){
value = fgetc(fp);
if(value == EOF) break;
else printf("%c", value);
}
fclose(fp);
}
}
Actualización de archivos¶
Para actualizar un archivo existente sin destruir la información que ya posee usaremos el modificador ab
:
#include <stdio.h>
void main(void){
FILE *fp;
int value;
fp = fopen("entrada.txt", "ab");
if(fp){
fprintf(fp, "Esto es un texto.\n");
fprintf(fp, "Esto es otro texto.\n");
fclose(fp);
}
}
Si ejecutamos este codigo varias veces veremos como se incluyen nuevas líneas a nuestro script.
Empaquetado y Preprocesamiento¶
Crear paquetes¶
En C podemos dividir el código y llamarlo en la cabecera
Tenemos un archivo llamado por ejemplo
funcion.c
que contiene una función específica:
int add_valores(int a, int b, int c){
return a + b + c;
}
Ahora necesitamos un archivo que exporte la función y lo llamamos
funcion.h
:
extern int add_valores(int a, int b, int c);
Y ahora en nuestro archivo principal podemos importar este paquete:
#include <stdio.h>
// llamada del archivo funcion.h:
#include "function.h"
void main(void){
printf("El total es %d\n", add_valores(1,2,3));
}
Importante
Para compilar este programa ejecutamos gcc -o miprograma main.c function.c
El preprocesador¶
El archivo de intercambio que creamos antes llamado funcion.h
es un archivo de preprocesamiento, podemos saltarnos ese paso y añadir directamente la línea al codigo principal:
#include <stdio.h>
extern int add_valores(int a, int b, int c);
void main(void){
printf("El total es %d\n", add_valores(1,2,3));
}
Importante
Es necesario ejecutar la compilación de ambos al mismo tiempo igualmente