Cómo aprender a programar en lenguaje C bajo sistema operativo Linux
Este artículo presenta los conocimientos básicos necesarios para la programación en lenguaje C en LINUX. En este artículo, aprenderemos lo siguiente:
Compilación del programa fuente
p>. Preparación de Makefile
Enlace a la biblioteca del programa
Depuración del programa
Archivo de encabezado y ayuda del sistema
-- -------- ------------------------------------------ -------- --------------------
1. Compilación del programa fuente
En Linux A continuación, si queremos compilar un Programa fuente en lenguaje C, necesitamos usar el compilador gcc de GNU. Usemos un ejemplo para ilustrar cómo usar el compilador gcc
Supongamos que tenemos el siguiente programa fuente muy simple (hello.c):
p>
int main(int argc, char **argv)
{
printf("Hola Linux\n");
}
Para compilar este programa, sólo necesitamos ejecutarlo desde la línea de comando:
gcc -o hello hello.c
gcc compile El compilador generará un hola archivo ejecutable para nosotros. Ejecute ./hello y podrá ver el resultado del programa en la línea de comando
gcc significa que usamos gcc para compilar nuestro programa fuente. Pídale al compilador que genere un archivo ejecutable llamado hola
y hello.c es nuestro archivo de programa fuente. El compilador gcc tiene muchas opciones. En términos generales, solo necesitamos saber cuáles son algunas de ellas. Ya conocemos la opción -o, que indica el nombre del archivo ejecutable que necesitamos generar.
La opción -c indica que solo requerimos que el compilador genere el código de destino, sin necesidad. para generar el archivo ejecutable. Archivo de ejecución La opción -g significa que le pedimos al compilador que nos proporcione información para depurar el programa en el futuro. Conociendo estas tres opciones, podemos compilar el programa fuente simple que escribimos. Si desea conocer más opciones, puede ver la documentación de ayuda de gcc, que tiene muchas descripciones detalladas de otras opciones.
2. Preparación de Makefile
Supongamos que tenemos el siguiente programa. , el código fuente es el siguiente:
/* main.c */
#include "mytool1.h"
#include "mytool2.h"< / p>
int main(int argc, char **argv)
{
mytool1_print("hola");
mytool2_print("hola " );
}
/* mytool1.h */
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif
/* mytool1.c */
#include "mytool1.h"
void mytool1_print(char *print_str)
{
printf("Este es mytool1 prin
t s\n", print_str);
}
/* mytool2.h */
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif
/* mytool2.c */
#include "mytool2. h"
void mytool2_print(char *print_str)
{
printf("Este es mytool2 print s\n", print_str);
}
Por supuesto, dado que este programa es muy corto, podemos compilarlo así
gcc -c main.c
gcc -c mytool1.c
gcc -c mytool2.c
gcc -o main main.o mytool1.o mytool2.o
En este caso, también podemos generar el programa principal, y también es muy problemático de vez en cuando. Pero si lo pensamos bien, si un día modificamos uno de los archivos (por ejemplo, mytool1.c)
¿lo tendremos? ¿Quieres volver a ingresar el comando anterior? Tal vez dirás: Esto es fácil de resolver. Puedo escribir un script SHELL y pedirle que lo complete por mí. Sí, para este programa, puedo reproducirlo. Pero cuando ponemos las cosas para pensar de manera más complicada, si nuestro programa tiene cientos de programas fuente, ¿el compilador necesita recompilarlos uno por uno? Por esta razón, los programadores inteligentes han creado una buena herramienta para hacer esto. es make. Solo necesitamos ejecutar el siguiente make para resolver el problema anterior. Antes de ejecutar
make, primero debemos escribir un archivo muy importante: Makefile para el programa anterior, un posible Makefile. es: # Este es el Makefile para el programa anterior
main: main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
gcc -c main.c
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c
Con Este Makefile, cada vez que modificamos cualquier archivo en el programa fuente, siempre que ejecutemos el comando make, nuestro compilador solo compilará y modificará los archivos que modificamos. Ella ni siquiera quiere procesar archivos relacionados con archivos
Aprendamos cómo se escribe Makefile.
En Makefile, las líneas que comienzan con # también son líneas de comentarios. Lo más importante en Makefile es la descripción de las dependencias del archivo. El formato general es:
objetivo: componentes
regla TAB
La primera línea representa dependencias. La segunda línea son reglas. >Por ejemplo, el Makefil que tenemos arriba
La segunda línea del archivo e
main: main.o mytool1.o mytool2.o
Indica que el objeto dependiente (componentes) de nuestro principal objetivo (objetivo) es principal. o mytool1 .o mytool2.o
Cuando el objeto dependiente se modifica después de modificar el objetivo, se debe ejecutar el comando especificado en la línea de regla, tal como lo decía la tercera línea de nuestro Makefile anterior. debe ejecutarse gcc -o
main main.o mytool1.o mytool2.o Tenga en cuenta que el TAB en la línea de regla indica que hay una tecla TAB. El Makefile tiene tres variables muy útiles. $@, $^, $
int main(int argc, char **argv)
{
valor doble;
printf("Valor: f\n ", valor);
}
Este programa es bastante simple, pero cuando lo compilamos con gcc -o temp temp.c, aparece el error. aparecerá a continuación
/tmp/cc33Kydu.o: En función `main':
/tmp/cc33Kydu.o(.text 0xe): referencia indefinida a `log'.
collect2: ld devolvió 1 estado de salida
Este error se produce porque el compilador no puede encontrar la implementación específica de log. Aunque incluimos el archivo de encabezado correcto, aún necesitamos conectarnos al archivo. cierta biblioteca al compilar En Linux, para
usar funciones matemáticas, debemos conectarnos a la biblioteca matemática, para lo cual necesitamos agregar la opción -lm gcc -o temp temp.c
-lm puede compilar correctamente. Algunas personas pueden preguntar, ¿por qué no nos conectamos a la biblioteca cuando usamos la función printf? Así es, para la implementación de algunas funciones de uso común, el compilador gcc se conectará automáticamente. algunas bibliotecas de uso común, por lo que no necesitamos especificarlas nosotros mismos. A veces necesitamos especificar la ruta de la biblioteca al compilar el programa. En este momento, necesitamos usar
-L del compilador. opción para especificar la ruta. Por ejemplo, si tenemos una biblioteca en /home/hoyt/mylib, necesitamos agregar
-L/home/hoyt/mylib al compilar. No es necesario indicar las rutas, siempre que estén en la ruta de la biblioteca predeterminada. La ruta de la biblioteca predeterminada del sistema es /lib
/usr/lib /usr/local/lib en estas tres rutas. Biblioteca, no necesitamos especificar la ruta. Hay otra pregunta. A veces usamos una función determinada, pero no sabemos el nombre de la biblioteca. Conozco la respuesta a esta pregunta. Solo tengo una forma estúpida. Primero, fui a la ruta de la biblioteca estándar para ver si hay alguna biblioteca relacionada con la función que utilicé. De esta manera, encontré el archivo de biblioteca de la función del hilo. (libpthread .a).
Por supuesto, si no puede encontrarlo, solo hay una forma estúpida. Por ejemplo, si quiero encontrar la biblioteca donde se encuentra la función sin, la tengo. usar el comando nm -o /lib/*.so|grep p>
singt; ~/sin, y luego mirar el archivo ~/sin y buscarlo allí.
En el archivo sin, encontraré una línea como libm-2.1.2, por lo que: 00009fa0 W sin Entonces sé sin.
En la biblioteca libm-2.1.2.so, solo uso la opción -lm (elimino la lib al frente y la marca de versión en la parte posterior, y solo queda m, por lo que es -lm ).
p>
Si sabes cómo encontrarlo, dímelo rápidamente. Te lo agradeceré mucho. 4. Depuración del programa.
¡Es poco probable! Para que el programa que escribimos tenga éxito de una vez, habrá muchos errores en nuestro programa que no podemos imaginar. En este momento, debemos depurar nuestro programa
El más utilizado. El software de depuración es gdb. Si desea utilizar la interfaz gráfica, descargue el depurador, ahora puede elegir xxgdb. Recuerde agregar la opción
-g al compilar. Con respecto al uso de gdb. el archivo de ayuda de gdb. Como no he usado este software, no puedo decirle cómo usarlo.
Pero no me gusta usar gdb. Por lo general, use el valor de la variable intermedia en el programa para depurar el programa. Por supuesto, puede elegir su propio método y no es necesario aprender de otros. Hoy en día, existen muchos entornos IDE que ya tienen sus propios depuradores. Puedes elegir algunos y probarlos para encontrar el que más te guste.
5. Archivos de encabezado y ayuda del sistema
A veces solo conocemos la forma general de una función. no recuerda la expresión exacta, o no recuerda en qué encabezado está la función. El archivo está explicado. En este momento podemos pedir ayuda al sistema
Por ejemplo, si queremos saber. la forma exacta de la función fread, solo necesitamos ejecutar man fread
El sistema generará la función Explicación detallada y el archivo de encabezado donde se encuentra esta función explica si queremos escribir la descripción. esta función, cuando ejecutamos man
write, el resultado de salida no es el que necesitamos.
Porque lo que queremos es la descripción de la función de escritura, pero lo que sale es el descripción del comando de escritura Para obtener la descripción de la función de escritura, necesitamos usar man 2 write.
2 significa que usamos La función de escritura es una función de llamada al sistema, y también existe. una función de biblioteca que usamos comúnmente 3 para indicar que la función es C. Recuerde, man es nuestro mejor asistente en cualquier momento
--- -------------. ------------------------------- ------------- -------------
Bien, eso es todo por este capítulo, con este conocimiento podremos entonces adentrarnos en la apasionante aventura de la programación en C bajo Linux