Я хочу поместить определения массива в исходный файл C или C ++.

ю, что это вопрос, который должен знать каждый программист, но я не знаю. Давненько не программировал на С, и я много чего забыл.

Мой вопрос:

У меня есть три огромных статических массива, определенных в заголовочном файле. Кто-то сказал мне, что лучше объявить ихextern в заголовочном файле и определите их в одном исходном файле на C или C ++.

Как я могу это сделать?

Вот мой заголовочный файл:

#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_


#define NUM_TEMPLE_OBJECT_VERTEX 10818

static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
static const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
static const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};

#endif

Если я использую исходный файл C ++, могу ли я определить класс?

ОБНОВИТЬ:
Я думаю, что проблема заключается в:
Каждый исходный файл, в который включены эти заголовки (даже косвенно), будет генерировать свое собственное определение для этих статических массивов. Нет гарантии, что компилятор / компоновщик оптимизирует их в одно определение, даже в исходных файлах, где они не используются. Фактически, во многих случаях компилятор не может их оптимизировать. Это может привести к тому, что ваши статические данные будут занимать много места на диске, а также, возможно, оперативную память.

Спасибо.

 Andy22 мая 2015 г., 14:12
Не должно быть в случае GCC и оптимизации с включенной сборкой. Вот информация о "-fkeep-static-consts" из [gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html]https://... "Выдавать переменные, объявленные как статические константы, когда оптимизация не включена, даже если на переменные не ссылаются. GCC включает эту опцию по умолчанию. Если вы хотите заставить компилятор проверять, есть ли ссылка на переменную, независимо от того, какой или не включена оптимизация, используйте опцию -fno-keep-static-consts. "

Ответы на вопрос(5)

Решение Вопроса

static а такжеextern в то же время не имеет смысла.static в области видимости файла делает массив недоступным для других файлов, в то время какextern сообщает компилятору, что ваш массив определен где-то еще.

Вы можете делать то, что предлагает 321008,за исключением того, что вы не объявляете свои массивы статическими что запрещено C и C ++. Это дает вам три глобальные переменные, которые вы можете использовать везде, где включен заголовочный файл.

Например, вот так:

// .h file:

extern const float TEMPLEVertices[];

// .cpp (or .c) file:

const float TEMPLEVertices[] = { 1.0, 2.0, 5.6 /* or whatever*/ };

Или вы можете делать то, что предлагает Фортран, но это даст вам доступ только к области файла, а не к глобальным переменным.

Вы делаетене в любом случае нужно определить класс, если вы используете исходный файл C ++. В отличие от Java, C ++ не принуждает вас к объектно-ориентированному дизайну (может ли это обсуждаться хорошо или нет, но в любом случае).

РЕДАКТИРОВАТЬ: Что касается обновления вашего вопроса, это потому, что вы определяете их какstatic, Если вам нужны только глобальные переменные, вы не должны этого делать, а вместо этого оставить одно определение (const float) и сослаться на этоexternсогласно моему примеру выше.

 VansFannel10 янв. 2011 г., 11:28
Компилируется, но компоновщик выдает ошибку:undefined reference toTEMPLEVertices` и то же самое для двух других массивов.
 VansFannel10 янв. 2011 г., 11:40
и @jweyrich: вы правы. Я забыл добавить новый исходный файл C для создания файла. Сожалею.
 BeeBand10 янв. 2011 г., 11:31
+1 за упоминание, что «Вы никоим образом не должны определять класс в исходном файле C ++».
 jweyrich10 янв. 2011 г., 11:32
@VansFannel: тогда вы неправильно скопировали. Предоставленный код должен компилироваться и ссылаться.
 Oystein10 янв. 2011 г., 11:32
@VansFannel: А какой у тебя код? Не могли бы вы обновить свой вопрос с ним, возможно? Обратите внимание, что вам нужно включать .h файл везде, где вы хотите использовать массив.

Я продемонстрирую на более простом примере простую примитивную константу.

В вашем проекте у вас есть два файлаpi.h а такжеpi.cpp.

Содержаниеpi.h выглядит так:

#ifndef _PI_H
#define _PI_H

extern const double PI;

#endif

Константыpi.cpp выглядит так:

#include "pi.h"

const double PI = 3.1415926535;

Если вы хотите использовать эту константу, вы просто включаетеpi.h где необходимо. Значение всегда будет читаться из одного места.

То же самое можно сделать практически с чем угодно - массивами, объектами, массивами объектов, контейнерами STL и т. Д. Просто убедитесь, что вы не злоупотребляете этой техникой, особенно когда объекты объявленыextern неconstВы можете создать некоторые действительно трудно отследить побочные эффекты. Но для постоянных данных, это вы это делаете.

Ваш заголовочный файл становится:

#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_


#define NUM_TEMPLE_OBJECT_VERTEX 10818

extern const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];
extern const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3];
extern const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3];

#endif

Пока ваш исходный файл становится:

// include header
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
const float TEMPLENormals[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};
const float TEMPLETexCoords[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...};

// rest of the source

Обновление: если вы указываете массивы явно, вам не нужно указывать размеры. То есть вы можете сделать:

const float TEMPLEVertices[] = {...};

или же

const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];
 edgar.holleis10 янв. 2011 г., 11:12
Вот как ты это делаешь! @ Øystein: Что вы думаете, не так с этим?
 jweyrich10 янв. 2011 г., 11:20
@ 341008: вы не можете использоватьextern вstatic переменная, в противном случае вы получите ошибку компоновки.
 34100810 янв. 2011 г., 11:37
Извините ребята. Мне позвонили и вернулись, чтобы найти так много людей, работающих над этим фрагментом кода. Вы все правы.static Ключевое слово должно быть удалено (винить копировать-вставить здесь). Используйте [] / [n] последовательно вместо смешивания[]/* в заголовке и источнике (вините меня здесь). Извините за путаницу. Обновленный код
 Oystein10 янв. 2011 г., 11:00
Это не разрешено C или C ++.
 VansFannel10 янв. 2011 г., 11:09
Это законно C или C ++?

который на самом деле был просто необычным способом использования include:

просто сделать:

static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {
#include "TEMPLEVertices.txt"
};

и т.п.

И храните только данные во включенных файлах.

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

 VansFannel10 янв. 2011 г., 11:11
Спасибо за ваш ответ, но, думаю, у меня возникнет та же проблема. Я обновил свой вопрос с более подробной информацией о проблеме.


Я обычно использую простой трюк.

а) В каждом файле C / CPP я определяюимя файла_C
б) В каждом файле H / HPP я определяюимя файла_ЧАС

чем ...

Это будет ваш включаемый файл

#ifndef _TEMPLE_OBJECT_H_
#define _TEMPLE_OBJECT_H_

#define NUM_TEMPLE_OBJECT_VERTEX 10818

#ifdef _TEMPLE_OBJECT_C
const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {...} ; /* Put here your const values */
#else
extern const float TEMPLEVerticies[] ;
#endif

#endif

Если я не ошибаюсь, это грязная работа (или что-то очень похожее на это) ...: o)

 VansFannel10 янв. 2011 г., 11:14
Я хочу поместить определения массива в исходный файл C или C ++.

Ваш ответ на вопрос