【问题标题】:What is *(uint32_t*)?什么是 *(uint32_t*)?
【发布时间】:2018-02-16 19:57:10
【问题描述】:

我很难理解*(uint32_t*)

假设我有:

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

【问题讨论】:

  • 这个演员表在这里没用。其实整个表情都是。无论如何ptr + numuint32_t *
  • 注意这个定义first appeared in C99.
  • 不得不说,鉴于这里的定义,*(uint32_t*)(ptr + num)确实和*(ptr + num)一样,当然是ptr[num]。后一种形式是更可取的恕我直言
  • 什么

标签: c uint32-t


【解决方案1】:

uint32_t 是保证 32 位的数字类型。该值是无符号的,这意味着值的范围是从 0 到 232 - 1。

这个

uint32_t* ptr;

声明了一个uint32_t*类型的指针,但该指针未初始化,即 也就是说,指针并不特别指向任何地方。尝试通过该指针访问内存将导致未定义的行为,并且您的程序可能会崩溃。

这个

uint32_t num;

只是一个uint32_t类型的变量。

这个

*(uint32_t*)(ptr + num);

ptr + num 返回一个新指针。它被称为指针算术。就像常规算术一样,只是编译器将类型的大小带入 考虑。将ptr + num 视为基于原始ptr 指针加上num uint32_t 对象的字节数的内存地址。

(uint32_t*) x 是一个演员表。这告诉编译器它应该将表达式x 视为uint32_t*。在这种情况下,它甚至不需要, 因为ptr + num 已经是uint32_t*

开头的*是解引用操作符,用于通过指针访问内存。整个表达式等价于

ptr[num];

现在,因为这些变量都没有被初始化,结果将是垃圾。

但是,如果你像这样初始化它们:

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

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

这将打印 5,因为 ptr[2] 是 5。

【讨论】:

  • OK,除了 printf 说明符。 "%" PRIu32 更好。 "%u" 匹配 unsigned
  • @chux huy 键盘精灵攻击了我,有很多“错别字”。我修复了 printf 说明符,没想到。
  • 那么uint32_tint32_t有什么区别
  • @TravisSu 阅读了我回答的第一句话。 uint32_t 用于无符号 32 位整数,意味着它存储 0 到 4294967295 之间的值,int32_t 用于有符号 32 位整数,意味着它存储 -2147483648 和 2147483647 之间的值。
  • 自学Python,这个很清楚了,谢谢
【解决方案2】:

uint32_t 定义在stdint.h 中,因此可能需要包含它

#include <stdint.h>

这个标题shall define uint32_t to be an unsigned integer type taking exactly 32 bits

【讨论】:

  • 这条评论没有回答“*(uint32_t*)是什么?”的问题
  • 而是将此作为评论添加
【解决方案3】:

这并没有真正做任何事情。让我给你一个不同的例子:

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

首先,void* 表示“通用”指针。它可以指向任何类型的对象。

现在,(uint32_t *) 的意思是“将 pointer 解释为指向 uint32_t 类型的对象的指针。

表达式的其余部分仅表示“在此指针存储的位置存储 5”。

如果您想知道uint32_t 是什么,那是一个正好为 32 位的无符号整数。而pointer + numpointer[5]的地址是一样的。

【讨论】:

  • void *pointer = &amp;data; 是有效的 C++。是从void * 隐式转换到其他在C++ 中无效的指针类型。
【解决方案4】:

这种类型的表达式通常用在类型双关语中。如果您不熟悉类型双关语,主要思想是绕过类型系统,以便您可以将某些内容视为与实际不同的类型(即将 int a 视为 double)

类型双关语背后的主要思想是,您获取一个指向当前变量的指针,然后通过将其转换为该类型的指针然后取消引用它来将其双关为不同的类型,因此您所指的是常用的强制转换和取消引用到(*(uint32_t *) = 转换为无符号 32 位 int 指针,然后取消引用)。

正如其他人指出的那样,您的代码“什么都不做”,因为您将一个 int 与一个 int 连在一起,这没有任何效果。但是,如果您想将 int 转换为 double...

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

现在您可以通过myvarnums 内存作为双精度操作,即使num 仍然是一个Int。这是一个糟糕的想法,只是作为使用双关语的玩具示例。

【讨论】:

  • 您的类型双关语示例违反了 C 严格的别名规则。在实践中,这意味着它不能在基于类型的别名分析的编译器上可靠地工作。
  • 啊,对不起。我错过了这个被标记为 C 的事实,这个例子来自 C++,不确定它与 C 的相关性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多