我正在尝试将旧的Fortran 77代码转换为C ++,并且大多数变量都在Common块中声明,例如:
COMMON/BLK1/Gw(200),Eta(4096),t(4096),Phi(200),w(200)
COMMON/BLK2/g,dw,Vel,M,dt,N,Ioutp1,Ioutp2
COMMON/BLK3/Hs,Std,E,Hs1,Tdt
据我所知,常用块仅用于在不同的子程序中使整个程序中的变量可访问。因此,在C ++程序中,我是否能够使用变量(在main之外)创建结构并以这种方式调用变量作为结构的成员?
答案 0 :(得分:1)
根据我对this page的COMMON的理解,C ++的等价物是创建一个名为common.h
的文件(带有包含警卫),其中包含:
namespace BLK1
{
int const Gw = 200;
int const Eta = 4096;
int const t = 4096;
int const Phi = 200;
int const w = 200;
}
namespace BLK2
{
extern int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
extern int Hs, Std, E, Hs1, Tdt;
}
此外,在项目中只有一个.cpp
文件中,您需要为任何非consts提供定义,例如:在foo.cpp
:
#include "common.h"
namespace BLK2
{
int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
int Hs, Std, E, Hs1, Tdt; // initialized to 0 by default
}
您可能希望使用与int
不同的类型,例如unsigned long
。我假设初始化值是const;如果没有,则将int const
更改为extern int
并删除初始值设定项。初始化程序必须包含在.cpp
文件中的定义中。
避免在标题中声明非const,非extern变量的错误;如果标题包含在两个不同的单元中,则会导致未定义的行为。
您可以通过编写BLK1::Eta
来访问这些变量。
正如你猜测的那样,使用struct
而不是名称空间可能会被认为更整洁,尽管你仍然需要在标题中创建一个声明为extern
的结构的实例,并且只在一个.cpp
文件中定义;如果你是预先C ++ 11,那么提供初始化器会更烦人。
(当然,更好的方法是重构代码以不使用全局变量。但它可能作为直接翻译的第一步有用。)
答案 1 :(得分:0)
具有相同名称的公共块在内存中相互重叠。您可以分配一块内存,并指向它的类型指针。另一种选择是在联盟中声明它们。这就是工会被发明的原因。当然,一旦你的联盟成立,你就可以在其他模块中使用extern。
将以下内容放入公共标头中,并将其实例放入模块1中。 添加一个extern,以便在模块2中看到。
union blk1
{
struct module_1_view
{
double gw(200);
double eta(4096);
double t(4096);
double phi(200);
double w(200);
}
struct module_2_view
{
double parameters(8592); // 200 + 4096 + 4096 + 200
double w_status(200);
}
}
想象一下,模块1负责将文件中的一些双打加载到module_1_view中的变量中。一旦加载并验证了这些参数,就调用模块2,模块2从模块2视图访问参数。几乎所有这些都是通过参数变量访问的,除了w_status,它实际上是200个指示符,用于指示参数的成功或验证。
关键是模块1和模块2访问相同的内存块(因此是联合),并且它们使用自己的一组变量名称。
答案 2 :(得分:-1)
我不能直接与Fortran对话,但是如果你想在c / c ++中的整个程序中访问一个变量,extern就是你要找的关键字。
Extern是一种共享数据的C风格方式。 C ++会推动你进入OO设计,其中一个与许多对象紧密耦合的变量不是很好的OO。
如果您尝试在遗留代码之上执行C ++操作,有时静态方法(通过指向C ++类的指针)可以充当包装器。下面是一个简单的例子:
extern int _magicVariable;
static void call( void* klass )
{
((MyClass*)klass)->functionCall( _magicVariable );
}
在MyClass中,您需要将void call(void *)命名为朋友。现在遗留代码可以使用指向您的类的指针调用(void *),将_magicVariable传递到您的OO设计中。从那里开始,c ++就能做到这一点。
最重要的是,您有很多方法可以完成任务,尝试根据您所需的代码结构做有意义的事情。