C y C++ desde cero: historia, diferencias, sintaxis y ejemplos prácticos
Guía de programación desde cero
C y C++: fundamentos, diferencias y ejemplos prácticos
Descubre dos lenguajes esenciales para comprender cómo funciona el software, controlar los recursos del equipo y crear desde sistemas operativos hasta videojuegos.
C ofrece sencillez, velocidad y control cercano al hardware; C++ amplía esa base con clases, plantillas, una biblioteca estándar moderna y varios paradigmas de programación.
Conceptos esenciales
¿Qué son C y C++?
Ambos son lenguajes compilados, portables y de propósito general. Un compilador traduce su código fuente a instrucciones ejecutables para una plataforma concreta, lo que permite obtener programas muy eficientes.
C: pequeño y directo
Su modelo se apoya en funciones, estructuras, punteros y gestión explícita de memoria. Es habitual en sistemas operativos, controladores, firmware, bibliotecas y dispositivos integrados.
C++: multiparadigma
Añade abstracciones como clases, sobrecarga, plantillas, excepciones y contenedores. Se utiliza en videojuegos, motores gráficos, navegadores, finanzas y aplicaciones de alto rendimiento.
Origen y evolución
De los laboratorios Bell al software moderno
La historia de estos lenguajes está ligada al desarrollo de Unix y a la búsqueda de software eficiente que también pudiera trasladarse entre equipos.
1972: nace C
Dennis Ritchie desarrolló C en Bell Labs a partir de B. C permitió reescribir gran parte de Unix y combinar portabilidad con acceso de bajo nivel.
1979–1985: llega C++
Bjarne Stroustrup comenzó «C with Classes» en Bell Labs. El lenguaje adoptó el nombre C++ en 1983 y su primera versión comercial apareció en 1985.
Estándares en evolución
C y C++ se normalizan mediante ISO. Sus revisiones incorporan mejoras manteniendo una fuerte preocupación por el rendimiento y la compatibilidad.
Comparación rápida
Diferencias principales entre C y C++
La elección depende del proyecto, la plataforma, las bibliotecas disponibles y el nivel de abstracción que necesites.
| Característica | C | C++ |
|---|---|---|
| Estilo principal | Procedimental | Procedimental, orientado a objetos y genérico |
| Organización | Funciones y estructuras | Funciones, clases, espacios de nombres y módulos |
| Memoria dinámica | malloc, calloc y free | RAII, contenedores y punteros inteligentes |
| Biblioteca | Biblioteca estándar de C | Biblioteca estándar con cadenas, vectores, algoritmos y más |
| Errores | Códigos de retorno y errno | Códigos, tipos de resultado y excepciones |
Preparar el entorno
Compilar el primer programa
GCC y Clang son compiladores muy extendidos. Guarda el ejemplo como hola.c para C o hola.cpp para C++, abre una terminal en esa carpeta y ejecuta la orden correspondiente.
# C con avisos y estándar C17
gcc -std=c17 -Wall -Wextra -Wpedantic hola.c -o hola_c
./hola_c
# C++ con avisos y estándar C++20
g++ -std=c++20 -Wall -Wextra -Wpedantic hola.cpp -o hola_cpp
./hola_cpp
Sintaxis fundamental
Variables, decisiones, bucles y funciones en C
Este ejemplo declara tipos, recorre un arreglo, llama a una función y utiliza una condición. main es el punto de entrada del programa y devolver cero comunica que terminó correctamente.
#include <stdio.h>
double promedio(const int valores[], size_t cantidad) {
long suma = 0;
for (size_t i = 0; i < cantidad; ++i) {
suma += valores[i];
}
return cantidad > 0 ? (double) suma / cantidad : 0.0;
}
int main(void) {
int notas[] = {8, 7, 10, 9};
size_t cantidad = sizeof notas / sizeof notas[0];
double resultado = promedio(notas, cantidad);
printf("Promedio: %.2f\n", resultado);
if (resultado >= 5.0) {
puts("Curso aprobado");
}
return 0;
}
Direcciones y memoria
Entender los punteros
Un puntero almacena la dirección de otro objeto. El operador & obtiene una dirección y * accede al valor apuntado. Son fundamentales para modificar datos, recorrer memoria y comunicarse con APIs de bajo nivel.
#include <stdio.h>
void intercambiar(int *a, int *b) {
int temporal = *a;
*a = *b;
*b = temporal;
}
int main(void) {
int izquierda = 10;
int derecha = 20;
intercambiar(&izquierda, &derecha);
printf("%d, %d\n", izquierda, derecha);
return 0;
}
Abstracciones de C++
Clases, objetos y encapsulación
Una clase reúne datos y operaciones, controla qué detalles son públicos y mantiene sus invariantes. El constructor establece un estado inicial válido.
#include <iostream>
#include <string>
#include <utility>
class Cuenta {
private:
std::string titular_;
double saldo_;
public:
Cuenta(std::string titular, double saldo_inicial)
: titular_(std::move(titular)), saldo_(saldo_inicial) {}
bool retirar(double cantidad) {
if (cantidad <= 0 || cantidad > saldo_) {
return false;
}
saldo_ -= cantidad;
return true;
}
[[nodiscard]] double saldo() const {
return saldo_;
}
};
int main() {
Cuenta cuenta{"Ana", 250.0};
cuenta.retirar(40.0);
std::cout << "Saldo: " << cuenta.saldo() << '\n';
}
C++ moderno
Contenedores, algoritmos y memoria segura
La biblioteca estándar evita reinventar estructuras habituales. std::vector gestiona una secuencia dinámica, los algoritmos expresan la intención y RAII vincula la vida de un recurso con la de un objeto.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> valores{12, 5, 19, 8, 14};
std::ranges::sort(valores);
const auto suma = std::accumulate(valores.begin(), valores.end(), 0);
const auto media = static_cast<double>(suma) / valores.size();
std::cout << "Mínimo: " << valores.front() << '\n'
<< "Máximo: " << valores.back() << '\n'
<< "Media: " << media << '\n';
}
En C++ moderno, prefiere objetos automáticos, contenedores y punteros inteligentes como std::unique_ptr. Reserva manualmente con new y delete solo cuando una API o una necesidad muy concreta lo justifique.
Proyecto completo
Una lista de tareas con C++
Este pequeño programa combina entrada de datos, cadenas, un vector, un bucle y validación. Permite añadir tareas hasta que el usuario escribe fin.
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> tareas;
std::string texto;
std::cout << "Escribe tareas; usa 'fin' para terminar.\n";
while (std::getline(std::cin, texto) && texto != "fin") {
if (!texto.empty()) {
tareas.push_back(texto);
}
}
std::cout << "\nTareas guardadas:\n";
for (std::size_t i = 0; i < tareas.size(); ++i) {
std::cout << i + 1 << ". " << tareas[i] << '\n';
}
}
Errores y buenas prácticas
Escribe programas fiables
Inicializa y valida
Inicializa variables, comprueba entradas, tamaños y resultados. Nunca supongas que un archivo se abrió o que una reserva de memoria funcionó.
Limita la propiedad manual
En C libera cada recurso exactamente una vez. En C++, usa RAII, contenedores y punteros inteligentes para expresar quién posee cada recurso.
Prueba con herramientas
Compila con avisos, crea pruebas automáticas y usa sanitizadores como -fsanitize=address,undefined durante el desarrollo.
Ruta de aprendizaje
¿Por cuál deberías empezar?
Empieza por C si deseas comprender con claridad memoria, representación de datos, sistemas integrados o APIs de bajo nivel. Elige C++ si tu meta es crear aplicaciones grandes y eficientes usando abstracciones, bibliotecas y herramientas modernas.
Base compartida
Aprende tipos, operadores, control de flujo, funciones, compilación, depuración y organización en varios archivos.
Especialización
En C profundiza en punteros y memoria; en C++ avanza hacia RAII, biblioteca estándar, clases, plantillas y concurrencia.
Conclusión
Dos lenguajes para entender y construir software eficiente
C enseña a observar de cerca los datos, la memoria y el sistema. C++ permite conservar ese rendimiento mientras construye abstracciones de alto nivel. Practica con programas pequeños, compila con avisos y aumenta la complejidad solo cuando domines cada fundamento.
Comentarios
Publicar un comentario
Hola amigos/as dejad vuestros comentarios, gracias 🙂