我根据结果执行一些计算,我想对其余程序使用short int或int作为某种类型的数据。可以(/怎么可以)在C或C ++中明智地做到这一点?我并不真正关心使用的内存量(即2或4个字节),我的主要目的是访问通用数组,就像它们包含这种类型的数据一样。我想避免使用以下代码:
char s[128];
if (result of preliminary calculations was A)
*((int*) s) = 50;
else
*((short int*) s) = 50;
设置 s 的前4或2个字节。条件全局typedef是理想的:
if (result of preliminary calculations was A)
typedef int mytype;
else
typedef short int mytype;
我不熟悉C ++类模板(还)。他们适用于我的问题吗?我是否必须在整个程序中更改声明(myclass<>和myclass<> *)?
非常感谢!
谢
编辑:值可能并不总是对齐。即,int可以从第21位开始。感谢您的答案。
答案 0 :(得分:4)
对于普通的C,你可以使用函数指针来完成这个:
static union { s_int[32]; s_short[64]; s_char[128]; } s;
static void set_s_int(int i, int n)
{
s.s_int[i] = n;
}
static int get_s_int(int i)
{
return s.s_int[i];
}
static void set_s_short(int i, int n)
{
s.s_short[i] = n;
}
static int get_s_short(int i)
{
return s.s_short[i];
}
static void (*set_s)(int, int);
static int (*get_s)(int);
根据初步计算设置一次:
if (result of preliminary calculations was A)
{
set_s = set_s_int;
get_s = get_s_int;
}
else
{
set_s = set_s_short;
get_s = get_s_short;
}
然后在程序的其余部分使用函数指针:
set_s(0, 50); /* Set entry 0 in array to 50 */
您的文件编写功能可以直接引用s
或s.s_char
,具体取决于其工作原理。
答案 1 :(得分:2)
在C和C ++中,所有类型信息都在编译时定义。所以不,你不能这样做。
答案 2 :(得分:2)
如果可以在编译时找到初步计算的结果,那么这可以工作。以下是一些简单的示例,以说明这是如何工作的。要执行更复杂的示例,请参阅http://en.wikipedia.org/wiki/Template_metaprogramming
using namespace std;
#include <iostream>
template<int x> struct OddOrEven { typedef typename OddOrEven<x-2>::t t; };
template<> struct OddOrEven<0> { typedef short t; };
template<> struct OddOrEven<1> { typedef int t; };
template<bool makeMeAnInt> struct X { typedef short t; };
template<> struct X<true> { typedef int t; };
int main(void) {
cout << sizeof(X<false>::t) << endl;
cout << sizeof(X<true>::t) << endl;
cout << sizeof(OddOrEven<0>::t) << endl;
cout << sizeof(OddOrEven<1>::t) << endl;
cout << sizeof(OddOrEven<2>::t) << endl;
cout << sizeof(OddOrEven<3>::t) << endl;
cout << sizeof(OddOrEven<4>::t) << endl;
cout << sizeof(OddOrEven<5>::t) << endl;
}
我认为上面是标准的C ++,但如果没有,我可以告诉你这个关于g ++的工作(Debian 4.3.2-1.1)4.3.2
答案 3 :(得分:1)
您可以为此目的滥用模板。任何受决策影响的代码都必须根据int类型进行模板化。一个分支将实例化int版本,另一个分支将实例化short int版本。这可能是一个坏主意*。
修改强>
*嗯,将它应用于整体架构只是一个坏主意。如果您有一个封装了各种行为的特定数据类型,那么模板应该可以正常工作。
以下是Aaron McDaid回答的一个变体,用以说明它与条件的使用:
#include <iostream>
#include <string>
using namespace std;
template<int x> struct OddOrEven { typedef typename OddOrEven<x-2>::t t; };
template<> struct OddOrEven<0> { typedef short t; };
template<> struct OddOrEven<1> { typedef int t; };
int main() {
cout << "int or short? ";
string which;
cin >> which;
if (which.compare("int") == 0)
cout << sizeof(OddOrEven<1>::t) << endl;
else if (which.compare("short") == 0)
cout << sizeof(OddOrEven<0>::t) << endl;
else
cout << "Please answer with either int or short next time." << endl;
return 0;
}
答案 4 :(得分:1)
我认为您的主要问题是,如果您不知道要阅读的类型,您计划稍后如何从s
读取数据。
如果你有这个部分,你可以使用工会:
union myintegers
{
int ints[32];
short shorts[64];
};
现在只需使用您想要的类型。
myintegers s;
if (result of preliminary calculations was A)
s.ints[0] = 50;
else
s.shorts[0] = 50;
更进一步,你可以将它全部包装在一个用result of preliminary calculations was A
构造的类中,并覆盖运算符*和[]以存储在一个或另一个中。
但你确定要的吗?
答案 5 :(得分:1)
在当前的C ++标准(C ++ 03)中,你不能。
事实上你可以使用一些先进的元编程技巧,但它在大多数情况下都无济于事。
在下一个标准(C ++ 0x,最后肯定是C ++ 11)中,您将能够使用the keyword decltype
来获取表达式的类型。如果您使用的是VC10(VS2010)或GCC 4.4或更新版本,那么您已经拥有该功能。
答案 6 :(得分:0)
这是我前一段时间项目的代码片段。
void* m_pdata;
if (e_data_type == eU8C1){
pimage_data = new unsigned char[size_x * size_y];
}
if (e_data_type == eU16C1){
pimage_data = new unsigned short[size_x * size_y];
}
我希望它可以帮到你
答案 7 :(得分:0)
由于您声明的目标是将信息有效地存储在磁盘上,您应该学会停止直接将C / C ++数据结构的内存映像写入磁盘,而是序列化您的数据。然后,您可以使用多种形式的可变长度编码(“vlc”)中的任何一种来获得您想要的效果。最简单的是每字节7位的编码,其中第8位是连续标志,表示该值在下一个字节中继续。所以259将被存储为(二进制,其中连续位标记为间距和字节边界标记为;):
1 0000010 ; 0 0000011
或者,您可以使用头部半字节来表示将遵循的字节数,或者使用类似于UTF-8的方案,但开销略微增加,但更严格的重新同步保证。还有vlcs设计为可解析,并且在向前或向后读取时可以轻松地重新同步。