C es un lenguaje estructurado y modular durante años ha sido la base de la programación, en la enseñanza incluso es un icono que sirve para entender las bases y funcionamiento de lo que ahora llamamos programación orientada a objetos, cabe señalar que a la capacidad de un lenguaje de procesar información de formas diferentes se les conoce como “paradigmas de la programación”
Paradigmas de la programación:
Hice esta introducción por que durante años como alumno y como profesor eh escuchado el típico; “C esta muerto por que no aprendemos otra cosa”, tu sistema operativo esta corriendo en c, los servidores corren gracias a c, los titanes del software no existirían sin C, además como mencione es un lenguaje perfecto para aprender bases y entender como funcionan algunas cosas que un futuro les ayudará
Empezamos
Como recomendación siempre que haya dudas recomiendo checar la documentación de c para gnu: https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html
Sintaxis de C:
En c la sintaxis basica es
tipo nombre_dato = valor ;
los comentarios se ponen con // y la funcion que nunca debe faltar es main mas adelante abordaremos funciones por ahora solo recuerda que es la mas importante.
_Ejemplo: _
voidmain(){
int a=5 ;
}
como iras notando el símbolo “;” sirve para el cierre de cualquier sentencia; "Cualquier instrucción ejecutable"
viste el “int” bueno a eso es lo que se le conoce como tipo de dato.
Tipos de dato:
int, char , bool(solo existe en c++), float, double
los tipos de datos sirven para guardar un elemento en memoria y leerlo de tal manera que se conozca su valor, recordemos que todo se maneja en bits.
main (){
int a = 10; //a es una variable con un valor de 10 guardado en a dirección de a//como es un entero el sistema sabe que vale 4bytes(varia dependiendo la computadora) así que lo convierte a binario 1010// y rellena con ceros hacia adelante a completando 4 octetos 00000.......1010 //entonces para que sirve el tipo de dato, le dice al programa cuantos bytes guardar y cuantos leer dependiendo si se lee o se escribe en la memoria.
}
Librerias:
C esta repleto de librerías estándar y otras definidas por poxis, en este parte se abordarán las mas esenciales a la hora de trabajar en C que son las estándar.
#include<stdio.h> // el #include es la forma en la que le decimos al compilador de c que mande a llamar ese codigo en el archivo .h // y con "<>" le indicamos que la libreria se encuentra en la direccion de librerias del compilador que varia dependiendo el so en el que se trabaje//comunmente en mingw/lib/stdio.h#include<stdlib.h>#include<string.h>voidmain(){
int a = 10;
}
funciones de librerias:
stdio.h es realmente la standard input output library es decir que es la librería mediante la cual se accede a las funciones de entrada y salida de datos
stdlib.h esta es importante y extensa pues nos deja acceder a funciones para controlar el sistema operativo, o manejar la memoria del programa, entre otros
string,h nos proporciona funciones para trabajar con cadenas de char, que como veremos adelante son importantes para los arreglos de char
//este ejemplo es el hello world usando todo lo que hasta ahora sabemos#include<stdio.h> //obtenemos las funciones de entrada y salida, printf es la de salidavoidmain(){
printf("Hello world"); // usamos printf para imprimir "Hello world" en la consola
}
estamos listos para hablar de funciones
una función es una forma de hacer las cosas de una forma modular diviendo el codigo en pequeños trozos de código ç
sintaxis de una función
tipo_dato_que_retorna nombre_funcion(argumentos){
//bloque de codigo
}
Ejemplo:
#include<stdio.h>intsum(int a,int b){
// sum regresa un valor entero, y recibe dos enteros que copia en variables a y b , esto significa que a y b de la función es diferente al del mainreturn a+b ;
}
voidmain(){
int a,b;
a=19;
b=20;
printf("Hello World: La suma de a:%d y b:%d es igual a: %d",a,b,sum(a,b));
}
cuando una función no retorna nada usa void, si pensaste el main tiene void enfrente es justo por que no retorna nada, otra cosa interesante de este codigo es que la función sum recibe valores por copia.
es decir que en memoria
a(main) y b(main) son diferentes de a(sum) y b(sum) esto es por que son segmentos de codigo distintos los “{}” aislan bloques de codigo convirtiendo cada bloque en uno independiente y de esta forma las variables allí declaradas son locales en ese bloque, entonces como le dices a una funcion que modifique una variable recibiéndola por referencia.
Para entender esto veamos que hace & y *
Punteros
Puntero: Es una variable que guarda direcciones, podemos ver una variable como una casa que contiene algo adentro, y esa casa tiene una dirección, entonces podemos ver un puntero como un directorio en donde guardas la dirección de esa casa
#include<stdio.h>voidsum(int *a, int c){
printf("Valor de c: %d , dirección de c:%x",c,&c);
printf("Valor de a: %d , dirección de a:%p",*a, a);
// aqui veremos como la a de sum tiene la dirección de a del main y el puntero "*a" me regresa el valor que esta en "a"
*a= 6; // *a voy al valor de a y lo modifico es como pedir la direccion guardada en a ya que es un puntero e ir a la casa a poner otra cosa adentro de esa cosa
}
intmain(){
int a=10 ;
printf("Valor de a: %d , dirección de a:%x",a,&a);
sum(a,a);
return1;
}
Estructuras
El fin de todo esto es hace una stack y entenderla por lo que falta ver a ahora el struct que lo podemos entender como un contenedor de datos
suele ser lo mas cercano una clase.
#include<stdio.h>#include<stdlib.h> //incluye malloc struct persona{
int edad;
char *nombre; // un vector de cadenas o sea un string
};
typedefstruct perro{
int edad;
int altura;
} perro ;
intmain(){
struct persona per;
perro pe; // usando el typedef define un nuevo tipo por lo que struct perro se convierte en solo perro//acceso a datos
per.edad=10;
pe.edad=10// puntero a estructura
perro *punteroper;
punteroper=malloc(sizeof (perro));
punteroper->edad=10; // en una estructura se puede acceder a los miembros a traves del simbolo -> //otra forma de haceer eso como se ha visto anteriormente es ir a la direccion y modificarla
(*punteroper).edad=5;
}
Ahora si veamos una pila que hice mientras enseñaba c:
//main.c #include"Stack.h"#include <stdio.h> int main() {
int n;
scanf("%d",&n);
Stack Pila;
Pila = start(Pila);int aux;while ((aux=getchar())!='\n'){
Pila = push(Pila,aux);
}
while (empty(Pila)){
printf("%c\n",(char)top(Pila));
Pila=pop(Pila);
}
//7u7 que lastima que termino el festival de hoy ;c // () []// detallar algoritmo // ()[][]()()// ()[])// (([])[])// return0;
}
//Stack.h#ifndef __STACK_H__#define __STACK_H__/*
TAD Pila
Descripción: La pila es una estructura de datos de tipo LIFO (Last input First output), esta constituida por una collecion de datos que son similares en tipo
*/typedefstruct nodo {
int elemento;
struct nodo *anterior;
} *Stack,nodo,*head;
//push: Inserta un elemento en el tope de la pila//regresa la el head, recibe la pila y el elementohead push(Stack stack,int elemento);
//pop: saca el valor que esta en el topehead pop(Stack stack);
//top: Regresa el valor en el topeinttop(Stack stack);
//inicialiazarStack start(Stack stack);
//retorna 0 vacia, 1 tiene algointempty(Stack stack);
#endif
//Stack.c#include"Stack.h"#include<stdlib.h>Stack start(Stack stack){
returnNULL;
}
intempty(Stack stack){
//NULL=0x000000=falseif (stack)return1;
return0 ;
}
// (4)->(3)->(1)->null// |head push(Stack stack, int elemento){
head newnode = malloc(sizeof(nodo));
newnode->elemento= elemento;
newnode->anterior=stack;
return newnode;
}
head pop(Stack stack){
if (stack){// si la pila es diferente de NULL
head aux = stack->anterior;
free(stack);
return aux;
}
returnstack; //or null
}
inttop(Stack stack){
returnstack->elemento;
}
La programación estructurada modular no solo es sobre dividir codigo en segmentos llamados funciones si no que tambien se crean modulos completos que funcionan independientemente uno de otro en este caso stack.h es un archivo que contiene la definición del modulo Stack mientras que en stack.c se crean las funciones del prototipo, y ya en main.c se usa la librería para implementarse.