是否可以在 Char-Array(或类似)上获取 Int-Array-Pointer?

Is it possible to get an Int-Array-Pointer on a Char-Array (or sth similar)?

提问人:someuser47 提问时间:4/25/2023 最后编辑:ryykersomeuser47 更新时间:4/25/2023 访问量:81

问:

我想将五个整数(作为 32 位整数)写入一个 char-array。目前,我制作了 5 个指向 char-array 中特定位置的单独 int 指针,但相反,我只想要一个指针。下面的代码有效,但我想要一个不那么笨拙的解决方案。

int uSensorID = 7;
int uSensorTypeEnum = 5;
int currentSensorValue = 15;
static const int messageSize = 20;               
static char dataToSendBuffer[messageSize + 1];    

static int* PointerSensorIDInSendBufferCharArray = (int*)(&dataToSendBuffer[0]);
static int* PointerFirstSeparatorInSendBufferCharArray = (int*)(&dataToSendBuffer[4]);
static int* PointerSensorTypeInSendBuffer = (int*)(&dataToSendBuffer[8]);
static int* PointerSecondSeparatorInSendBufferCharArray = (int*)(&dataToSendBuffer[12]);
static int* PointerCurrentSensorValueInSendBuffer = (int*)(&dataToSendBuffer[16]);

*PointerSensorIDInSendBufferCharArray = htonl(stoi(uSensorID);
*PointerFirstSeparatorInSendBufferCharArray = -1;                       
*PointerSensorTypeInSendBuffer = htonl(uSensorTypeEnum);
*PointerSecondSeparatorInSendBufferCharArray = -1;
*PointerCurrentSensorValueInSendBuffer = htonl(currentSensorValue);

理想情况下,我想要一个类似 Int-Array-Pointer 的东西,它指向 char-array 的第一个元素的内存地址,所以代码应该看起来像这样(但我的代码不起作用,只是为了给出一个想法):

int uSensorID = 7;
int uSensorTypeEnum = 5;
int currentSensorValue = 15;
static const int messageSize = 20;                 
static char dataToSendBuffer[messageSize + 1];            

int* IntPointerToDataToSendBuffer[] = (int* [])(&dataToSendBuffer);
*IntPointerToDataToSendBuffer[0] = htonl(stoi(uSensorID);
*IntPointerToDataToSendBuffer[1] = -1;
*IntPointerToDataToSendBuffer[2] = htonl(uSensorTypeEnum);
*IntPointerToDataToSendBuffer[3] = -1;
*IntPointerToDataToSendBuffer[4] = htonl(currentSensorValue);

这是否可能(或不需要 5 个单独指针的类似情况)?
(我想理想情况下只使用一个数组,所以不要只是复制数组(多个指针是可以的)。使用静态,因为它稍后将无休止地循环。

问候并感谢您的任何帮助

C 指针网络 投射

评论

0赞 463035818_is_not_an_ai 4/25/2023
请仅标记您正在使用的语言。C 和 C++ 是两种不同的语言
1赞 stark 4/25/2023
为什么不使用 int 数组?
0赞 someuser47 4/25/2023
@stark 稍后,这将用于需要 iirc char-array(或者可能是 char*)的函数中,因此反过来(char-array-pointer 或 int-array 上的 char-pointer)也可以,但不仅仅是带有 int-pointer 的 int-array
0赞 stark 4/25/2023
您始终可以将 int 数组用作 char 数组,但反之则不然。char 数组可能未正确对齐以保存整数。
0赞 someuser47 4/25/2023
当使用一些整数介于两者之间的 0 的 int 数组时,使用 char* 会遇到问题吗?当指针/程序认为数组在那里结束或(因为 null)?

答:

-1赞 Bodo 4/25/2023 #1

任何指针都可以像数组一样使用,指向单个值或指向数组的第一个值的指针之间没有区别。当然,如果您使用指针访问无效内存,则行为是未定义的。

*pointer等同于 。pointer[0]

以下代码片段仅用于演示如何根据问题中的原始代码将指针用作数组。它不会修复原始代码中的其他问题。

int* IntPointerToDataToSendBuffer = (int*)(&dataToSendBuffer);
IntPointerToDataToSendBuffer[0] = htonl(stoi(uSensorID); /* unrelated syntax error here */
IntPointerToDataToSendBuffer[1] = -1;

等。

但是:将 char * 转换为 int * 并取消引用此指针是错误的。

这似乎在某些平台上有效(因为这是未定义行为的一种可能变体),我经常在实际代码中看到它。
除了违反正式规则外,您还可能会在某些平台上遇到问题。可能需要比 .根据您的平台,如果数组碰巧没有按照数组的要求对齐,这可能会导致编译器警告、执行速度变慢或程序中止,从而导致对齐陷阱。
我也看到了这些问题,我永远不会这样做。
int*char *charint

你应该反过来做:使用一个数组并将其转换为一个,以便将其用作字节数组/缓冲区。intchar *

评论

0赞 someuser47 4/25/2023
当使用一些整数介于两者之间的 0 的 int 数组时,使用 char* 会遇到问题吗?当指针/程序认为数组在那里终止或终止时?
0赞 Bodo 4/25/2023
@someuser47 值 0 仅在将数组用作 C 字符串时才相关,例如,通过使用 or 的 format 等函数。如果存储二进制数据,则必须指定数据的大小,或者必须由函数暗示。charcharstrcpyprintf%s
3赞 Lundin 4/25/2023
“任何指针都可以像数组一样使用”不! 可能确实未对齐,但也会通过严格的别名冲突来调用未定义的行为。这个答案只是误导,不要这样写代码。dataToSendBufferIntPointerToDataToSendBuffer[0]
1赞 Lundin 4/25/2023 #2

您可以使用 a 作为包装器,然后以字节或 32 位整数的形式访问数据。这是明确定义的,可以解决对齐和指针别名的问题。这是 C 语言中序列化/反序列化的常用技术。union

typedef union
{
  uint8_t  u8  [MESSAGE_SIZE];
  uint32_t u32 [MESSAGE_SIZE/4]
} data_buf_t;

static data_buf_t buf = { .u8 = { /* init this to something */ } };
buf.u32[0] = htonl(...);

你不能做的是将原始字符缓冲区转换为一个,然后从那里砍掉 - 字符缓冲区可以有不同的对齐方式,更糟糕的是,C 没有定义会发生什么,这反过来可能导致不正确的程序行为。通过 C 中的字符类型指针访问任何变量都可以 - 但反过来就不行了!int*int

此外,为了提高可读性,请避免使用过长的标识符名称。