Как сделать глобальную константу (работу с несколькими файлами) в программе C?

У меня есть программа ANSI C, содержащая два файла. Первый файл содержит функцию main(), а второй файл содержит другие функции, которые вызывает первый файл. Перед определением функции main() я разместил следующий код:

#define PI 3.14159265358979323846

но второй файл не видел эту переменную. Первый файл видит это хорошо. Затем я поместил эту же строку во второй файл (сохраняя его в первом файле, как указано выше), до определения функций, но второй файл его не видит. Вещи всегда компилируются отлично, но при прослеживании переменной PI в gdb она показывает "No symbol "PI" in current context."

Как сделать PI глобальной постоянной видимой для всех файлов, скомпилированных в приложении?

EDIT/UPDATE:

На основании ответа до сих пор я создал следующий файл:

myheader.h

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

и в двух файлах я хочу видеть этот постоянный PI, я включил этот файл следующим образом:

file1.c

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

и file2.c

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

Вопросы:

  • Когда я использую GDB для отладки, b PI возвращает (в обоих файлах тот же результат) "Нет символа" PI "в текущем контексте". Однако математика в зависимости от PI вычисляется правильно. Есть ли способ просмотра PI в gdb?

  • Могу ли я также включить две строки для stdio и stdlib в файл myheader.h?

  • Могу ли я также включить какие-либо прототипы функций в файл myheader.h? Если я это сделаю, а затем скажу, что создаю файл3.c, который не требует какого-либо из этих прототипов, потому что он не использует эти функции, какой-либо вред нанесен?

Ответ 1

  • Нормально, что определение макроса не отображается в GDB. Это потому, что GCC заменяет каждый PI фактическим значением pi.
  • Да. В вашем случае это не повредит. Если файл .h содержит прототип (его обычно называют объявлениями), который использует тип, который определен в другом месте, вы можете просто #include в ваших файлах заголовков
  • Да. Вы можете объявить о том, что когда-либо будет использовать прототип, который вам нужен, и он не принесет никакого вреда с точки зрения функциональности вашей программы. Компилятор даже не проверяет существование определений этих функций, если вы на самом деле не вызываете их из другого места.

Ответ 2

Я бы объявил PI в файле заголовка и включил этот заголовочный файл во все исходные файлы

Вы должны размещать объявления функций, макросы в своем файле заголовка (и, возможно, некоторые простые встроенные функции) Реализация должна быть помещена в файлы .c

//Я отредактировал ответ на ответ на ваш комментарий

Ответ 3

Макрос не является переменной, и он не будет отображаться в gdb как переменная. Все отлично компилируется, потому что они работают нормально; у вас просто неправильные ожидания для gdb.

В общем случае макрос, который необходим в нескольких местах, должен быть определен в файле заголовка, который был включен везде, где он нужен; например, макрос M_PI уже определен как pi в стандарте include math.h.

Другое, что вы можете сделать, это иметь const int PI = 3.14159etcetc; в одном файле и extern const int PI; во всех остальных, но это боль, потому что для определения значения существует только одно компиляционное устройство.

Ответ 4

Вы можете создать глобальную переменную.

//file1.c
int my_global;


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

Обратите внимание, что использование препроцессора в основном обескураживается.

Также обратите внимание, что определение M_PI, предложенное другими, недоступно в последнем стандарте C (C99), поэтому вы не можете положиться на него.

Ответ 5

Если вы работаете только со стандартными определениями математики, стандартный файл заголовка math.h имеет несколько хороших:

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

Для определения глобальных констант существует множество методов, адекватно объясненных в других ответах.

Ответ 6

Было бы очень хорошо, если бы вы создали файл заголовка для файла, который включен в основной исходный файл, и это тоже хорошая оценка, и вы улучшите свои навыки языка C. Представьте, что у нас есть исходный файл с функциями, глобальными переменными и константами, которые нам понадобятся в основном исходном файле, мы могли бы создать заголовочный файл для этого файла и поместить туда эти функции:

 #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

В вашем файле file.c вы должны сделать следующее:

#inlcude "file.h"

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

    /**
     *do something
     */
}

В вашем файле "main.c" вы должны сделать:

 #include "file.h"

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

Надеюсь, я как-то помог.

Ответ 7

препроцессор direct заменит фактическим кодом перед компиляцией, поэтому в вашем случае ваш первый файл PI заменит на 3.14... и символ символа PI в таблице символов первого блока перевода не будет. поэтому gdb не будет указывать символ "PI".

если вы хотите использовать #define и не хотите использовать заголовочный файл, вам нужно #deine PI в начале каждого файла.