Introducción

Introducción

Continuaremos en esta parte de nuestro tutorial con los complejos tipos de datos en C, y hablaremos sobre estructuras. Muchos lenguajes de programación modernos los ofrecen, una forma u otra, y también C. Como verá más adelante, las estructuras le permiten manipular datos más fácilmente, permitiéndole almacenar diferentes variables de (posiblemente) diferentes tipos bajo un solo "techo".

Estructuras iniciales

Aunque quería posponer la parte de definición para este subcapítulo, parece que no podría esperar e incluida en la introducción. Sí, amigos, eso es lo que es una estructura, y verá por capricho lo útil que es cuando le mostraré algunos ejemplos. Un paralelo interesante es el que se refiere a una tabla de base de datos: si tiene una tabla llamada usuarios (el nombre único), entonces pondrá en esa tabla los datos exactos que pertenecen directamente a los usuarios: edad, sexo, nombre, dirección, dirección, etcétera. Pero estos son diferentes tipos! No hay problema, puede hacerlo con una tabla, tal como puede hacerlo con una estructura: la edad será un entero, el género será un carbón, el nombre será una cadena y así sucesivamente. Entonces podrás acceder al miembros de la tabla fácilmente, refiriéndose al nombre de la tabla/miembro. Pero este no es un curso de base de datos, así que sigamos adelante. Pero antes de eso, echemos un vistazo a un aspecto lógico: está invitado a crear estructuras con miembros que tienen algo en común desde un punto de vista lógico, como el ejemplo anterior. Haz que sea más fácil para ti y las personas que luego mirarán tu código. Entonces, veamos cómo se traduciría la tabla de base de datos de nuestros usuarios en una estructura C:

estructura usuarios int Age; char género; nombre del personaje; char *dirección; ; 

Por favor, no olvide el punto y coma al final. Ok, me jacté de que los miembros de la estructura son fáciles de acceder. Aquí está cómo, siempre que desee acceder a la edad del usuario:

printf ("La edad del usuario es %D.\ n ", usuarios.edad); 

Pero para que ese printf funcione, tendremos que definir la edad primero. Que se puede hacer así

estructura usuarios int Age; ... usrs; USRS.edad = 25; .. 

Lo que hicimos aquí es declarar un instancia de la estructura (puede tener tantas instancias como quieras), llamada "USRS". Puede tener USRS1, USRS2, USRS3, etc., para que pueda usar estos atributos (como edad, género, dirección) en todos ellos. La segunda forma de hacer esto es declarar la estructura como lo hicimos la primera vez (e.gramo. sin instancias) y luego declare las instancias respectivas más adelante en el código:

estructura usuarios USRS1, USRS2, USRS3; 

... y luego cuide la edad, el género, la dirección, etc. como lo hicimos anteriormente.

Cuando hablamos de estructuras junto con las funciones, lo más importante de hablar es probablemente el hecho de que las estructuras se consideran como un todo, no como un compuesto hecho de varios elementos. Aquí hay un ejemplo:

void show_age (usrs i) printf ("La edad del usuario es %D.\ n ", yo.edad); printf ("El nombre del usuario es %S.\ n ", (& i)-> nombre); 

Lo que hace esta función es: toma un argumento numérico e imprime a todos los usuarios que tienen esa edad específica. Es posible que haya notado un nuevo operador en el código anterior (si no lo ha hecho, mire nuevamente). El operador "->" hace exactamente lo que hace el operador DOT, lo que le permite acceder a un miembro de la estructura, con la especificación de que se usa cuando los punteros están involucrados, al igual que el operador del DOT se usa en los casos en que los punteros no están involucrados. Una consideración más importante aquí. Dado el siguiente código:

estructura mystruct int myInt; char *mystring;  *pag; 

¿Qué crees que hará la siguiente expresión??

++p-> myint; 

Temas avanzados

Una de las cosas que verá bastante a menudo en relación con las estructuras, pero no solo, es la typeedef palabra clave. Como su nombre lo indica, le permite definir los tipos de datos personalizados, como en los ejemplos a continuación:

typeedef int longitud; / * ahora la longitud es un sinónimo de int */ typeedef char * cadena; 

Con respecto a las estructuras, Typedef básicamente elimina la necesidad de usar la palabra 's'. Así que aquí hay una estructura declarada de esta manera:

typeedef estructura colegas int Age; char género; ... colls; 

Para nuestro próximo tema, tomaremos una idea encontrada en K&R y la usaremos para ilustrar nuestro punto. Por qué? Está bien pensado y se muestra muy bien y de una manera simple lo que estamos a punto de ilustrar. Pero antes de comenzar, aquí hay una pregunta para usted: saber que C permite estructuras anidadas, ¿cree que las estructuras anidadas por medio de typedef podrían aceptarse?? Por qué?

Entonces, aquí está el siguiente tema: Arrays de estructura. Ahora que sabes de qué matrices se trata fácilmente de qué se trata esto. Sin embargo, quedan algunas preguntas: cómo implementar el concepto y, lo que es más importante, cuál podría ser el uso? El ejemplo del que hablamos pronto arrojará algo de luz sobre ambos asuntos. Supongamos que tiene un programa, escrito en C, y desea contar el número de ocurrencias de todas las palabras clave que define el estándar. Necesitamos dos matrices: una para almacenar las palabras clave y otra para almacenar el número de ocurrencias correspondientes a cada palabra clave. Esta implementación se puede escribir como tal:

char *palabras clave [nrkeywords]; int resultado [nrkeywords]; 

Mirando el concepto, pronto verá que utiliza un concepto de pares, que se describe de manera más eficiente utilizando una estructura. Entonces, debido al resultado final que necesitaremos, tendremos una matriz cuyo elemento es una estructura. Vamos a ver.

