2011-11-29 10 views
11

Tengo un programa ANSI C que comprende dos archivos. El primer archivo contiene la función main() y el segundo archivo contiene otras funciones a las que llama el primer archivo. Antes de la definición main() función, he colocado el siguiente código:¿Cómo hacer global constante (trabajo a través de múltiples archivos) en el programa C?

#define PI 3.14159265358979323846 

pero el segundo archivo no vi esta variable. El primer archivo lo ve bien. Luego, coloqué esta misma línea en el segundo archivo (manteniéndolo en el primer archivo como se muestra arriba), antes de las definiciones de función, pero aún así el segundo archivo no lo ve. Las cosas siempre compilan bien, pero al rastrear la variable PI en gdb, muestra "No symbol "PI" in current context."

¿Cómo hacer que PI sea una constante global visible en todos los archivos compilados en la aplicación?

EDIT/UPDATE:

Sobre la base de la respuesta hasta ahora, he creado el siguiente archivo:

myheader.h

#ifndef my_header_stuff 
#define my_header_stuff 
    #define PI 3.1415926535897932384626433832795 
#endif 

y en los dos archivos que quiero para ver este PI constante, he incluido este archivo de la siguiente manera:

file1.c

#include <stdio.h> 
#include <stdlib.h> 
#include "myheader.h" 
int main(void) { 
    etc... 
} 

y Archivo2.c

#include <stdio.h> 
#include <stdlib.h> 
#include "myheader.h" 
double interesting_function(void) { 
    etc... 
} 

Preguntas:

  1. Cuando uso GDB para depurar, b PI devuelve (en ambos archivos, el mismo resultado) "Ningún símbolo "PI" en el contexto actual ". Sin embargo, las matemáticas que dependen de PI se calculan correctamente. ¿Hay alguna manera de ver PI en gdb?

  2. ¿Puedo incluir también las dos líneas para stdio y stdlib en el archivo myheader.h?

  3. ¿Puedo incluir también cualquier prototipo de función en el archivo myheader.h? Si lo hago, y luego digamos que creo un archivo3.c que no requiere ninguno de estos prototipos porque no usa esas funciones, ¿hay algún daño?

+0

Siempre ponga todas las definiciones en archivos .c y declaraciones (incluyendo macros) en archivos .h.Eso debería resolver el problema el 99% del tiempo. – JosephH

+0

Gracias JosephH, ¿me pueden ayudar con la mecánica de esto? Ver mi intento anterior. – ggkmath

+0

Ver la respuesta que acabo de publicar – JosephH

Respuesta

3
  1. Es normal que una definición de macro no aparezca en GDB. Es porque GCC reemplaza cada PI con el valor real de pi.
  2. Sí. En tu caso, no duele. Si el archivo .h contiene un prototipo (generalmente se llaman declaraciones) que usa un tipo que está definido en otro lugar, simplemente puede #include en sus archivos de encabezado
  3. Sí. Puedes declarar el prototipo de función que quieras y no hará ningún daño en términos de la funcionalidad de tu programa. El compilador ni siquiera verificará la existencia de las definiciones de esas funciones a menos que realmente las llame desde otro lugar.
+0

Gracias JosephH !!! Otra pregunta ... Originalmente coloqué el #define directamente en cada archivo, que parecía funcionar bien en el archivo1.c pero no en el archivo2.c (sin errores de compilación, pero el resultado fue matemáticamente falso). Usar #include es como cortar y pegar contenido en un archivo, ¿verdad? ¿Por qué el enfoque myheader.h produce resultados diferentes? ¿No son ambas las soluciones que solo confían en '#define NAME value'? O, si no puedes explicarlo, tal vez fue mi confusión de depuración. – ggkmath

+0

No creo que obtendría resultados diferentes. ¿Podría verificarlo? – JosephH

2

Me declaro PI en el archivo de cabecera para insertar esta archivo de cabecera para todos los archivos de origen

