简体   繁体   English

什么是 *(uint32_t*)?

[英]What is *(uint32_t*)?

I have a hard time understanding *(uint32_t*) .我很难理解*(uint32_t*)

Let's say that I have:假设我有:

uint32_t* ptr;
uint32_t num
*(uint32_t*)(ptr + num); // What does this do? Does it 

uint32_t is a numeric type that guarantees 32 bits. uint32_t是保证 32 位的数字类型。 The value is unsigned, meaning that the range of values goes from 0 to 2 32 - 1.该值是无符号的,这意味着值的范围从 0 到 2 32 - 1。

This

uint32_t* ptr;

declares a pointer of type uint32_t* , but the pointer is uninitialized, that is, the pointer does not point to anywhere in particular.声明了一个uint32_t*类型的指针,但该指针未初始化,也就是说,该指针没有特别指向任何地方。 Trying to access memory through that pointer will cause undefined behaviour and your program might crash.尝试通过该指针访问内存将导致未定义的行为,并且您的程序可能会崩溃。

This

uint32_t num;

is just a variable of type uint32_t .只是一个uint32_t类型的变量。

This

*(uint32_t*)(ptr + num);

ptr + num returns you a new pointer. ptr + num返回一个新指针。 It is called pointer arithmetic.它被称为指针算术。 It's like regular arithmetic, only that compiler takes the size of types into consideration.这就像常规算术,只是编译器考虑了类型的大小。 Think of ptr + num as the memory address based on the original ptr pointer plus the number of bytes for num uint32_t objects.ptr + num视为基于原始ptr指针加上num uint32_t对象的字节数的内存地址。

The (uint32_t*) x is a cast. (uint32_t*) x是一个演员表。 This tells the compiler that it should treat the expression x as if it were a uint32_t* .这告诉编译器它应该将表达式x视为uint32_t* In this case, it's not even needed, because ptr + num is already a uint32_t* .在这种情况下,它甚至不需要,因为ptr + num已经是uint32_t*

The * at the beginning is the dereferencing operator which is used to access the memory through a pointer.开头的*是解引用运算符,用于通过指针访问内存。 The whole expression is equivalent to整个表达式等价于

ptr[num];

Now, because none of these variables is initialized, the result will be garbage.现在,因为这些变量都没有被初始化,结果将是垃圾。

However, if you initialize them like this:但是,如果您像这样初始化它们:

uint32_t arr[] = { 1, 3, 5, 7, 9 };
uint32_t *ptr = arr;
uint32_t num = 2;

printf("%u\n", *(ptr + num));

this would print 5, because ptr[2] is 5.这将打印 5,因为ptr[2]是 5。

uint32_tstdint.h定义,因此可能需要包含它

#include <stdint.h>

This doesn't really do anything.这真的没有任何作用。 Let me give you a different example:让我给你一个不同的例子:

uint32_t data;
void *pointer = &data;
*(uint32_t *)pointer = 5;

First of all, void* means "generic" pointer.首先, void*表示“通用”指针。 It can point to objects of any type.它可以指向任何类型的对象。

Now, (uint32_t *) means "interpret pointer as a pointer to an object with type uint32_t .现在, (uint32_t *)表示“将pointer解释为指向类型为uint32_t的对象的指针。

The rest of the expression simply means "store 5 at the location stored by this pointer".表达式的其余部分仅表示“在此指针存储的位置存储 5”。

If you want to know what uint32_t is, that's an unsigned integer with exactly 32 bits.如果你想知道uint32_t是什么,那是一个 32 位的无符号整数。 And pointer + num is the same as the adress of pointer[5] .并且pointer + numpointer[5]的地址相同。

This type of expression is usually used in type punning.这种类型的表达式通常用于类型双关。 If you're not familiar with type punning, the main idea is to bypass the type system so that you can treat something as a different type than it really is (ie treat an int a as double)如果您不熟悉类型双关语,主要思想是绕过类型系统,以便您可以将某些东西视为与实际不同的类型(即将 int a 视为 double)

The main idea behind type punning is you take a pointer to a current variable and then pun it into a different type by casting it into a pointer of that type and then dereferencing it, hence the commonly used cast and dereference you are referring to ( *(uint32_t *) = cast to unsigned 32bit int pointer and then dereference).类型双关背后的主要思想是您获取一个指向当前变量的指针,然后通过将其转换为该类型的指针然后取消引用它来将其转换为不同的类型,因此您所指的常用转换和取消引用( *(uint32_t *) = 转换为无符号 32 位 int 指针,然后取消引用)。

As others have pointed out, your code "does nothing" because you are punning an int to an int, which has no effect.正如其他人指出的那样,您的代码“什么都不做”,因为您将 int 转换为 int,这没有任何效果。 If you wanted to pun an int into a double however...但是,如果您想将 int 转换为 double ......

uint32_t num=5;
double& myvar=*(double*) &num;

Now you can manipulate num s memory as a double via myvar even though num is still an Int.现在,即使num仍然是 Int,您也可以通过myvar num的内存作为 double 进行myvar This is a terrible idea and is just meant as a toy example of the use of punning.这是一个糟糕的想法,只是作为使用双关语的一个玩具示例。

Why can't i just declare a unsigned int variable ?Is there any difference?为什么我不能只声明一个unsigned int variable ?有什么区别吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM