Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как определить констатнты/перем. в .h файле для C ?
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
Саша Z
Вопрос конечно чайниковский, сознаю, я пока к таким отношусь.. wink.gif
В коде С определены несколько массивов (ессно постоянного размера), например:
Код
int arr1[A], arr2[B],...

.
.
.

void main()
{
.
.


A,B - постоянные константы для всего проэкта, посему хочу дать их определение в .h файле где буду определять все константы и глобальные переменные. Сей .h файл includиться в С.
Как правильно определить A,B (и инициализировать) в .h файле что-бы их символьно использовать в С коде (в определении размеров массивов) ?

Пробовал:
Код
.h file:

extern int A = 5800;
extern int B = 2900;


Затем в С:
Код
int arr1[A], arr2[B];

void main()
{
.
.


Компилятор не берет ...
WHALE
Попробуйте
.h file:
#define A 5800
#define B 2900
.c file:
int arr1[A],arr2[B],...
makc
Цитата(WHALE @ May 31 2007, 07:58) *
Попробуйте
.h file:
#define A 5800
#define B 2900
.c file:
int arr1[A],arr2[B],...


Можно и по-другому:

.h file:
const int A=5800;
const int B=2900;
.c file:
int arr1[A],arr2[B],...
Doka
Цитата(makc @ May 31 2007, 08:06) *
Можно и по-другому:

.h file:
const int A=5800;
const int B=2900;
.c file:
int arr1[A],arr2[B],...


можно, да не нужно.
в 1ом случае осуществляется простая макроподстановка на уровне препроцессора
а во 2ом - съедается память под константы А и В
(принципиально для ембеддед-программирования)
Саша Z
Цитата(Doka @ May 31 2007, 10:49) *
можно, да не нужно.
в 1ом случае осуществляется простая макроподстановка на уровне препроцессора
а во 2ом - съедается память под константы А и В
(принципиально для ембеддед-программирования)


Спасибо всем.
Воторой вариант (const) пробовал сам ранее - не работает. При компиляции ругается - требует консатнт в определении размера массивив (в С коде) - значит видимо все-таки через const в .h файле он их не видит глобально либо видит но не происходит процесса подстановки перед самой компиляцией.

Сейчас попробую первыай вариант (define) - надеюсь сработает.

Увы, не сработало :-(

Код
.h file:

#define PACKED_SIZE   5800

C file:

int bulk[PACKED_SIZE];


Компайлер ругается: error: expected a"]" - в строке определения массива (в С файле).

Чушь какая-то cranky.gif
BratherLU
в *.с в верху
#include "*.h"
//Забыли наверно сделать smile.gif
Саша Z
Цитата(BratherLU @ May 31 2007, 12:28) *
в *.с в верху
#include "*.h"
//Забыли наверно сделать smile.gif


да нее, это есть..чайник то я чайник, но не аткой прогоревший... lol.gif
SM
Цитата(Саша Z @ May 31 2007, 11:11) *
Компайлер ругается: error: expected a"]" - в строке определения массива (в С файле).


Скорее всего в .h после дефайна по привычке ";" вкатили.
jorikdima
это все примитивные вещи.

У вас путь к h файлу в опциях проекта прописан (или он в одной папке с *.с ??)?


Текст h файла :

#define x 10


Текст с файла:

#include "(тут имя h файла )"

int arr[x];



Все должно работать
mdmitry
>.h file:
>const int A=5800;
>const int B=2900;
>.c file:
>int arr1[A],arr2[B],...

Компилятору надо знать размер массива и с #define препроцессор дает размер. В случае с const int на момент компиляции значение неизвестно.
Вывод: В языке С размеры массивов принято определять через соответствующий #define .
Саша Z
Цитата(SM @ May 31 2007, 12:36) *
Скорее всего в .h после дефайна по привычке ";" вкатили.


Как всегда SM прав - завидую вашей интуиции.. a14.gif - действительно влепил везде ; после defineов автоматом.... smile.gif

Сейчас убрал - все нормально. Учимся...учимся... wink.gif

Теперь такое дело - некоторые из этих defineов должны быть видны как переменные (точнее константы) для использования в ассемблерных рутинах (есть несколько asm файлов в проэкте). Ессно, define этого не дает (т.е. определенная defineом она не опознается в файле asm). В виду этого приходиться определять в теле кода C новую константу и присваивать ей значение соотв. defineа и в asm коде работать с этой новой константой.
Вопрос такой: есть ли вариант однозначного определения в .h цонстанты так что она работала и как define и как физическая константа для asm файлов ?

Цитата
Компилятору надо знать размер массива и с #define препроцессор дает размер. В случае с const int на момент компиляции значение неизвестно.
Вывод: В языке С размеры массивов принято определять через соответствующий #define .


Да, именно это и понял из всего...получил полезный урок.. biggrin.gif
SM
Цитата(Саша Z @ May 31 2007, 13:42) *
Вопрос такой: есть ли вариант однозначного определения в .h цонстанты так что она работала и как define и как физическая константа для asm файлов ?


В asm константы определяются через ".set" или ".equ" или как-то аналогично. Отдельно взятые трансляторы асма умеют понимать и #define, но это скорее исключение, чем правило. Посему чтобы однозначно - никак. Держите два файла, .inc для асма и .h для цэ. Ну и меняйте их одновременно.
zltigo
Цитата(SM @ May 31 2007, 13:01) *
Держите два файла, .inc для асма и .h для цэ. Ну и меняйте их одновременно.

Хлопотно sad.gif
Лучше в проект запихнуть конвертировщик *.H в *.INC для вариантов с EQU пользую штатную утилииту от Borland.
Саша Z
Большое спасибо всем, помошь в понимании была весьма существенна.
Проблема решена defineами в .h файле.

Ввиду того что мало общих констант требуется в ассемблерных файлах - решил себе жизню не осложнять - просто определяю те несколько констант в теле C кода как const и давать ей там соотв. значение defineа.

Предпочел пока по простому - благо таких констант всего 2-3 в ассемблерных рутинах.
makc
Цитата(mdmitry @ May 31 2007, 13:40) *
>.h file:
>const int A=5800;
>const int B=2900;
>.c file:
>int arr1[A],arr2[B],...

Компилятору надо знать размер массива и с #define препроцессор дает размер. В случае с const int на момент компиляции значение неизвестно.
Вывод: В языке С размеры массивов принято определять через соответствующий #define .


Да, точно. Это я с C++ перепутал, в котором этот пример работает нормально.
Mokena
Подскажите, почему такое происходит в Code Composer Studio:

В .h файле есть такое определение массива:
Код
#ifndef SSD_API_H
#define SSD_API_H

#ifndef SSD_REGS
#define SSD_REGS

// Значения регистров после POR
const Uint16 SSDRegsPOR[0x50] = {
  0x0000, 0x0000 .............
}

#endif // SSD_REGS

#endif // SSD_API_H
Этот файл включается в два .c файла. И в этом случае компилятор сообщает, что константа SSDRegsPOR определа несколько раз. Может быть дело в настройках компилятора/препроцессора?
mdmitry
В глобальном списке имен появляются два одинаковых массива
const Uint16 SSDRegsPOR[0x50] = {
0x0000, 0x0000 .............
},
что, естественно, линкеру не нравиться.

ИМХО, лучше массивы в заголовочных файлах не определять, тем более глобальные.
Решение: определить в одном файле исходного текста, а в друггм ссылаться через extern.
PSP
Если всетаки хочется определить переменную/массив в .h файле, то можно воспользоваться манипуляциями с extern.


#ifdef IMPLEMENT
#define EXTERN
#else
#define EXTERN extern
#endif

EXTERN const Uint16 SSDRegsPOR[0x50] = {...


В свою очередь IMPLEMENT нужно определить только в одном .c файле, там и будет реализация массива. А во всех остальных он будем с модификаторм extern, т.е. только объявлен.
Сергей Борщ
Цитата(Mokena @ Oct 2 2007, 23:16) *
Про массивы уже сказали. Компилятор должен знать, где этот массив размещать. Когда вы включаете в заголовочный файл определение а не объявление массива - компилятор вынужден создать по копии массива в каждом из файлов. Если вас это не смущает - добавьте static перед определением массива. Тогда каждая копия массива будет видна только внутри этого .c файла. Но это некрасивое решение. Правильнее объявить массив в .h как extern, а определить его в одном из .с:
Код
array.h:
extern uint8_t array[size];

file1.c:
#include "array.h"
uint8_t array[size] =
{
    .....
    .....
};
file2.c:
#include "array.h"
А вот для обычных констант как раз наоборот - можно определять их в .h как static uint8_t const Const1 = 123;, тогда компилятор вполне может не выделять под нее память и скомпилировать в опкод сразу значение константы, вместо ее чтения. Но при таком подходе нельзя брать адрес этой константы - иначе компилятор будет вынужден выделить под нее память.
Mokena
Ого, все оказалось чуточку сложнее, чем я представлял. Но теперь все ясно, всем большое спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.