我的c ++应用程序中有一个函数需要一个整数作为输入。遗憾的是,这个整数只能以usigned char数组的形式提供,这让我这样做:
unsigned char c[4] = {'1','2','3','4'};
void myFuncThatBadlyNeedsInts(int i)
//compares some memory value(which is an int) with anotherone...
myFuncThatBadlyNeedsInts((int)c);
这给了我一个错误,告诉我这是不允许的。 但如果我决定变得棘手并且这样做:
myFuncThatBadlyNeedsInts(*((int*)&c));
现在程序开始,给我总是我想要的结果。我的问题是:为什么两个演员的结果有差异? 他们都不应该这样做,但是在这个过程中我有两个不必要的指针吗?
非常感谢帮助或对我现有答案的现有答案的指导。
编辑(因为我无法发表评论):这种确实愚蠢的转换需要从比较特定内存位置的项目中继承(作为int)带有一个DWORD,它从FGPA中重新获得并作为一个数组出现。最后将DWORD读取为一个十六进制数。 我会尝试获得更改此权限的权限,并感谢您快速回复。我真的没有得到这个程序的一部分,也没有理解为什么它一开始就像这样。现在我知道有人幸运了
P.S。:因为我刚刚来到这里,这是我的第一个问题,请让我知道您可能需要的其他细节,或者只是编辑我的新生儿。
答案 0 :(得分:1)
当您执行myFuncThatBadlyNeedsInts((int)c)
时,编译器首先将数组c
衰减到指针到第一个元素,即&c[0]
,然后再将其转换为指针到int
并将其传递给函数。
当你执行*((int*)&c)
时,你获取数组的地址(类型为int (*)[4]
)并告诉编译器它是指向int
的指针(这是不正确的)然后取消引用(不正确)int*
。
所以这两个电话实际上都是不正确的。演员只是让编译器沉默。
如果你想将数组的四个字节视为一个32位字,有很多方法可以做到,但它们都会中断the strict aliasing rule。
最简单的方法非常接近你现在拥有的东西,并且完成了铸造。使用C-casting,您将c
衰减的指针转换为指向int
的指针并取消引用:
myFuncThatBadlyNeedsInts(*(int*)c);
请注意,这与您的任何尝试都不相同。
第二种方法是使用联合:
union my_union
{
char bytes[sizeof(int)];
int integer;
};
然后将数据复制到您的工会bytes
成员,并宣读integer
。
答案 1 :(得分:0)
在第二种情况下,你从unsigned char获取指针而不是将它转换为整数,所以实际上你总是使用你的uchar和3个字节(在这种情况下是整个数组c)。因为sizeof int是4(通常,但不总是),并且uchar的大小只有1.所以除非你喜欢用腿射击自己,否则不要这样做。
说实话,我真的不明白你将在这个例子中取得什么成就
答案 2 :(得分:0)
在第一种情况下,你试图将一个char数组转换为int - 这显然毫无意义,因为字符列表与int完全不同。
在第二种情况下,您首先获取阵列的地址 - &运算符为您提供指向数组的第一个元素的字符指针。
具体来说,#include <iostream>
#include <new>
#include <string>
#include <utility>
const int TU_STRING = 0;
const int TU_INT = 1;
const int TU_FLOAT = 2;
struct TU {
union my_union {
struct i_type { int type; int i; } i;
struct f_type { int type; float f; } f;
struct s_type { int type; std::string s; } s;
my_union(int i) : i{TU_INT, i} {}
my_union(float f) : f{TU_FLOAT, f} {}
my_union(std::string s) : s{TU_STRING, std::move(s)} {}
my_union(my_union const& other) {
// This is safe.
switch (other.i.type) {
case TU_INT: ::new(&i) auto(other.i); break;
case TU_FLOAT: ::new(&f) auto(other.f); break;
case TU_STRING: ::new(&s) auto(other.s); break;
}
}
~my_union() {
// This is safe.
if (TU_STRING == s.type) {
s.~s_type();
}
}
} u;
TU(int i) : u(i) {}
TU(float f) : u(f) {}
TU(std::string s) : u(std::move(s)) {}
TU(TU const&) = default;
~TU() = default;
};
int main() {
TU tu("hello");
std::cout << tu.u.s.s << '\n';
return 0;
}
的类型是&c
- 在指针类型之间转换是合法的(尽管很危险),因此从unsigned char *
到unsigned char *
的转换是合法的。
然后你取消引用指针并得到这个位置的整数,这可能是从字符串中的前几个字符派生的一些讨厌的(无意义的)数字,这些字节是那些字节。
所以你的第二个解决方案不能从int *
转换为char[]
,这可能是你想要的,而是它给你一个char数组的第一个字节的整数表示。