Generación de código fuente de Gcc xgcc
Desarrollo secuencial.
Compilador GNU C
Depuración de aplicaciones GCC con gdb
También puede ver otras herramientas útiles de programación en C distribuidas con Linux. Estas herramientas incluyen la preparación del código fuente.
Bonito programa de impresión, herramientas de depuración adicionales, herramienta de generación automática de prototipos funcionales.
(Prototipo de función automática).
Compilador GNU C
El compilador GNU C (GCC) lanzado con Slackware Linux es un compilador ANSI C y .
Compilador. Si está familiarizado con los compiladores de C en otros sistemas operativos o plataformas de hardware, podrá hacerlo muy rápidamente.
Domina con éxito GCC.
Usar GCC
Usualmente seguido de algunas opciones y un nombre de archivo para usar el compilador GCC. El uso básico del comando gcc es el siguiente:
gcc[opciones][nombre de archivo]
Las operaciones especificadas por las opciones de la línea de comando se realizarán en cada archivo dado en el comando línea. Esto se describe en la siguiente sección.
Algunas de las opciones que más utilizas.
Opciones de GCC
GCC tiene más de 100 opciones de compilación disponibles. Es posible que muchas de estas opciones nunca se utilicen.
Pero algunas de las opciones principales se utilizan con frecuencia. Muchas opciones de GCC contienen varios caracteres. Por lo tanto,
debe especificar un guión separado para cada opción y, como la mayoría de los comandos de Linux, no puede
un guión seguido de un grupo de opciones. Por ejemplo, los dos comandos siguientes son diferentes:
gcc -p -g test
gcc -pg test
El primer comando le dice a GCC que compile test. c y
y agregue información de depuración al ejecutable. El segundo comando simplemente le dice a GCC que lo construya para el comando gprof.
Analizar información.
Cuando compilas un programa sin opciones, GCC crea un programa llamado .
. Por ejemplo, el siguiente comando generará un documento llamado a.out en el directorio actual.
Número de piezas:
prueba gcc
Puedes usar la opción -o compile para especificar el nombre del archivo ejecutable que se generará en lugar de . out p>
Por ejemplo, para compilar un programa C llamado count.c en un archivo ejecutable llamado count, ingresaría
el siguiente comando:
gcc - o count Count
-
-
Nota: cuando se utiliza la opción -o, -o debe ir seguido de un nombre de archivo.
-
-
GCC también tiene una opción de compilación que especifica cuánto manejará el compilador. La opción c le dice a GCC que compile solo el código fuente.
Traducir al código de destino y omitir los pasos de ensamblaje y conexión. Esta opción se utiliza con mucha frecuencia mientras se compila.
Múltiples programas en C son más rápidos y fáciles de administrar. De forma predeterminada, GCC crea un archivo de código objeto.
. oExtendido.
La opción de compilación S le indica a GCC que detenga la compilación. Una vez producido GCC, el archivo en lenguaje ensamblador se genera como código C.
La extensión predeterminada para los archivos generados en lenguaje ensamblador es . s. La opción -E indica al compilador que precompila solo archivos de entrada.
Procesamiento. Cuando se utiliza esta opción, la salida del preprocesador se envía a la salida estándar en lugar de almacenarse en un archivo.
Opciones de optimización
Cuando utiliza GCC para compilar código C, intentará completar la compilación en el menor tiempo posible y hará que el código compilado sea muy fácil de depurar. La facilidad de depuración significa que el código compilado tiene el mismo orden de ejecución que el código fuente. Después de la compilación, el código de
no está optimizado. Hay muchas opciones para indicarle a GCC que dedique más tiempo a la compilación, sacrificando la facilidad de uso.
Basado en la depuración, genera archivos ejecutables más pequeños y más rápidos. Las más típicas de estas opciones son -O y -O2.
Proyecto.
La opción O le dice a GCC que realice optimizaciones básicas en el código fuente. Estas optimizaciones mejorarán el proceso en la mayoría de los casos.
La ejecución de la secuencia es más rápida. La opción -O2 le dice a GCC que genere código lo más pequeño y rápido posible. La opción -O2
hará que la compilación sea más lenta que cuando se usa -O, pero generalmente el código generado se ejecutará más rápido.
Además de las opciones de optimización -O y -O2, existen algunas opciones de bajo nivel para generar código más rápido. Estas
opciones son muy específicas y se utilizan mejor si comprende completamente qué efecto tendrán en el código compilado.
Qué efecto utilizar. Para obtener una descripción detallada de estas opciones, consulte la página Guía de línea de comandos de GCC.
Escriba man gcc on.
Opciones de depuración y creación de perfiles
GCC admite varias opciones de depuración y creación de perfiles. De estas opciones, -g y -pg son las más utilizadas.
Opciones.
La opción g le dice a GCC que genere información de depuración que puede ser utilizada por el depurador GNU para depurar su programa.
GCC proporciona muchas características que otros compiladores de C no tienen. En GCC, puedes usar -g y -O(
Esto es muy útil porque puedes acercarte lo más posible al producto final.
Depura tu código. Cuando usas ambos Al elegir esta opción, debes saber que parte del código que escribes ya es excelente.
Para obtener más información sobre la depuración de programas C, consulta la siguiente sección "Depuración de C con gdb"
<. p>Programa".La opción -pg le dice a GCC que agregue código adicional a su programa y, cuando se ejecute, generará gprof.
Analizar información para mostrar la hora consumo del programa Para obtener más información sobre gprof, consulte "gprof" I.
Depuración de programas GCC con gdb
Linux. Incluye un depurador GNU llamado gdb. Potente depurador para programas C y C++. Le permite observar la estructura interna del programa y el uso de memoria del programa mientras se ejecuta.
Situación Las siguientes son algunas de las características proporcionadas por Guangfa. Banco:
Le permite monitorear los valores de las variables en su programa.
Le permite establecer puntos de interrupción para evitar que el programa se ejecute en líneas de código específicas.
Escriba gdb en la línea de comando y presione Enter para ejecutar gdb.
Se iniciará Gdb y verá algo similar en la pantalla:
GDB. es software gratuito y puede distribuir copias del mismo.
En Bajo ciertas condiciones, escriba "mostrar copia" para ver las condiciones.
GDB no tiene absolutamente ninguna garantía, escriba "mostrar garantía";
GDB 4.14 (i486). -slak ware-Linux), Copyright 1995 Free Software Foundation
Inc.
(Guangfa Bank)
Cuando inicia gdb, puede usar el comando. También puede especificar muchas opciones en la línea:
Para ejecutar gdb:
Cuando ejecute gdb de esta manera, especifique directamente el programa. para ser depurado. Esto le indica a gdb que lo instale
Ingrese el archivo ejecutable llamado
Archivo principal o que se conecte a un programa en ejecución. Escriba gdb -h en esta línea para obtener una breve descripción de estas opciones.
Compilar código para depurar
Para que gdb funcione correctamente, debe incluir información de depuración cuando su programa. se compila.
Incluye todas las variables del programa, el tipo, la asignación de direcciones en el archivo ejecutable y el número de línea del código fuente.
Gdb utiliza esta información para conectar el código fuente al código máquina.
Utilice la opción -g para activar las opciones de depuración al compilar.
Comandos básicos de Gdb
Gdb admite muchos comandos que le permiten implementar diferentes funciones. Estos comandos se cargan desde archivos simples.
Comandos complejos que permiten inspeccionar el contenido de la pila llamada. La Tabla 27.1 enumera los comandos que usará al depurar con gdb.
Algunos comandos. Para conocer el uso detallado de Guangfa Bank, consulte la página de guía de Guangfa Bank.
Tabla 27.1. Comandos básicos de gdb.
Descripción del orden de vida
Archivo carga el archivo ejecutable a depurar.
Kill finaliza el programa que se está depurando.
Lista enumera parte del código fuente que genera el archivo ejecutable.
A continuación ejecuta una línea de código fuente sin ingresar a la función.
Step ejecuta una línea de código fuente e ingresa a la función.
Ejecutar ejecuta el programa actualmente depurado.
Salir y terminar gdb
Watch le permite monitorear el valor de una variable cuando cambia.
Break establece un punto de interrupción en el código. Cuando el programa se ejecuta aquí, lo suspenderá.
Make le permite reconstruir el ejecutable sin salir de gdb.
Shell le permite ejecutar comandos de shell UNIX sin salir de gdb.
Gdb admite muchas de las mismas funciones de edición de comandos que los programas shell de UNIX. Puede presionar la tecla Tab como en bash o
como en tcsh y dejar que gdb complete un comando único por usted. Si no es único, Guangfa Bank
enumerará todos los comandos coincidentes. También puede utilizar las teclas del cursor para desplazarse hacia arriba y hacia abajo por los comandos del historial.
Ejemplo de aplicación de China Guangfa Bank
Esta sección utiliza un ejemplo para enseñarle paso a paso cómo usar gdb para depurar un programa. El programa para depurar es bastante sencillo.
Pero muestra una aplicación típica de gdb.
Los programas a depurar se enumeran a continuación. Este programa se llama Saludos y muestra un simple
saludo y luego los enumera en orden inverso.
# include & ltstdio.h & gt
main()
{
char my_string[] = "Hola"; /p>
mi_impresión(mi_cadena);
mi_impresión 2(mi_cadena);
}
void mi_impresión ( char *cadena)
{
printf("La cadena es %s\n ", cadena);
}
void my_print2 (char *cadena)
{
char * cadena2
int tamaño, I;
tamaño = strlen(cadena);
cadena 2 =(char *)malloc(tamaño+1);
for(I = 0;i<size;i++)
cadena 2[tamaño-I]= cadena[I];
cadena2[tamaño+1] = `\0 '
printf("La cadena impresa al revés es %s \n ", cadena 2);
}
Compílelo usando el siguiente comando:
Prueba de prueba
Al ejecutar el programa, se mostrarán los siguientes resultados:
Cadena es hola
La cadena impresa al revés es
La primera línea de salida es correcta, pero la segunda La línea impresa no es lo que esperábamos. Lo que esperamos
El resultado previsto debería ser:
La cadena impresa al revés es ereht olleh
Por alguna razón, mi función _print2 no funciona correctamente. Usemos gdb para ver dónde radica el problema.
¿Dónde está? Primero escriba el siguiente comando:
Saludo de Groadfa
-
-
Nota: al compilar el programa de saludo, recuerde activar la opción de depuración.
-
-
Puedes usar esto si olvidas pasar el programa que deseas depurar como argumento a gdb al ingresar el comando.
Utilice el comando de archivo en el indicador de gdb para cargarlo:
(gdb) archivo de saludo
Este comando cargará el ejecutable del saludo tal como lo haría usted. Mismo como cargarlo en la línea de comando de gdb.
En este momento, puede usar el comando ejecutar de gdb para ejecutar el saludo. Cuando GDB se está ejecutando.
El resultado será así:
(Banco de Desarrollo de Guangdong) Ejecutar
Inicia el programa:/root/greeting
Cadena es Hola
La cadena impresa al revés es
El programa salió con el código 041
Esta salida es la misma que si se ejecuta fuera de gdb. La pregunta es: ¿por qué no podemos oponernos a la India?
Para descubrir el quid de la cuestión, podemos establecer un punto de interrupción después de la declaración for de la función my_print2.
El método principal es escribir el comando list tres veces en el gdb. solicitar listar Código fuente:
lista (gdb)
lista (gdb)
lista (gdb)
Consejo: en el Indicador de gdb Presione Entrar para repetir el último comando.
-
El resultado de la primera vez que escribe el comando de lista es el siguiente:
1 # include & ltdio.h & gt
p>
2
3 main()
4 {
5 char my_string[] = "Hola";
6
7 mi_impresión(mi_cadena);
8 mi_impresión 2(mi_cadena);
9 }
10
p >Si presiona Enter, gdb ejecutará el comando list nuevamente y dará el siguiente resultado:
11 my_print(char * string)
12 {
p>
13 printf("La cadena es %s\n ", cadena);
14 }
15
16 my_print2 (char *string)
17 {
18 char * string 2;
19 int size, I
20 Presione Enter nuevamente. , enumere los programas de saludo restantes:
21 size = strlen(string);
22 string 2 =(char *)malloc(size+1);
23 for(I = 0;i<size;i++)
24 cadena 2[tamaño-I]= cadena[I];
25 cadena2[tamaño +1] = `\0 '
26 printf("La cadena impresa al revés es %s\n ", cadena 2
27 }
Según el programa fuente listado, Puede ver que el lugar para establecer el punto de interrupción es la línea 24 en el símbolo del sistema de gdb.
Escriba el siguiente comando bajo el operador para establecer un punto de interrupción:
(gdb) break 24
Guangfa Bank responderá de la siguiente manera:
Punto de interrupción 1 en 0x139: Archivo saludo.c, línea 24
(Guangfa Bank)
Ahora escriba el comando ejecutar nuevamente, esto producirá el siguiente resultado:
p>Inicie el programa:/root/greeting
La cadena es hola
Punto de interrupción 1 en Greeting.c, my_print 2(cadena = 0x bfffdc 4 "hola")
:24
24 string2[size-i]=string[i]
Puedes ver el error estableciendo un punto de observación Para observar el valor de cadena2[tamaño-i] variable.
Cómo generar, escribiendo:
(gdb) fob chain 2[size - i]
Guangfa Bank responderá de la siguiente manera:
Punto de observación 2: Cadena 2 [tamaño - i]
Ahora puedes recorrer el bucle for usando el siguiente comando:
(GF)Siguiente
Después del primer ciclo, gdb nos dice que el valor de string2[size-i] es 'h'. GDB usado.
La siguiente pantalla le indicará esta información:
Punto de observación 2, cadena 2 [tamaño - i]
Valor anterior = 0 `\000 '
Nuevo valor = 104 ' h '
my_print2(string = 0xbfffdc4 "Hola") en saludo.c:23
23 for(I = 0; i<size ;i++)
El valor es el esperado. Los resultados de varios bucles posteriores son correctos. Cuando i=10, el valor de la expresión
cadena2[tamaño-i] es igual a 'e', el valor de tamaño-I es igual a 1 y el último carácter ha sido
Se copia en una nueva cadena.
Si continúas haciendo el bucle, verás que a string2[0] no se le asigna un valor, y
es el primer carácter de la nueva cadena porque la función malloc. se inicializan a nulo.
carácter (nulo). Entonces el primer carácter de cadena2 es el carácter nulo. Esto explica por qué se está imprimiendo.
No hay salida para string2.
Ahora que hemos identificado el problema, es fácil corregir el error. Tienes que ponerlo en código.
El desplazamiento del primer carácter de cadena2 se cambia a tamaño-1 en lugar de tamaño. Esto se debe a que el tamaño de la cadena2 es 12, pero el desplazamiento inicial es 0 y los caracteres de la cadena van desde el desplazamiento 0 hasta el desplazamiento 0.
10, el desplazamiento 11 está reservado para caracteres nulos.
Existen muchas formas de modificar el código para que funcione correctamente. Una es establecer otra que sea 1 más pequeña que el tamaño real de la cadena.
Este es el código de la solución:
# include & ltstdio.h & gt
main()
{ p>
char my_string[] = "Hola";
my_print(my_string);
my_print 2(my_string);
}
my_print (char *cadena)
{
printf("La cadena es %s\n ", cadena);
}
my_print2 (char *cadena)
{
char * cadena2
int tamaño, tamaño2, I;
tamaño = strlen(cadena);
tamaño 2 = tamaño-1;
cadena 2 =(char *)malloc(tamaño+1);
for( I = 0;i<size;i++)
cadena 2[tamaño 2-I]= cadena[I];
cadena2[tamaño] = `\0 '
printf("La cadena impresa al revés es %s\n ", cadena 2);
}
Otra herramienta de programación en C
La distribución Slackware Linux También incluye algunas herramientas de desarrollo en C que aún no hemos mencionado. Esta sección
presentará estas herramientas y su uso típico.
xxgdb
Xxgdb es una interfaz gráfica de gdb basada en el sistema X Window. xxgdb incluye la línea de comando.
Todas las características de la versión gdb. xxgdb le permite ejecutar comandos comunes con solo presionar un botón. Activar.
Los puntos también se muestran gráficamente.
Puedes ejecutarlo escribiendo el siguiente comando en una ventana de Xterm:
xxgdb
Puedes inicializar XXgdb con cualquier opción de línea de comando válida en gdb. Además, xxgdb también tiene una
La Tabla 27.2 enumera algunas opciones de línea de comando únicas.
Tabla 27.2. Opciones de línea de comando xxgdb.
Descripción de elementos opcionales
Db_name especifica el nombre del depurador utilizado. El valor predeterminado es gdb.
Db_prompt especifica el indicador del depurador, que por defecto es gdb.
Gdbinit especifica el nombre del archivo de comando para inicializar gdb, el valor predeterminado es. gdbinit.
Nx le dice a xxgdb que no se ejecute. archivo gdbinit.
Bigicon utiliza iconos grandes.
Llamadas
Puede utilizar la siguiente ruta en el sitio FTP sunsite.unc.edu:
/pub/Linux/devel/lang/c/calls . tar .z
Para recibir la llamada, algunas distribuciones de CD-ROM de Linux más antiguas también las incluyen. Debido a que es una herramienta útil, la presentamos aquí también. Si lo encuentra útil, obtenga una copia desde un BBS, FTP
o en otro CD-ROM. Llama al preprocesador de GCC para procesar el programa fuente dado.
Secuenciar archivos y luego generar diagramas de árbol de llamadas de funciones en estos archivos.
-
Nota: Para instalar la llamada en su sistema, inicie sesión como superusuario y realice los siguientes pasos: 1. solución.
Haz clic y extrae el archivo. 2. Llame a untar en el subdirectorio creado después de ingresar el CD. 3. Asígnele un nombre
Mueva el archivo de llamada al directorio /usr/bin. 4. Mueva el archivo llamado llamadas.1 al directorio.
/usr/man/man1. 5. Elimine el directorio /tmp/calls. Estos pasos los seguirá el programa de llamadas y sus referencias.
South Page está instalado en su sistema.
-
Cuando las llamadas generan resultados de seguimiento de llamadas, proporciona el texto de la función entre paréntesis después de la función.
Nombre de archivo:
Main[test.c]
Si la función no está en el archivo proporcionado a las llamadas, las llamadas no sabrán dónde está la función llamada. viene de.
Entre ellos, solo se muestra el nombre de la función:
Imprimir función
Las llamadas no generan funciones recursivas ni estáticas. La función recursiva se ve así:
Fact& lt& lt& ltfactorial.c & gt& gt& gt
La función estática se ve así:
total[en calcular. c static]
Por ejemplo, supongamos que la siguiente rutina se maneja llamando:
# include & ltstdio.h & gt
main() p>
{
char my_string[] = "Hola";
my_print(my_string);
my_print 2(my_string
}
my_print (char *cadena)
{
printf("La cadena es %s\n ", cadena);
}
my_print2 (char *string)
{
char * string2
int tamaño, tamaño2, I;
tamaño = strlen(cadena);
tamaño 2 = tamaño-1;
cadena 2 =(char *)malloc( tamaño+1);
for(I = 0;i<size;i++)
cadena 2[tamaño 2-I]= cadena[I];
cadena2[tamaño] = ` \0 '
printf("La cadena impresa al revés es %s\n ", cadena 2);
}
Se producirá el siguiente resultado:
1 principal [test.c]
2 mi_impresión [test.c]
3 imprimir f
4 mi_impresión2 [test. c]
5 strlen
6 malloc
7 printf
Las llamadas tienen muchas opciones de línea de comandos para configurar diferentes formatos de salida. Para obtener más información sobre estas opciones, consulte.
Página de guía de llamadas. Esto se hace escribiendo llamadas -h en la línea de comando.
cproto
Cproto lee archivos de programa fuente C y genera automáticamente una declaración prototipo para cada función. Usando cproto, puedes
definir prototipos de funciones te ahorrará mucho tiempo al escribir programas.
Si dejas que cproto maneje el siguiente código:
# include & ltstdio.h & gt
main()
{< / p>
char my_string[] = "Hola";
my_print(my_string);
my_print 2(my_string);
} p>
my_print (char *cadena)
{
printf("La cadena es %s\n ", * cadena);
}
my_print2 (char *cadena)
{
char * cadena2
int tamaño, tamaño2, I;
tamaño = strlen(cadena);
tamaño 2 = tamaño-1;
cadena 2 =(char *)malloc(tamaño+1);
for(I = 0;i<size;i++)
cadena 2[tamaño 2-I]= cadena[I];
cadena2[tamaño] = `\0 '
printf("La cadena impresa al revés es %s\n ", cadena 2);
}
Obtendrá el siguiente resultado:
/* test.c */
int main(void);
int my_print(char * string) ;
int my _ print 2(char * string);
Esta salida se puede redirigir a un archivo de inclusión que define el prototipo de la función.
Sangría
La herramienta de sangría es otra herramienta de programación incluida en Linux. Esta herramienta simplemente.
Crea un hermoso formato de sangría para tu código. La sangría también tiene muchas opciones para especificar cómo desea formatearla.
Para obtener más información sobre estas opciones, consulte la página de guía de sangría y escriba sangría -h en la línea de comando.
El siguiente ejemplo es el resultado predeterminado para la sangría:
Ejecute código c antes de la sangría:
# include & ltstdio.h & gt
main () {
char my_string[] = "Hola";
my_print(my_string);
my _ print 2( my_string);}
my_print (char *cadena)
{
printf("La cadena es %s\n ", * cadena
); }
my_print2 (char *cadena) {
char * cadena2
int tamaño, tamaño2, I;
tamaño = strlen( cadena);
tamaño 2 = tamaño-1;
cadena 2 =(char *)malloc(tamaño+1);
for(I = 0 ;i<size;i++)
cadena 2[tamaño 2-I] = cadena[I];
cadena2[tamaño] = ` \0 '
printf ("La cadena impresa al revés es %s\n ", cadena 2);
}
Ejecute el código C sangrado:
# include & ltstdio. h & gt
main()
{
char my_string[] = "estás bien";
my_print(my_string);
mi_impresión 2(mi_cadena);
}
mi_impresión (char *cadena)
{
printf ("La cadena es %s\n ", * cadena);
}
my_print2 (char *cadena)
{
char * cadena2
int tamaño, tamaño2, I;
tamaño = strlen (cadena);
tamaño 2 = tamaño-1;
cadena 2 =(char *)malloc(tamaño+1);
for(I = 0;i<size;i++)
cadena 2[tamaño 2-I] = cadena [I];
cadena2[tamaño] = `\0 '
printf("La cadena impresa al revés es %s\n ", cadena 2);
}
La sangría no cambia la esencia del código, solo cambia. Mejora la apariencia del código y lo hace más legible.
Esto siempre es algo bueno.
gprof
Gprof es un programa instalado en el directorio /usr/bin del sistema Linux. Le permite
analizar su programa para comprender qué parte del programa tarda más en ejecutarse.
Gprof te dirá cuántas veces se llama a cada función del programa y cuánto tiempo tarda en ejecutarse cada función.
Esta información es útil si quieres mejorar el rendimiento de tu programa.
Para poder utilizar gprof en un programa, debes agregar la opción -pg al compilar el programa. Esto hará que
el programa genere un archivo llamado gmon.out cada vez que se ejecute. gprof utiliza este archivo para generar información de perfiles.
Después de ejecutar su programa y generar el archivo gmon.out, puede utilizar el siguiente comando para obtener la carta de análisis.
Interés:
gprof & ltprogram_name & gt
El parámetro program_name es el nombre del programa que generó el archivo gmon.out.
-
Consejo: gprof genera muchos datos de creación de perfiles, por lo que si desea examinar estos datos, es mejor redirigir la salida.
Ponlo en un archivo.
-
F2c y p2c
F2c y p2c son dos programas de conversión de código fuente. f2c convierte código FORTRAN en código C,
P2c convierte código Pascal en código C. Ambos programas se instalarán cuando instale GCC.
.
Si tiene algún código escrito en FORTRAN o Pascal que necesita ser reescrito en C, f2c y p2c.
Muy útil para ti. El código C generado por estos dos programas se puede compilar directamente con GCC sin modificaciones.
Si el programa FORTRAN o Pascal a convertir es relativamente pequeño, puede utilizar f2c o p2c directamente.
No es necesario añadir ninguna opción. Es posible que quieras utilizar esto si el programa que deseas convertir es grande y contiene muchos archivos.
Algunas opciones de línea de comando.
Para usar f2c en un programa FORTRAN, ingrese el siguiente comando:
f2c my_fortranprog.f
-
Nota: f2c requiere conversión La extensión del programa es . f o a.f .
-
Para reemplazar un programa Pascal con un programa C, ingrese el siguiente comando:
p2c my_pascalprogram.pas
Los nombres de archivo del código fuente C generado por estos dos programas son los mismos que los nombres de archivo originales, excepto por la extensión. f.
O. pas se convirtió. c.
========================================== === ========================
Si estás haciendo ingeniería, aún necesitas saber hacer. Se recomienda que aprendas a hacer.
============================================ === =======================