这两个演员之间有什么区别?

时间:2016-02-26 09:42:01

标签: c++

我的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。:因为我刚刚来到这里,这是我的第一个问题,请让我知道您可能需要的其他细节,或者只是编辑我的新生儿。

3 个答案:

答案 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完全不同。

在第二种情况下,您首先获取阵列的地址 - &amp;运算符为您提供指向数组的第一个元素的字符指针。 具体来说,#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数组的第一个字节的整数表示。