Usted debe colocar la declaración de funciones, macros en el archivo de cabecera (y tal vez algunas funciones en línea simples) Implementación debe ser colocado en los archivos .c

// edité respuesta a la respuesta a tu comentario

+0

¿Deberían los prototipos de función de todos los archivos colocarse también en el archivo de encabezado? Empecé a hacer esto, luego lo solté cuando encontré empíricamente que las funciones que no se llamaban en un archivo en particular no necesitaban tener sus prototipos allí, y luego me pregunté si algo podría romperse o ser ineficiente si existiera esta redundancia. – ggkmath

+0

He editado mi respuesta –

+0

Gracias Jan. ¿Usaría #define PI 3.14159 para declararlo en el encabezado? De ser así, ¿no incluiría un #include solo como lo tengo actualmente? Si no, ¿cómo? – ggkmath

1

se puede crear una variable global.

//file1.c 
int my_global; 


//file2.c 
extern int my_global; 
//code using my_global... 

Tenga en cuenta que el uso del preprocesador está desaconsejado en su mayoría.

También tenga en cuenta que la definición M_PI sugerida por otros no está disponible en el último estándar C (C99) por lo que no puede confiar en ella.

+0

¿Por el valor de pi? –

+0

¿Están ambos colocados antes de las definiciones de función? – ggkmath

+0

@ggkmath Sí, si desea que * my_global * sea utilizado por esas funciones. – Beginner

2

Una macro no es una variable, y no aparecerá en gdb como una variable. Las cosas están compilando bien porque están funcionando bien; solo tienes las expectativas incorrectas para gdb.

En general, una macro que se necesita en más de un lugar se debe definir en un archivo de encabezado que se incluye donde sea que se necesite; por ejemplo, la macro M_PI ya está definida como pi en el estándar incluye math.h.

La otra cosa que puedes hacer es tener const int PI = 3.14159etcetc; en un archivo y extern const int PI; en todos los demás, pero esto es un dolor, ya que requiere la definición del valor de existir en exactamente una unidad compilación.

+1

Diría que tener el valor de una constante en un solo lugar es realmente un plus ...;) –

+0

Es desafortunado, pero 'M_PI' no es estándar c. – u0b34a0f6ae

0

Si está trabajando únicamente con las definiciones estándar de matemáticas, el archivo de cabecera estándar math.h tiene algunos buenos:

#include <math.h> 
    ... 
double area = radius * radius * M_PI; 

Para definir las constantes globales, hay muchos métodos, que se explica adecuadamente en otras respuestas.

+0

Es desafortunado, pero 'M_PI' no es estándar c. – u0b34a0f6ae

-1

el preprocesador directo reemplazará por el código real antes de la compilación, por lo que en su caso el PI de su primer archivo se reemplazará por 3.14 ... y no hay símbolo PI en la tabla de símbolos de la primera unidad de traducción. por lo que el gdb no dirá ningún símbolo 'PI'.

si desea utilizar #define y no desea utilizar el archivo de encabezado, necesita #deine PI al comienzo de cada archivo.

0

Sería muy bueno si crea un archivo de encabezado para el archivo que está incluido en el archivo fuente principal, y es una buena práctica también y mejorará sus habilidades de lenguaje C. Imaginemos que tenemos un archivo de origen con las funciones, variables y constantes que vamos a necesitar en el archivo principal fuente mundial, podríamos crear un archivo de cabecera para ese archivo y poner esas funciones existen:

#ifndef _FILE_H 
#define _FILE_H 

#include "file.h" 
#define PI 3.14 
/** 
    *functions protypes here or other constants or globlal variables 
    */ 
    void do_something(char **param1, int *param2); 

#endif 

En su " file.c" archivo que debe hacer el folowing:

#inlcude "file.h" 

void do_something(char **param1, int *param2) 
{ 

    /** 
    *do something 
    */ 
} 

En su "main.c" presentar que debe hacer:

#include "file.h" 

/** 
    *Now you can use "PI" 
    */ 

espero que ayudó de alguna manera.

Cuestiones relacionadas