2016-02-26 91 views
0

我有一个函数在需要作为输入的整数我的C++应用程序。可悲的是这个整数只是一个usigned字符数组,这不由得我做到这一点的形式提供:这两个演员之间有什么区别?

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)); 

现在程序进入有关,给我总是我想要的结果。我的问题是:为什么两个演员的结果有差异? 难道他们不应该都做同样的,用之探源我在过程中的两个三分球不必要的?

帮助或指导的alredy现有的答案,我qustion是非常赞赏。

编辑(因为我不能评论)需要这个确实无聊的转换,从一个DWORD至极,其比较特定内存位置(作为int)一个项目在继承从FGPA retrived并以数组形式出现。 DWORD最后读取为一个十六进制数字。 我会尽力获得更改,并感谢所有人的快速回复。我真的没有得到这个程序的部分,我也不明白为什么它首先这样工作。现在我知道有人很幸运

P.S:因为即时通讯新来的,这是我第一次qustion请让我知道你可能需要的其他具体或只需编辑我牛逼misshabits了。

+1

虽然我已经回答了你的两个电话会发生什么,我不能说你真正应该做的事情,因为我不知道你真正想做的事。你想将整个数组作为单个32位整数传递吗?只传递数组中的一个元素?请详细说明您尝试解决的*实际*问题([关于XY问题的相关阅读](http://xyproblem.info/))。 –

+0

这是为什么在C和C++中存在联合概念的一个更好的原因 - 它允许你真正地告诉编译器你在做什么。现在你欺骗它变成做飕权..... – tofro

+0

@tofro使用工会办[*类型双关*](https://en.wikipedia.org/wiki/Type_punning)在C行不行,但不是在C(它明确地在说明书中提及)++其中它违反了[*串混叠规则*](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule)。 –

回答

0

在你想投的字符数组为int第一种情况下才达到什么 - 这是在一个列表显然毫无意义字符与int相当不同。

在第二种情况下,您首先获取数组的地址 - &运算符为您提供指向数组元素的第一个元素的字符指针。 具体的&c类型是unsigned char * - 它是合法的(虽然危险)到指针类型之间投从而从unsigned char *铸造到int *是合法的。

然后取消引用指针,并得到整数,在这个地方这可能是从第一对夫妇的字符串,其中那些字节字符的衍生一些讨厌的(无意义的)数量。

因此,你的第二个解决方案不会从char[]转换为int[]这大概是你想要的,而是它给你一个字符数组的第一个字节的整数表示。

1

这样做myFuncThatBadlyNeedsInts((int)c)编译第一衰减所述阵列c指针到所述第一元件,即&c[0],那么你施放此指针int并传递给函数。

当你做*((int*)&c)你拿(int (*)[4]类型)数组的地址,并告诉大家,这是一个指向int(这是不正确的)编译器,然后解引用是(不正确)int*

所以两个呼叫实际上是不正确。该演员只是使编译器沉默。


如果你想治疗的四个字节数组作为一个单一的32位的字,有很多方法可以做到这一点,但他们都休息the strict aliasing rule

最简单的方法是非常接近你现在所拥有的,并与铸造完成。使用C-铸造你投的是c衰变为指针int和取消引用指针:

myFuncThatBadlyNeedsInts(*(int*)c); 

注意,这是不一样的东西或者您的尝试。

第二种方法是使用一个联盟:

union my_union 
{ 
    char bytes[sizeof(int)]; 
    int integer; 
}; 

然后数据bytes成员复制到您的工会,并读出integer

+1

扩大评论“两个电话实际上是不正确的”。第二个要求是对编译器说谎,“如果你对编译器说谎,它会得到它的报复” - 亨利斯彭斯。访问转换返回的值是未定义的行为,很容易造成程序崩溃。 –

0

在你的指针从无符号的字符比它转换为整数,所以实际上你总是用你的UCHAR,只是(在这种情况下,整个数组c)经过3个字节的第二种情况。因为sizeof int是4(通常,但并非总是),并且uchar的大小只有1。所以,除非你喜欢用自己的腿来拍摄,否则不要这样做。

说实话,我真的不明白,你要在这个例子中