[英]Is it possible to subscript into a uint64_t pointer in C?
I'm a C beginner.我是C初学者。 Having trouble understanding whats happening with this code:
无法理解这段代码发生了什么:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint64_t num = 99999;
uint64_t *num_ptr = #
uint8_t first_byte = ((uint8_t *)num_ptr)[0];
printf("%hhu", first_byte);
return 0;
}
This prints 159
.这将打印
159
。
I'm looking at uint8_t first_byte = ((uint8_t *)num_ptr)[0];
我在看
uint8_t first_byte = ((uint8_t *)num_ptr)[0];
I'm trying to understand it this way: the uint64_t pointer num_ptr
is first cast as a uint8_t pointer, then we index into it with the square brackets to get the first byte.我试图以这种方式理解它:首先将 uint64_t 指针
num_ptr
为 uint8_t 指针,然后我们用方括号对其进行索引以获取第一个字节。 Is this a correct explanation?这是一个正确的解释吗? If so is it possible to index into pointers to get their partial contents without dereferencing?
如果是这样,是否可以在不取消引用的情况下索引指针以获取其部分内容?
Consider a work-alike program:考虑一个类似工作的程序:
#include <stdio.h>
#include <stdint.h>
typedef union td_USixtyFour
{
uint64_t whole;
uint8_t parts[sizeof(uint64_t)];
} USixtyFour;
int main( int argc, char **argv )
{
USixtyFour number;
number.whole = 99999;
printf( "number.parts[0] is %u / 0x%02x\n", number.parts[0], number.parts[0] );
return 0;
}
Which outputs:哪个输出:
number.parts[0] is 159 / 0x9f
Here with a C union , it's simulating what was done in the OP's code.这里有一个C union ,它模拟了 OP 代码中所做的事情。 The
.parts
covers the same memory as the .whole
. .parts
覆盖与.whole
相同的内存。 So in essence the parts
is giving access to the content of the uint64_t
's bytes-in-memory without any sort of pointer dereference.所以本质上,这些
parts
是在没有任何类型的指针取消引用的情况下访问uint64_t
的内存字节的内容。
This sort of operation will have issues with portability due to endianness , and should generally be avoided.由于字节顺序,这种操作会存在可移植性问题,通常应避免。 Of course one could mitigate this by packing into network-byte-order with functions like
htonl()
, so a known order is preserved.当然,可以通过使用
htonl()
之类的函数打包成网络字节顺序来缓解这种情况,因此保留了已知的顺序。
99999
= 0x1869F
or if you will as a 64 bit number 0000 0000 0001 869F
99999
= 0x1869F
或者如果您将作为 64 位数字0000 0000 0001 869F
9F86 0100 0000 0000
.9F86 0100 0000 0000
存储在内存中。uint8_t
is a character type on all non-exotic systems. uint8_t
是所有非奇异系统上的字符类型。((uint8_t *)num_ptr)[0];
Converts the 64 bit pointer to a 8 bit (character) pointer and then uses the []
operator to de-reference that pointer.[]
运算符取消引用该指针。0x9F
= 159 dec.0x9F
= 159 dec。%hhu
is used to print unsigned char
. %hhu
用于打印unsigned char
。 The most correct conversion specifier to use for uint8_t
would otherwise be "%" PRIU8
from inttypes.h
uint8_t
的最正确转换说明符将是inttypes.h
中的"%" PRIU8
char
s it is OK.char
的形式访问其他数据时,就可以了。int main(void)
{
uint64_t num = 99999;
uint64_t *num_ptr = #
printf("%016"PRIx64"\n", num);
for(size_t index = 0; index < sizeof(num); index++)
{
printf("Index = %2zu, value= %02hhx\n", index, ((unsigned char *)num_ptr)[index]);
}
return 0;
}
The safest method is to use memcpy
最安全的方法是使用
memcpy
int main(void)
{
uint64_t num = 99999;
uint64_t *num_ptr = #
unsigned char arr[sizeof(num)];
printf("%016"PRIx64"\n", num);
memcpy(arr, &num, sizeof(num));
for(size_t index = 0; index < sizeof(num); index++)
{
printf("Index = %2zu, value= %02hhx\n", index, arr[index]);
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.