Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;:如何将数组中的2个字节强制转换为无符号短字符 我一直致力于一个传统的C++应用程序,而且绝对超出了我的舒适范围(好事情)。我想知道是否有人愿意给我一些建议(双关语)_C++_Pointers_Casting - Fatal编程技术网

C++;:如何将数组中的2个字节强制转换为无符号短字符 我一直致力于一个传统的C++应用程序,而且绝对超出了我的舒适范围(好事情)。我想知道是否有人愿意给我一些建议(双关语)

C++;:如何将数组中的2个字节强制转换为无符号短字符 我一直致力于一个传统的C++应用程序,而且绝对超出了我的舒适范围(好事情)。我想知道是否有人愿意给我一些建议(双关语),c++,pointers,casting,C++,Pointers,Casting,我需要将无符号字符数组中的2个字节强制转换为无符号短字符。字节是连续的 例如,我正在尝试做什么: 我从套接字接收字符串,并将其放入无符号字符数组中。我可以忽略第一个字节,然后将接下来的2个字节转换为无符号字符。这将只在windows上进行,因此没有大/小的Endian问题(我知道) 以下是我现在的情况(显然不起作用): //packetBuffer是一个无符号字符数组,包含用于测试的字符串“123456789” //我需要将字节2和3转换为短字节,2是最重要的字节 //所以我希望得到515(2*

我需要将无符号字符数组中的2个字节强制转换为无符号短字符。字节是连续的

例如,我正在尝试做什么:

我从套接字接收字符串,并将其放入无符号字符数组中。我可以忽略第一个字节,然后将接下来的2个字节转换为无符号字符。这将只在windows上进行,因此没有大/小的Endian问题(我知道)

以下是我现在的情况(显然不起作用):

//packetBuffer是一个无符号字符数组,包含用于测试的字符串“123456789”
//我需要将字节2和3转换为短字节,2是最重要的字节
//所以我希望得到515(2*256+3),而不是我尝试过的所有代码
//错误或2(仅转换一个字节
未签名的短myShort;
myShort=static_cast(packetBuffer[1])

静态强制转换有不同的语法,加上您需要使用指针,您要做的是:

unsigned short *myShort = static_cast<unsigned short*>(&packetBuffer[1]);
unsigned short*myShort=static_cast(&packetBuffer[1]);

这可能远低于您所关心的,但请记住,这样做很容易获得未对齐的访问。x86是可以原谅的,未对齐的访问导致的中止将在内部捕获,并最终复制并返回值,因此您的应用程序不会知道任何不同但是,如果此代码将在非x86上运行(您没有提到目标平台,所以我假设是x86桌面窗口),那么这样做将导致处理器数据中止,您必须在尝试强制转换数据之前手动将数据复制到对齐的地址


简言之,如果您要经常进行这种访问,您可以考虑对代码进行调整,以避免未对齐的读取,这样您将看到性能优势。

您不应该将无符号字符指针强制转换为无符号短指针(因此,从较小数据类型的指针强制转换为较大数据类型)。这是因为假定地址将正确对齐。更好的方法是将字节转换为实际的无符号短对象,或将memcpy转换为无符号短数组


毫无疑问,您可以调整编译器设置以绕过此限制,但如果代码被传递和重用,这是一件非常微妙的事情,将来会被打破。

好吧,您正在将字符加宽为短值。您想要的是将两个字节解释为短值。
static\u cast
无法从
unsi进行强制转换gned char*
unsigned short*
。您必须强制转换到
void*
,然后转换到
unsigned short*

