将静态数组定义到C或C++源文件中

Van*_*nel 13 c c++ arrays static

我知道这是每个程序员都应该知道的问题,但我不知道.很久没有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
Run Code Online (Sandbox Code Playgroud)

如果使用C++源文件,我可能需要定义一个类吗?

更新:
我认为问题是:
包含这些头的每个源文件(甚至是间接的)将为这些静态数组生成自己的定义.无法保证编译器/链接器会将它们优化为单个定义,即使在未使用它们的源文件中也是如此.事实上,在许多情况下,编译器无法优化它们.这可能导致静态数据占用大量磁盘空间,并可能导致运行时内存.

谢谢.

Oys*_*ein 19

staticextern在同一时间是没有意义的.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*/ };
Run Code Online (Sandbox Code Playgroud)

或者你可以做fortran所建议的,但这只会给你文件范围访问,而不是全局变量.

以任何方式,如果您使用C++源文件来定义一个类.与Java不同,C++不会强迫您进入面向对象的设计(无论是否可以讨论,但无论如何都可以讨论).

编辑:至于你的问题更新,那是因为你将它们定义为static.如果你只想要全局变量,你不应该这样做,而是保留一个单一的定义(const float)并引用它extern,如上面的例子所示.


for*_*ran 7

我曾经在Quake2源代码中看到了一个有趣的"技巧",实际上这只是一种使用include的不寻常方式:

做就是了:

static const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3] = {
#include "TEMPLEVertices.txt"
};
Run Code Online (Sandbox Code Playgroud)

等等

并保留包含文件中的数据.

您仍然可以extern在编译单元中声明它们,但这会使事情变得更加整洁.


341*_*008 6

您的头文件将变为:

#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
Run Code Online (Sandbox Code Playgroud)

当您的源文件变为:

// 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
Run Code Online (Sandbox Code Playgroud)

更新:如果要显式指定数组,则不必提及大小。那就是你可以做的:

const float TEMPLEVertices[] = {...};
Run Code Online (Sandbox Code Playgroud)

要么

const float TEMPLEVertices[NUM_TEMPLE_OBJECT_VERTEX * 3];
Run Code Online (Sandbox Code Playgroud)

  • 对不起大家。被叫走了,回来发现有那么多人在为这个代码片段做工。你们所有人都是对的。应该删除`static`关键字(在此归咎于复制粘贴)。始终使用[] / [n],而不是在标头和源中混合使用[[/]](在这里怪我)。对困惑感到抱歉。更新的代码。 (2认同)

Mep*_*ane 5

实际上它非常简单; 我将用一个更简单的例子来演示一个简单的原始常量.

在您的项目中,您有两个文件pi.hpi.cpp.

内容pi.h如下:

#ifndef _PI_H
#define _PI_H

extern const double PI;

#endif
Run Code Online (Sandbox Code Playgroud)

的contants pi.cpp如下所示:

#include "pi.h"

const double PI = 3.1415926535;
Run Code Online (Sandbox Code Playgroud)

如果你想使用这个常量,你只需要包含pi.h必要的地方.该值始终从同一位置读取.

几乎任何事情都可以做到 - 数组,对象,对象数组,STL容器等.请确保不要过度使用这种技术 - 特别是当声明的对象extern不是时const,你可能会创建一些非常难以跟踪的副作用.但是对于不断的数据,你就是这样做的.