Teclado mecanico, modificado, en primer plano.
Work

Como comenzar a desarrollar Software

Primeros pasos
Fundamentos
Programación

Primeros pasos en el desarrollo de software, conozca las bases del inmenso mundo del desarrollo, cuales son los elementos primarios, y como contextualizarse en el arte.

Tipos de Datos

Los tipos de datos, son de las principales estructuras primitivas o de primer nivel de un lenguaje, con estos podemos entender como estructurar la información, a partir de usar estos tipos.

Ahora bien los lenguaje de programación, proponen un conjunto de estructuras de datos primitivas, con las cuales el lenguaje opera.

A partir de los avances en teoría de lenguajes de programación, logrados con el lenguaje C, tenemos una definición prácticamente universal de estos tipos de datos primarios.

Numero - Integer - int

Un Numero es una representación en el sistema Decimal de una unidad minima de 8 bits osea un byte

Calculadora de valores Hexadecimales

es decir que cuando hablamos de los números primitivos de las maquinas estos partían de esta estructura, en la imagen podemos ver un convertidor de bits, los campos iluminados en blanco representan una serie de bits encendidos en este caso 8, partiendo del 0 al 7, en bus de datos (Información estructurada) de 64 bits representado en los campos numéricos, así mismo en la conversión, vemos que esto representa 0xFF, que es un valor Hexadecimal, así mismo su valor en decimal 255.

en la actualidad por cuestiones funcionales se toma los números como estructuras de datos de 16, 32, y 64 bits, lo que aumenta en escala su representación decimal, así mismo si esta estructura requiere de signo, es necesario que exista un control sobre esto, para ello la mayoría de sistemas, usan la mitad de la estructura binaria, para representar valores negativos, lo que quiere decir que por ejemplo un numero con signo de 16 bits, puede tomar valores, de -32767 a 32767.

int number = 32766;
unsigned int unsigned_number = 65535;
short int = 255;
long int = 2147483647;

Decimal - Floating-point, Double - float, double

Cuando los sistemas computacionales ganaron mayor capacidad por encima de los bits, es decir podían procesar en bytes, el instituto IEEE, definió el estándar IEEE 754 para operar valores de punto flotante, el cual define la estructura para estos datos en un procesador de 32 bits.

en el caso de los double, es la misma teoria pero con el doble de bits 64.

float number = 16777216.000000; // Max value
double doubleNumber = 16777216.000000;

Carácter, Letra - Character - char

En el caso de los caracteres la convención se baso en 2 factores. El primer factor, la herencia del telégrafo, la cual en su momento especifico un conjunto de valores y símbolos, en el intercambio de información, a esto se le conoce como la tabla ASCII, una representación simbólica de base numérica.

Tabla antigua de valores ASCII

Este conjunto con el tiempo ha evolucionado a lo que se le conoce como la actual tabla, una representación de 255 valores, en 3 categorías, Valores control, Valores Imprimibles, y Valores de Extensión.

Gracias a esto el segundo factor es que la estructura de un carácter, es la de un conjunto de 8 bits, o 1 byte, convirtiéndole en la estructura de datos minima por excelencia.

a día de hoy este estándar hace parte de un nuevo estándar de caracteres llamado Unicode el cual unifica todos los símbolos usados en el lenguaje humano.

Cadenas, Arreglos - Array, Strings - Array[]

Teniendo en cuenta que una de las principales características de los tipos de datos primitivos, es la estructura secuencial en bits, un array es un conjunto de datos estructurados secuencial mente, lo que quiere decir que se forma una especie de cadena datos seguidos, pertenecientes a un grupo mayor, a esto de le definió como Arreglos, Arrays, Cadenas o Strings.

A este conjunto de datos se accede mediante un indice, este indice es un valor numéricos, de 0 al tamaño del arreglo - 1, que quiere decir que un arreglo de tamaño 5 tiene indices del 0 al 4.

Visualización de un Arreglo de datos

Estructuras de control

La estructuras de control, son construcciones que permiten controlar el flujo de ejecución de un programa.