unsigned short *p = static_cast<unsigned short*>(static_cast<void*>(&packetBuffer[1]));
unsigned short*p=static_cast(static_cast(&packetBuffer[1]);
现在,您可以取消对p的引用并获得短值。但是这种方法的问题是,您从unsigned char*、void*转换为其他类型。标准不保证地址保持不变(此外,取消引用该指针将是未定义的行为).更好的方法是使用位移位,这将始终有效:

unsigned short p = (packetBuffer[1] << 8) | packetBuffer[2];

unsigned short p=(packetBuffer[1]没有人看到输入是字符串

/* If it is a string as explicitly stated in the question.
 */
int byte1 = packetBuffer[1] - '0'; // convert 1st byte from char to number.
int byte2 = packetBuffer[2] - '0';

unsigned short result = (byte1 * 256) + byte2;

/* Alternatively if is an array of bytes.
 */
int byte1 = packetBuffer[1];
int byte2 = packetBuffer[2];

unsigned short result = (byte1 * 256) + byte2;
这也避免了大多数其他解决方案在某些平台上可能存在的对齐问题。请注意,短指针至少有两个字节。如果您尝试取消引用未对齐两个字节的短指针(或系统上的(短)指针大小)!

char packetBuffer[]={1, 2, 3};
无符号短myShort=*重新解释强制转换(&packetBuffer[1]);
我(不得不)一直这样做。big-endian是一个明显的问题。当机器不喜欢未对齐的读取(和写入)时,真正让你得到的是不正确的数据


您可能需要编写测试转换和断言,以查看其读取是否正确。因此,当在big-endian机器上运行时,或者更重要的是,在不喜欢未对齐读取的机器上运行时,将发生断言错误,而不是奇怪的难以跟踪的“错误”;)

上面的位偏移有一个错误:

unsigned short p = (packetBuffer[1] << 8) | packetBuffer[2];
或者,为了节省一些时钟周期,并且不将位移离末端:

unsigned short p;
p = (((unsigned short)packetBuffer[1])<<8) | packetBuffer[2];
无法保证一个完全没有bug的编译器会创建您所期望的代码。字节数组
b
发送到
do\u something\u with()
函数可能永远不会被
*s
操作修改。上面的代码中没有说明应该修改。如果不优化代码,则可能永远不会看到此问题(直到有人优化或更改编译器或编译器版本)。如果使用调试器,则可能永远不会看到此问题(直到为时已晚)

编译器看不到s和b之间的连接,它们是两个完全独立的项。优化器可能会选择不将
*s
写回内存,因为它看到
*s
有许多操作,因此它可以将该值保留在寄存器中,并且只在最后将其保存到内存中(如果有的话)

有三种基本方法可以解决上述指针问题:

  • s
    声明为易失性
  • 使用工会
  • 在更改类型时使用一个或多个函数

  • 在windows上,您可以使用:

    unsigned short i = MAKEWORD(lowbyte,hibyte);
    

    我意识到这是一个古老的线程,我不能说我尝试了这里提出的每一个建议。我只是让自己对mfc感到舒服,我正在寻找一种方法,将uint转换为两个字节,然后再转换到套接字的另一端

    你可以在网上找到很多位转移的例子,但它们似乎都不起作用。很多例子似乎过于复杂;我的意思是,我们只是说从uint中获取2个字节,然后发送
    unsigned short p = (packetBuffer[1] << 8) | packetBuffer[2];
    
    unsigned short p;
    p = packetBuffer[1]; p <<= 8; p |= packetBuffer[2];
    
    unsigned short p;
    p = (((unsigned short)packetBuffer[1])<<8) | packetBuffer[2];
    
    unsigned short *s;
    unsigned char b[10];
    
    s=(unsigned short *)&b[0];
    
    if(b[0]&7)
    {
       *s = *s+8;
       *s &= ~7;
    }
    
    do_something_With(b);
    
    *s=*s+8;
    
    do_something_With(b);
    
    *s=*s+8;
    
    do_something_With(b);
    
    unsigned short i = MAKEWORD(lowbyte,hibyte);
    
    class ByteConverter { public: static void uIntToBytes(unsigned int theUint, char* bytes) { unsigned int tInt = theUint; void *uintConverter = &tInt; char *theBytes = (char*)uintConverter; bytes[0] = theBytes[0]; bytes[1] = theBytes[1]; } static unsigned int bytesToUint(char *bytes) { unsigned theUint = 0; void *uintConverter = &theUint; char *thebytes = (char*)uintConverter; thebytes[0] = bytes[0]; thebytes[1] = bytes[1]; return theUint; } }; unsigned int theUint; char bytes[2]; CString msg;
    ByteConverter::uIntToBytes(65000,bytes); theUint = ByteConverter::bytesToUint(bytes);
    msg.Format(_T("theUint = %d"), theUint); AfxMessageBox(msg, MB_ICONINFORMATION | MB_OK);
    union CharToStruct {
        char charArray[2];
        unsigned short value;
    };
    
    
    short toShort(char* value){
        CharToStruct cs;
        cs.charArray[0] = value[1]; // most significant bit of short is not first bit of char array
        cs.charArray[1] = value[0];
        return cs.value;
    }
    
    char array[2]; 
    array[0] = 0x00;
    array[1] = 0x03;
    short i = toShort(array);
    cout << i << endl; // or printf("%h", i);