¿Cómo comparto variables entre diferentes archivos .c? [duplicate]

7 minutos de lectura

pregunta de principiante sobre la declaración C:

En un archivo .c, ¿cómo usar variables definidas en otro archivo .c?

  • Cambié tu título. Trate de hacer que el título sea más descriptivo, para que 1) las personas que puedan responderlo puedan ver fácilmente lo que está preguntando, y 2) para que otras personas que tengan la misma pregunta puedan encontrar esto y no No tengo que preguntarlo de nuevo. Al mirar la lista de preguntas, no necesitamos saber que es una pregunta para principiantes, pero hacer Necesito saber de qué se trata la pregunta. Solo un consejo para futuras preguntas. 🙂

    – jalf

    25 de junio de 2009 a las 18:51

avatar de usuario
RichieHindle

En el archivo A.c:

int myGlobal = 0;

En el archivo A.h

extern int myGlobal;

En archivoB.c:

#include "fileA.h"
myGlobal = 1;

Así es como funciona:

  • la variable vive en fileA.c
  • fileA.h le dice al mundo que existe y cuál es su tipo (int)
  • fileB.c incluye fileA.h para que el compilador conozca myGlobal antes de que fileB.c intente usarlo.

  • cuando las variables son estáticas, me da un error de enlace, “símbolo irresoluble”, ¿cómo lidiar con eso?

    usuario53670

    25 de junio de 2009 a las 18:39

  • @jfq: “estático” en un contexto que no es de clase significa “limitado a esta unidad de traducción”. es esencialmente lo contrario de “externo”. No puedes tener ambos al mismo tiempo.

    – rmeador

    25 de junio de 2009 a las 18:40

  • Solo un comentario: ¿qué sucede si el propietario de la variable es el archivo main.c y no hay main.h?

    – jdepypere

    10 mayo 2013 a las 18:50

  • @arbitter: sin un archivo de encabezado, no puede compartir la variable (a menos que coloque extern int myGlobal; directamente en el archivo de origen que quiere acceder myGlobal, pero eso es una violación desagradable de DRY). Si necesita compartir un global desde main.c, crear principal.h!

    – RichieHindle

    10 mayo 2013 a las 19:00


  • @RichieHindle: No estoy seguro si puedo hacer un main.h, pero lo pondré en otro archivo entonces, ¡gracias!

    – jdepypere

    10 mayo 2013 a las 19:08

En el 99,9% de todos los casos, es un mal diseño del programa compartir variables globales no constantes entre archivos. Hay muy pocos casos en los que realmente necesita hacer esto: son tan raros que no puedo encontrar ningún caso válido. Declaraciones de registros de hardware tal vez.

En la mayoría de los casos, debe usar funciones setter/getter (posiblemente en línea) (“públicas”), variables estáticas en el ámbito del archivo (“privadas”) o implementaciones de tipo incompletas (“privadas”).

En esos pocos casos raros en los que necesita compartir una variable entre archivos, haga lo siguiente:

// file.h
extern int my_var;

// file.c
#include "file.h"
int my_var = something;

// main.c
#include "file.h"
use(my_var);