if - if/else - elseif

La estructura “if”, nos permite evaluar una condición, y en caso de que esta sea verdadera, el programa ejecutara las instrucciones dentro de esta estructura.

if (a = b) { printf("a is equal to b"); }

La estructura “if/else”, no solo nos permite evaluar una condición sino también ejecutar un proceso en caso de que la evaluación sea falsa.

if (a = b) {...} else { printf("a is NOT equal to b"); }

La estructura “else if”, nos permite realizar una evaluación adicional, cuando una evaluación es falsa.

if (a = b) {...} else if (a < 5) { printf("A is less than 5 and not equal B"); }

En las evaluaciones computacionales nos enfrentamos a un contexto donde prima la el universo booleano, y el contexto de los tipos de dato.

Esto quiere decir que la algebra booleana es un elemento principal y de acá salen las operaciones lógicas, conjunción, disyunción y negación que serán esenciales en la definición de condiciones dentro del código.

así mismo el contexto de tipos de dato plantea unos limites de operación donde ciertos datos no son comparables con otros, en algunos lenguajes de un nivel superior, plantean contextos especiales que enriquecen el este contexto, por ejemplo en c no podemos comparar Strings, sin embargo en python si podemos.

Bucles

Los Bucles son estructuras que nos permiten ejecutar un proceso repetidamente hasta cumplirse una condición.

While

El bucle While (Mientras), ejecuta un proceso definido en el bucle mientras que una condición es verdadera, su principal característica es la simple evaluación de dicha condición, abriendo la puerta a bucles infinitos, y los llamados motores.

while (1) { printf("Este mensaje es infinito.\r");}
while (breaker == 100) { printf("Este mensaje es infinito si a es 100.\r");}
For

El bucle For (para), ejecuta un proceso para un sistema el cual en cada iteración evalúa una condición y ejecuta una actualización.

for (int times = 0; times == 1000000; times = times + 1) {printf("ten times, %d", times);}
Do/While

Do/While, no es un Bucle en si, Do/While es una estructura previa a la definición de un bucle while, que va a garantizar que el proceso de un bucle while se ejecute al menos una vez.

// Common use
int huevo = 0;
do { printf("gallina, %d", huevo); } while (huevo == 1);

Hay formas de como lograr un comportamiento parecido a este en el bucle for y es la definición sin condición, algo contra intuitivo a su uso pero con utilidades.

for (int times = 0; ; times++) { printf("No limit times, %d"); break;}

Control de flujo en bucles

existen algunos comandos que son en el lenguaje que sirven para influir en el flujo de las iteraciones de un bucle.

Break

Break, nos permite finalizar las iteraciones de un bucle, su nombre nos evoca a que rompe con el flujo de iteaciones.

for (int times = 0; ; times++) { printf("No limit times, %d"); break;} // Break es el limite
// Break on While
int iterationBreaker = 0;
while(iterationBreaker < 100) { 
    if (iterationBreaker == 42) { break; }
    printf("All less 64, %d\r", iterationBreaker);
    iterationBreaker++;
}

Funciones

Las funciones son elementos de primer nivel de los lenguajes de programación, esto quiere decir que puede ser tratadas como un elemento o entidad dentro del lenguaje, eso incluye ser usadas como variables, argumentos, y ser el resultado de una función en si misma.

#include <stdio.h>
// Función que toma un puntero a función como argumento 
void ejecutar_funcion(void (*func)()) {
    printf("Ejecutando función...\n"); func();
}
// Función que imprime un mensaje 
void imprimir_mensaje() {
    printf("Hola, mundo!\n");
} 
int main() {
    // Llamada a la función ejecutar_funcion 
    // con la función imprimir_mensaje como argumento 
    ejecutar_funcion(imprimir_mensaje);
    return 0; 
}

Librerías y Módulos

Un Archivo de código fuente de programación estructurada, esta segmentado en 3 partes principales, cabecera, función principal, funciones extra.

en el caso de C, este código seria:

