提问人:someuser47 提问时间:4/25/2023 最后编辑:ryykersomeuser47 更新时间:4/25/2023 访问量:81
是否可以在 Char-Array(或类似)上获取 Int-Array-Pointer?
Is it possible to get an Int-Array-Pointer on a Char-Array (or sth similar)?
问:
我想将五个整数(作为 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 个单独指针的类似情况)?
(我想理想情况下只使用一个数组,所以不要只是复制数组(多个指针是可以的)。使用静态,因为它稍后将无休止地循环。
问候并感谢您的任何帮助
答:
任何指针都可以像数组一样使用,指向单个值或指向数组的第一个值的指针之间没有区别。当然,如果您使用指针访问无效内存,则行为是未定义的。
*pointer
等同于 。pointer[0]
以下代码片段仅用于演示如何根据问题中的原始代码将指针用作数组。它不会修复原始代码中的其他问题。
int* IntPointerToDataToSendBuffer = (int*)(&dataToSendBuffer);
IntPointerToDataToSendBuffer[0] = htonl(stoi(uSensorID); /* unrelated syntax error here */
IntPointerToDataToSendBuffer[1] = -1;
等。
但是:将 char
* 转换为 int *
并取消引用此指针是错误的。
这似乎在某些平台上有效(因为这是未定义行为的一种可能变体),我经常在实际代码中看到它。
除了违反正式规则外,您还可能会在某些平台上遇到问题。可能需要比 .根据您的平台,如果数组碰巧没有按照数组的要求对齐,这可能会导致编译器警告、执行速度变慢或程序中止,从而导致对齐陷阱。
我也看到了这些问题,我永远不会这样做。int*
char *
char
int
你应该反过来做:使用一个数组并将其转换为一个,以便将其用作字节数组/缓冲区。int
char *
评论
char
char
strcpy
printf
%s
dataToSendBuffer
IntPointerToDataToSendBuffer[0]
您可以使用 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
此外,为了提高可读性,请避免使用过长的标识符名称。
评论