在C中为数组中的现有数组指定数组的头指针

问题描述 投票:0回答:3

我想“等同”两个数组,其中一个在固定联合内(不应该更改)。我只是将myUnion.RawBytes的头部指向array的头部,而不是使用memcpy。但是编译器会为myUnion.RawBytes = &array[0]; assignmet抛出一个错误。为什么会这样?有什么方法可以绕过这个问题吗?

下面的错误代码试图说明这一点。

#include <stdio.h>

typedef union{
    unsigned char  RawBytes[2];
    unsigned short RawWord;
} MyUnion;

int main(){
    MyUnion myUnion;

    char array[2] = {1, 1};
    myUnion.RawBytes = &array[0];

    printf("%d", myUnion.RawWord);

    return 0;
}

错误:

main.c: In function ‘main’:
main.c:12:22: error: assignment to expression with array type
     myUnion.RawBytes = &array[0];
c arrays unions
3个回答
0
投票

为了解决您的目的,您可以使用以下方法。

注意:以下方法不遵循严格的别名规则。

#include <stdio.h>

typedef union{
    unsigned char  RawBytes[2];
    unsigned short RawWord;
} MyUnion;

int main(){
    MyUnion *myUnion;

    unsigned char array[2] = {1, 1};
    myUnion = &array;

    printf("%d", myUnion->RawWord);
    printf("\n%d %d", myUnion->RawBytes[0], myUnion->RawBytes[1]);

    return 0;
}

我严格建议你在联合内部使用数组并使用memcpy或for循环。


1
投票

工会双关语的正确方式。

#include <stdio.h>

typedef union{
    unsigned char  RawBytes[2];
    unsigned short RawWord;
} MyUnion;

int main(){
    MyUnion myUnion;

    char array[2] = {1, 1};
    myUnion.RawBytes[0] = array[0];
    myUnion.RawBytes[1] = array[1];

    printf("%d", myUnion.RawWord);

    return 0;
}

1
投票

我读了这个问题,因为可以采取任何2个字符的数组,并通过使用这个聪明的unsigned short技巧解释它的价值作为union,没有复制,答案是否定的,你不能。

原因不是严格的混叠,而是它可能违反对齐要求。对于unsigned short,几乎所有平台都具有至少2的对齐要求。如果指针正在转换为不具有基本对齐要求的另一个指针,则行为未定义。

是的,这可以crash on x86。忘记能够使用机器语言访问未对齐的对象 - 您使用C编程,而不是使用汇编编程。


正确的方法是使用memcpy,它将告诉编译器访问可以是不对齐的,即

char array[2] = {1, 1};
uint16_t raw_word;
memcpy(&raw_word, array, 2);

请注意,memcpy是一个标准库函数,只要行为as if调用标准库中的memcpy函数,就允许编译器生成任何类型的机器代码。

© www.soinside.com 2019 - 2024. All rights reserved.