Как сделать глобальную константу (работу с несколькими файлами) в программе 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 в начале каждого файла.