estructura Palabra clave char *palabras clave; intentos int;  keywrdtbl [nrkeywords]; 

Ahora inicializemos la matriz con las palabras clave y el número inicial de ocurrencias que, por supuesto, serán 0.

estructura Palabra clave char *palabras clave; intentos int;  keywrdtbl [] = "auto", 0, "break", 0, "case", 0, ... "while", 0; 

Su próxima y última tarea, dado que esta tarea es un poco más compleja, es escribir un programa completo que se tome como el texto para trabajar e imprimir el número de ocurrencias de cada palabra clave, de acuerdo con el método anterior.

El último tema de las estructuras con las que trataré es la cuestión de los punteros para las estructuras. Si escribió el programa en el último ejercicio, es posible que ya tenga una buena idea de cómo podría reescribirse para que pueda usar punteros en los índices. Entonces, si le gusta escribir código, puede considerar esto como un ejercicio opcional. Por lo tanto, no hay nada mucho por aquí, solo algunos aspectos, como (muy importante), debe introducir algún código adicional con cuidado adicional para que al analizar el código fuente del archivo que está escaneando para palabras clave y, por supuesto, la función de búsqueda Debe modificarse, no creará ni topará con un puntero ilegal. Consulte la parte anterior como referencia en la aritmética del puntero y las diferencias entre el uso de matrices y el uso de punteros. Otro problema con el que tener cuidado es el tamaño de las estructuras. No se deje engañar: solo puede haber una forma de obtener una estructura correcta, y eso es mediante el uso de sizeof ().

#incluir  estructura prueba int uno; int dos; char *str; flotante flt; ; int main () printf ("El tamaño de la estructura es %D.\norte", tamaño de(estructura prueba)); devolver 0;  

Esto debería devolver 24, pero eso no está garantizado, y K&R explica que esto se debe a varios requisitos de alineación. Recomiendo usar sizeOf cuando tenga dudas y supongo que nada.

Sindicatos

Debería haber alterado el título e incluir la palabra "uniones", y tal vez incluso "bitfields". Pero debido a la importancia y al patrón de uso general de las estructuras versus los sindicatos y los campos de bits, especialmente ahora que el hardware se está convirtiendo en un producto más barato (no necesariamente un pensamiento saludable, pero de todos modos), supongo que el título dirá solo "estructuras". Entonces, ¿qué es un sindicato?? Un sindicato se asemeja a una estructura, lo que difiere es la forma en que el compilador trata con el almacenamiento (memoria) para ello. En resumen, una unión es un tipo de datos complejo que puede almacenar diferentes tipos de datos, pero un miembro a la vez. Por lo tanto, independientemente de cuán grande sea la variable almacenada, tendrá su lugar, pero otros no se permitirán en la unión en ese momento preciso. De ahí el nombre "Unión". Las declaraciones y definiciones de sindicatos son las mismas que las estructuras, y está garantizado que el sindicato tomará tanta memoria como su 'miembro más grande.

Campos de bits

Si desea usar C en la programación de sistemas integrados y/o cosas de bajo nivel es su juego, entonces esta parte parecerá atractiva. Un campo de bits (algunos escriben el campo bit), no tienen una palabra clave asignada como enum o unión, y requiere que conozca su máquina. Le permite ir más allá de las limitaciones típicas basadas en palabras. Otros idiomas lo limitan. También le permite hacerlo, y esta podría ser una definición formal, "empacar" más de un objeto en una sola palabra.

Enumeros

Para comenzar con un breve hecho histórico, se introdujeron enums en C cuando C89 estaba fuera de la puerta, lo que significa que K&R carecía de este tipo ingenioso. Un enume permite al programador crear un conjunto de valores con nombre, también conocido como enumeradores, que tienen como su característica principal de que tienen un valor entero asociado con ellos, ya sea implícitamente (0,1,2 ...) o explícitamente por el programador (( 1,2,4,8,16 ...) . Esto hace que sea fácil evitar los números mágicos.

enumer Presión pres_low, pres_medium, pres_high; enumer Presión p = pres_high; 

Ahora, esto es más fácil, si necesitamos pres_low para ser 0, mediano 1 y así sucesivamente, y no tendrá que usar #defines para esto. Recomiendo un poco de lectura si estás interesado.

Conclusión

Aunque la información puede parecer un poco más condensada que antes, no se preocupe. Los conceptos son relativamente fáciles de comprender y un poco de ejercicio funcionará maravillas. Te estamos esperando en nuestros foros de Linux para una discusión adicional.

Todos los artículos de esta serie:

  • I. C Desarrollo en Linux - Introducción
  • II. Comparación entre C y otros lenguajes de programación
  • III. Tipos, operadores, variables
  • IV. Control de flujo
  • V. Funciones
  • VI. Punteros y matrices
  • VII. Estructuras
  • VIII. E/S básica
  • Ix. Estilo de codificación y recomendaciones
  • X. Construyendo un programa
  • Xi. Embalaje para Debian y Fedora
  • Xii. Obtener un paquete en los repositorios oficiales de Debian

Tutoriales de Linux relacionados:

  • Cosas para instalar en Ubuntu 20.04
  • Una introducción a la automatización, herramientas y técnicas de Linux
  • Cosas que hacer después de instalar Ubuntu 20.04 fossa focal Linux
  • Ubuntu 20.04 trucos y cosas que quizás no sepas
  • Mastering Bash Script Loops
  • Bucles anidados en guiones Bash
  • Cosas para instalar en Ubuntu 22.04
  • Mint 20: Mejor que Ubuntu y Microsoft Windows?
  • Cómo arrancar dual Kali Linux y Windows 10
  • Manipulación de Big Data para la diversión y las ganancias Parte 1