Nunca ponga ninguna forma de definición de variable en un archivo h.

  • Publiqué esto como respuesta a un duplicado exacto de esta publicación. Siento que algunos consejos sobre el uso de variables globales eran necesarios, en lugar de simplemente enseñar ciegamente malas prácticas a otros sin hacer una advertencia primero.

    – Lundin

    29/10/2012 a las 14:15


  • Su publicación es demasiado obstinada considerando que ha exagerado lo raro que es tener un caso válido para una variable global. En mi cabeza, los semáforos binarios que gobiernan la disponibilidad de recursos en un sistema integrado tienen que ser globales. Cualquier firmware basado en RTOS que comparta recursos estará plagado de semáforos globales. De manera similar, cuando un global representa algo que realmente debería estar disponible en todas partes, puede ser más simple y rápido en términos de velocidad y desarrollo. Además, los singletons son básicamente variables globales con algo de azúcar sintáctico. ¿Demasiado simplificado? Sí, pero conceptualmente válido.

    – Antonio

    9 de agosto de 2015 a las 2:50

  • @Anthony Hay una diferencia entre variables globalesque son accesibles desde cualquier parte del programa (por lo tanto global) y variables de ámbito de archivo que son estáticos y solo se puede acceder a ellos desde el interior del archivo en el que están declarados. Esta última no es realmente una mala práctica, salvo en algunos escenarios de subprocesos múltiples. Todos los ejemplos de su comentario deben implementarse con variables de alcance de archivo.

    – Lundin

    11 de agosto de 2015 a las 19:12

  • Entonces, ahora está tratando de decir que cada global debe ser una variable de alcance de archivo, lo cual es incorrecto, especialmente en el mundo incrustado, a menos que crea que todo el código debe estar en un archivo. ¿Cómo podría saber el alcance de las variables en un código que nunca ha visto? Es extremadamente común implementar tareas de RTOS que comparten recursos y nunca colocaría varias tareas completamente ajenas en el mismo archivo. Me encantaría ver una forma de controlar el acceso a ese recurso sin semáforos globales. Este es solo un ejemplo de cuando un global es extremadamente útil; hay muchos otros

    – Antonio

    11 de agosto de 2015 a las 22:38

  • @Anthony El objetivo de la encapsulación privada es solo eso: no debe ver ni preocuparse por esas variables, fuera del archivo donde se usan. El acceso a dichas variables debe realizarse a través de funciones setter/getter (que pueden estar en línea). Los datos que pertenecen a un módulo específico deben asignarse en ese mismo módulo, y el manejo de los semáforos, si es necesario, probablemente también podría colocarse dentro de la función setter/getter. Los semáforos en sí mismos son en realidad un ejemplo perfecto de este mismo principio: no sabe ni necesita saber cómo se manejan internamente.

    – Lundin

    12 de agosto de 2015 a las 8:37

avatar de usuario
jeffp

si la variable es:

int foo;

en el archivo 2nd C usted declara:

extern int foo;

  1. Trate de evitar los globales. Si debe usar un global, vea las otras respuestas.
  2. Pásalo como argumento a una función.

Esas otras variables tendrían que declararse públicas (use extern, public es para C++), y tendría que incluir ese archivo .c. Sin embargo, recomiendo crear archivos .h apropiados para definir todas sus variables.

Por ejemplo, para hola.c, tendría un hola.h, y hola.h almacenaría sus definiciones de variables. Luego, otro archivo .c, como world.c, tendría este fragmento de código en la parte superior:

#include "hello.h"

Eso permitirá que world.c use variables que están definidas en hello.h

Sin embargo, es un poco más complicado que eso. Puede usar < > para incluir archivos de biblioteca que se encuentran en la ruta de su sistema operativo. Como principiante, pegaría todos sus archivos en la misma carpeta y usaría la sintaxis ” “.

avatar de usuario
hermano azul

El segundo archivo necesita saber sobre la existencia de su variable. Para hacer esto, declara la variable nuevamente pero usa la palabra clave extern en frente de eso. Esto le dice al compilador que la variable está disponible pero declarada en otro lugar, por lo que evita instanciarla (nuevamente, lo que causaría conflictos al vincular). Mientras tu lata Pon el extern declaración en el propio archivo C, es un estilo común tener un encabezado que lo acompañe (es decir, .h) archivo para cada .c archivo que proporciona funciones o variables a otros que tienen el extern declaración. De esta forma evitarás copiar el extern declaración, especialmente si se usa en muchos otros archivos. Lo mismo se aplica a las funciones, aunque no necesita la palabra clave extern para ellos.

De esa manera, tendría al menos tres archivos: el archivo fuente que declara la variable, es un encabezado adjunto que hace el extern declaración y el segundo archivo fuente que #includes el encabezado para obtener acceso a la variable exportada (o cualquier otro símbolo exportado en el encabezado). Por supuesto, necesita todos los archivos de origen (o los archivos de objeto apropiados) cuando intenta vincular algo así, ya que el vinculador debe resolver el símbolo que solo es posible si realmente existe en los archivos vinculados.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad