static-httpd

Sitio web estático (HTML + CSS) que sostiene el blog del autor
Log | Files | Refs

commit d49b5e304fcc93f8487141452de9533c61df25ef
parent 6ee976588900811b9d172bf3dca8d491d48e7420
Author: fjbalon <fbalon@templier.es>
Date:   Fri,  3 Jul 2026 00:14:59 +0200

Añadidos artículos antiguos sobre make y punteros

Diffstat:
Mindex.html | 10++++++++++
Amake/index.html | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprogramacion-c-punteros/index.html | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprogramacion-c-punteros/punteros.png | 0
4 files changed, 173 insertions(+), 0 deletions(-)

diff --git a/index.html b/index.html @@ -394,6 +394,11 @@ <p class="info">1 de enero de 2019 · fjbalon</p><p>Qemu, que yo pronuncio como Khemu /xɛ̃mu/ -sí, el hijo de Bayek de Siwa-, es un potente software de virtualización y emulación....</p> </a> +<a href="./programacion-c-punteros/" class="article"> + <p class="title">De los punteros en el lenguaje C</p> + <p class="info">24 de noviembre de 2018 · fjbalon</p><p>Los punteros son uno de esos elementos más confusos y complejos cuando nos iniciamos en el lenguaje C, sea que vengamos de aprender directamente a programar, o sea que vengamos de otros lenguajes de ...</p> +</a> + <a href="./denis-ritchie-unix/" class="article"> <p class="title">Unix es simple. Sólo se necesita un genio para entender su simplicidad, de Denis Ritchie</p> <p class="info">2 de julio de 2018 · fjbalon</p><p>Unix es un sistema, aunque pensemos en éste de una forma abstracta y conceptual de cara a la filosofía, que se basa en módulos pequeños y simples. Sin embargo, decir que por ello Unix es simple se...</p> @@ -429,6 +434,11 @@ <p class="info">24 de mayo de 2016 · fjbalon</p><p>Buenos días. La siguiente entrada documenta cómo realizar una prueba de concepto que consiste en realizar una inyección SQL básico en un programa Java con JDBC (Java DataBase Connectivity). Ademá...</p> </a> +<a href="./make/" class="article"> + <p class="title">De las herramientas make y cmake</p> + <p class="info">1 de mayo de 2016 · fjbalon</p><p>Make es una herramienta de gestión de dependencias usada en entornos de la familia UNIX. Es una buena práctica para compilar de forma automatizada códigos compuestos y complejos, por ejemplo en có...</p> +</a> + <a href="./permisos-unix/" class="article"> <p class="title">De la heredad de permisos y propietarios de Unix</p> <p class="info">2 de abril de 2016 · fjbalon</p><p>La comprensión del fichero o archivo, file para los anglosajones, es fundamental para comprender la estructura y funcionamiento lógico de Unix. Un fichero es una colección de bytes agrupados bajo u...</p> diff --git a/make/index.html b/make/index.html @@ -0,0 +1,94 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1" /> +<title>De las herramientas make y cmake</title> +<link rel="icon" type="image/png" href="/favicon.png" /> +<link rel="stylesheet" type="text/css" href="../article.css" /> +</head> +<body> +<header> +<p class="title">De las herramientas make y cmake</p> +<p class="date">1 de mayo de 2016 • fjbalon</p> +</header> +<p>Make es una herramienta de gestión de dependencias usada en entornos de la familia UNIX. Es una buena práctica para compilar de forma automatizada códigos compuestos y complejos, por ejemplo en códigos compuestos de códigos C en distintos ficheros con distintos ficheros de cabecera <emb>.h</emb>.</p> +<p>Para preparar el funcionamiento de make es necesario crear un fichero, en el cual se especifica y se configura todo lo necesario para el proceso. Este fichero es denominado makefile. Podemos decir que son las instrucciones que make debe realizar.</p> +<p>Como añadido, make entiende los formatos y extensiones, dando una respuesta apropiada a cada tipo de archivo.</p> +<p>El formato genérico para un makefile es el siguiente:</p> +<pre><code>VARIABLES +... + +OBJETIVO: DEPENDENCIAS + COMANDO + ...</code></pre> +<p>Un makefile simple para realizar con make la compilación de un programa C sería similar al siguiente:</p> +<pre><code>hola: hola.c + gcc -o hola hola.c -I.\end{lstlisting} + +Podemos mejorarlo aún más para que sólo compile los ficheros que han cambiado desde el +último make, para ello sería similar al siguiente: + +\begin{lstlisting}[language=make] +# Vease el cambio de los ficheros .c a .o. +# Internamente make sabe que los .o son .c +# y asi los busca y compila; ignorando los +# encabezados. +CC=gcc +CFLAGS=-I. + +hola: hola.o + $(CC) -o hola hola.o</code></pre> +<p>En este caso si hiciéramos cambios en alguna de las cabeceras <emb>.h</emb> make no recompilaría los códigos C <emb>.c</emb>. Si quisiéramos, como generalmente debería ser, que esto ocurriese:</p> +<pre><code>CC=gcc +CFLAGS=-I. +DEPS = hola.h + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + +hola: hola.o + $(CC) -o hola hola.o</code></pre> +<p>Podemos mejorar el makefile añadiéndole más acciones, como una acción \textit{clean} para limpiar la compilación.</p> +<pre><code>CC=gcc +CFLAGS=-I. +DEPS = hola.h + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + +hola: hola.o + $(CC) -o hola hola.o + +clean: + rm -f hola hola.o</code></pre> +<p>E incluso podemos hacerlo más genérico y escalable declarando los nombres de los ficheros en forma de variable:</p> +<pre><code>CC=gcc +CFLAGS=-I. +DEPS = hola.h +OBJ = hola.o + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + +hola: $(OBJ) + $(CC) -o $@ $^ $(CFLAGS) + +# Podemos usar .PHONY para indicarle a +# make que el target clean en este caso +# es ficticio y no debe crear fichero; +# ya que si existiera un fichero llamado +# clean en el directorio no trabajaria. +.PHONY: clean +clean: + rm -f $(ODIR)</code></pre> +<p>Por otro lado, el <b>procedimiento CMake</b> (véase <a src="https://cmake.org">cmake.org</a>) o <i>Cross Platform Make</i> es una utilidad multiplataforma de automatización de código, que permite construir, probar y empaquetar el software. Es, en otras palabras, una suite de herramientas independientes de más alto nivel que make, y que facilita la compilación de programas C. Por ejemplo, para un fichero CMake <emb>CMakeList</emb>:</p> +<pre><code># Version minima requerida +cmake_minimum_required (VERSION 2.8) +# Nombre del proyecto +project (Hola) +# Ficheros a agregar +add_executable(hola hola.c)</code></pre> +<p>Para ejecutar CMake simplemente llamamos a su comando propio seguido del fichero CMake: <emb>cmake CMakeList</emb>. La salida de este comando será un makefile.</p> +</body> +</html> +\ No newline at end of file diff --git a/programacion-c-punteros/index.html b/programacion-c-punteros/index.html @@ -0,0 +1,67 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<meta name="viewport" content="width=device-width, initial-scale=1" /> +<title>De los punteros en el lenguaje C</title> +<link rel="icon" type="image/png" href="/favicon.png" /> +<link rel="stylesheet" type="text/css" href="../article.css" /> +</head> +<body> +<header> +<p class="title">De los punteros en el lenguaje C</p> +<p class="date">24 de noviembre de 2018 • fjbalon</p> +</header> +<p>Los punteros son uno de esos elementos más confusos y complejos cuando nos iniciamos en el lenguaje C, sea que vengamos de aprender directamente a programar, o sea que vengamos de otros lenguajes de más alto nivel, como C# o Python; los punteros suelen ser una característica que conlleva sufrimiento y sacrificio. Esto son parte de mis apuntes, para dar algo de claridad a este tema, espero que el lector pueda darle utilidad.</p> +<p>Cada posición de memoria tiene asociada una dirección que la identifica de forma única, algo así como un identificador. Dentro de ellas se almacenan instrucciones y datos. Para que al programador le resulte más sencillo referirse a una dirección de memoria se utilizan las variables, que no son más que nombres asociados a direcciones de memoria concretas.</p> +<p>Las variables de tipo puntero se utilizan para almacenar en ellas la dirección de memoria de otra variable. El puntero, como variable que es, tiene asociado su dirección de memoria; y su contenido será la dirección de memoria de otra variable. Entiendo que esto es muy confuso, quizá con la siguiente imagen esté algo más claro:</p> +<img class="color-invertible" style="width: 300px;" src="punteros.png" /> +<p>Los punteros pueden apuntar a variables previamente declaradas o a variables dinámicas. <b>La potencia de los punteros reside en poder crear (reservar memoria) y destruir (liberar memoria) una variable (dinámica) en tiempo de ejecución.</b> Un puntero ocupa normalmente 4 bytes y se declara siempre de acuerdo con el tipo de dato que apunta. Tenga en cuenta que la declaración de punteros en C se realiza anteponiendo <emb>*</emb> al nombre de la variable, tal que: <emb>int * x;</emb></p> +<p>El lenguaje C dispone de los <b>operadores de dirección (<emb>&</emb>) e indirección (<emb>*</emb>)</b>, permitiendo respectivamenta acceder a la dirección asociada a una determinada variable y acceder al contenido de ésta (zona de memoria) a la que apunta el puntero.</p> +<pre><code>int i, j, *p; +p = &i; +*p = 10; +p = &j; +*p = -2; +p = NULL;</code></pre> +<p>Voy a tratar de explicar el código anterior:</p> +<ol> +<li><emb>int i, j, *p;</emb> define las variables estáticas <emb>i</emb> y <emb>j</emb>, y el puntero <emb>p</emb>.</li> +<li><emb>p = &i;</emb> declara o asigna a la variable <emb>p</emb> la sección de memoria de la variable <emb>i</emb>.</li> +<li><emb>*p = 10;</emb> asigna a la dirección de memoria a la que apunta <emb>p</emb> el valor 10.</li> +<li><emb>p = &j;</emb> cambia el puntero a la variable <emb>j</emb>.</li> +<li><emb>*p = -2;</emb> asigna dinámicamente a <emb>p</emb> el valor -2.</li> +<li><emb>p = NULL;</emb> hace que el puntero ya no apunte a ninguna.</li> +</ol> +<p>Podemos trabajar con punteros de tipo indefinido con <emb>void *</emb>, pudiendo asignarse cualquier tipo de puntero y valor; es un puntero genérico a alguna parte donde se almacena información de algún tipo. Es el programador el responsable de definir estos "algún" eliminando esta ambigüedad.</p> +<pre><code>int x = 1; +float r = 1.0; + +void* ptr = &x; +*(int *)ptr = 2; + +ptr = &r; +*(float *) ptr = 1.1;</code></pre> +<p>Las <b>operaciones aritméticas entre punteros</b> en el lenguaje C se limitan a suma, resta, comparación y asignación. Estas operaciones a un tipo de dato x tienen automáticamente en cuenta el tamaño que ocupa ese tipo de dato en memoria. Es decir, el número de bytes necesario para almacenar un objetivo de ese tipo de dato: la suma incrementa la dirección a la que apunta el puntero teniendo en cuenta el tipo de dato al que apunte el puntero. O sea, si un puntero apunta a un tipo de dato entero y le suma 1, se desplaza el tamaño de un entero. En el caso de la resta, se decrementa la dirección.</p> +<p>Estas dos operaciones son útiles cuando trabajamos con vectores o matrices (lineal) y la suma o resta permitirían moverse entre los elementos de éste.</p> +<pre><code>int a, b, c; +int *p1, *p2; +void *p; + +p1 = &a; +*p1 = 1; + +p2 = &b; +*p2 = 2; + +p1 = p2; +*p1 = 0; + +p2 = &c; +*p2 = 3; + +p = &p1; +*p = p2; +*p1 = 1;</code></pre> +</body> +</html> +\ No newline at end of file diff --git a/programacion-c-punteros/punteros.png b/programacion-c-punteros/punteros.png Binary files differ.