¿Alguna diferencia fundamental entre la fuente y los archivos de cabecera en C?

No entiendo bien cómo se deben separar las cosas en los archivos de fuente y encabezado de C. A menudo veo muchos proyectos con dos conjuntos de archivos con el mismo nombre (sin la extensión que denota los archivos de fuente y encabezado).

Hasta ahora, a partir de esta falta de comprensión, cuando escribí las bibliotecas, coloqué toda la clase y el código del método de la clase en un solo archivo, con la indecisión de elegir la extensión del archivo.

¿Qué debería estar en los encabezados y qué debería estar en los archivos de origen? ¿Cómo implemento esta separación?

No hay diferencia técnica . El comstackdor le permitirá incluir un archivo .c o comstackr un archivo .h directamente, si así lo desea.

Hay, sin embargo, una gran diferencia cultural :

  • Declaraciones (prototipos) van en archivos .h . El archivo .h es la interfaz para lo que se implemente en el archivo .c correspondiente.

  • Las definiciones van en archivos .c . Implementan la interfaz especificada en el archivo .h .

La diferencia es que un archivo .h puede (y generalmente será) #include d en varias unidades de comstackción (archivos .c ). Si define una función en un archivo .h , terminará en varios archivos .o , y el vinculador se quejará de un símbolo definido de forma múltiple. Es por eso que las definiciones no deben ir en archivos .h . (Las funciones en línea son la excepción.)

Si una función está definida en un archivo .c , y desea usarla de otros archivos .c , una statement de esa función debe estar disponible en cada uno de esos otros archivos .c . Es por eso que pones la statement en un .h , y #include eso en cada uno de ellos. También puede repetir la statement en cada archivo .c , pero eso conduce a una gran cantidad de duplicación de código y un desorden que no se puede reparar.

Si una función está definida en un archivo .c , pero no desea usarla de otros archivos .c , no es necesario declararla en el encabezado. Es esencialmente un detalle de implementación de ese archivo .c . En ese caso, también haga que la función sea static , para que no entre en conflicto con las funciones con nombres idénticos en otros archivos.

¿Qué debería estar en los encabezados y qué debería estar en los archivos de origen?

Normalmente, los encabezados contienen uno o más de los siguientes:

  • Declaración de funciones (excepto estadísticas)
  • Declaración de variables (típicamente global)
  • Declaración de tipo definido por el usuario ( struct lectura, union , etc.)
  • Definición de macro

Los archivos fuente por otro lado tienen:

  • Definición de función / variable
  • Declaración de función estática y definición (no desea exponerlos a sus clientes)
  • Definición variable
  • Algunos prefieren definir funciones en línea (C99) en un encabezado

¿Cómo implemento esta separación?

La regla de una definición es tu amiga.

Recuerde, si está escribiendo una biblioteca, esto es lo que su cliente puede ver. Por lo tanto, sea útil y proporcione toda la información que pueda para que usen su biblioteca. Los archivos de origen normalmente se comstackn y se suministran en formato binario.

Y por cierto, C no tiene el concepto de clases.

Normalmente, los archivos de encabezado contienen declaraciones, los archivos de origen contienen código.

Entonces, si en el archivo fuente Ac necesita una función implementada en el archivo fuente Bc , simplemente incluya Bh para tener su statement.

Hay poca diferencia fundamental entre los archivos .c y .h (aunque algunos comstackdores pueden rehusarse a comstackr un archivo .h sin procesar). La diferencia es más por convención.

Normalmente, el archivo .h proporciona la API y .c proporciona la implementación.

Por lo tanto, el archivo .h contendría solo lo que necesitan otros archivos de origen para acceder a las facilidades proporcionadas por su archivo .c. Por lo tanto, los archivos .h proporcionarían la función de prototipos de funciones globales, declaraciones de variables globales (si realmente las debe tener) y las estructuras y otros tipos utilizados por ellas. (No exponga una estructura si el API solo requiere un puntero a la estructura).

Las funciones en línea a menudo también se incluyen en los archivos .h, pero algunas pautas de encoding prefieren el uso de una extensión separada (por ejemplo, .inl)

Todas las otras implementaciones de funciones, la definición e inicialización de variables y declaraciones de variables y funciones locales (estáticas) se encontrarán en el archivo .c.