// Un programa de C
// Cabecera
#include <stdio.h> // Libreria stdio.h / standard in-out
void print(); // Declaración de función.
// Funcion Principal
int main() {
    print(); // Uso de funciones.
    return 0; 
}
// Funciones Extra
void print() { printf("Hey..."); } // Definición de función

sin embargo también un código de C puede contener funciones que no están definidas en el mismo archivo, esto lo hace mediante el uso de librerías que especifican las funciones disponibles.

igual mente la estructura fuente es muy parecida:

// File: extra_functions.c
#include "extra.h"

void print() { printf("Y Olee..."); }

void otherFunction() {}

Archivo librería:

// File: extra.h
#include <stdio.h>
void print();
void otherFunction();

en otros lenguajes su tratamiento puede ser diferente, sin embargo la estructura y propósito son los mismos.

Python

# main.py
from circle import calculate_area

def main():
    radius = 5.0
    area = calculate_area(radius)
    print("Area of the circle:", area)

if __name__ == "__main__":
    main()
# circle.py
import math

def calculate_area(radius):
    return math.pi * radius ** 2

JS

// main.js
const { calculateArea } = require('./circle');

function main() {
    const radius = 5.0;
    const area = calculateArea(radius);
    console.log("Area of the circle:", area);
}

main();
// circle.js
function calculateArea(radius) {
    return Math.PI * radius ** 2;
}

module.exports = { calculateArea };

Rust

// main.rs
mod circle;

fn main() {
    let radius = 5.0;
    let area = circle::calculate_area(radius);
    println!("Area of the circle: {}", area);
}
// circle.rs
pub fn calculate_area(radius: f64) -> f64 {
    3.14159 * radius * radius
}

Ruby

# main.rb
require_relative 'circle'

radius = 5.0
area = Circle.calculate_area(radius)
puts "Area of the circle: #{area}"
# circle.rb
module Circle
  def self.calculate_area(radius)
    Math::PI * radius ** 2
  end
end

Make Y Ejecutables

El Software, tiene varias etapas, la primera, su desarrollo o construcción es una etapa donde el lenguaje tiene gran importancia, es decir el lenguaje define una forma de ejecutarse, como ser interpretado, y si su solución cuenta con un compilado o ejecutable, así mismo en los lenguajes modernos define mucho mas, la filosofía, la gestión de software de terceros, mecanismos de trasporte y demás.

Así pues existen herramientas que apoyan los procesos en el lenguaje, uno de ellos, en el caso de C, es la herramienta make, una herramienta parte de la Suite de Software de GNU en el 90, para automatizar los procesos de construcción, herramientas parecidas existen en otro tipo de lenguajes.

Así mismo también existe el scripting un mecanismo del mismo sistema operativo, que permite automatizar procesos, existente en UNIX gracias a la consola, por ejemplo Bash, y en el ecosistema de Windows Batch.

Aquí hay unos ejemplos para compilar un programa sencillo de C, usando makefiles, y Scripts

CC = gcc
CFLAGS = -Wall -Wextra -std=c99
OUT = program
SRC_DIR = ./src/
SRC_MAIN = main.c
BUILD_DIR = ./build/

build: $(SRC_MAIN)  
       mkdir -p ./build  
       $(CC) $(CFLAGS) -o $(BUILD_DIR)$(OUT) $(SRC)

clean:
       rm -rf ./build
#!/bin/bash

CC=gcc
CFLAGS="-Wall -Wextra -std=c99"
OUT=program
SRC_DIR=./src/
SRC_MAIN=main.c
BUILD_DIR=./build/

build() {
    mkdir -p $BUILD_DIR
    $CC $CFLAGS -o $BUILD_DIR$OUT $SRC_DIR$SRC_MAIN
}

clean() {
    rm -rf $BUILD_DIR
}

case "$1" in
    build)
        build
        ;;
    clean)
        clean
        ;;
    *)
        echo "Uso: $0 {build|clean}"
        exit 1
        ;;
esac

exit 0