【问题标题】:Why are pointer type casts necessary?为什么需要指针类型强制转换?
【发布时间】:2021-05-08 15:41:27
【问题描述】:

我不明白为什么指针类型转换是必要的,只要指针指向一个地址并且它们的类型仅在涉及指针算术时才重要。

也就是说,如果我遇到下一个代码sn -p:

int a = 5; 然后都是

char*b = (char*)&a;int*c = (int*)&a

指向同一个内存位置。

确实,在执行char*b = (char*)&a时,可能会丢失部分内存内容,但这是因为b的类型是char*,它只能存储sizeof(char)字节的内存,这是可以做到的隐含的。

【问题讨论】:

  • 您不能随意更改指针类型和访问内存。 What is the strict aliasing rule? 有很多错误的代码违反了这条规则,你会被告知“但它有效!”那些不了解未定义行为的后果的人包括 appears 起作用。因为它只会“起作用”,直到它不起作用。例如:gcc, strict-aliasing, and horror stories
  • 我看到一个强制转换是给编译器的信息:“我知道我做错了什么,请不要抱怨,去做吧。”
  • 这里要解释的东西太多了。指针类型兼容性、对齐方式、指针大小、指针别名、数据类型表示、字节序等。

标签: c pointers gcc types casting


【解决方案1】:

当您取消引用指针时,指针的类型很重要。

摘录

char *b = (int*)&a;

错误,因为int * 不能分配给char *。你的意思是char *b = (char *)&a;。 C 标准说您需要显式转换,因为类型不兼容。这就是“是的,我知道我在做什么”。

摘录

int*c = (int*)&a;

是对的,但是&a 已经是一个指向int 的指针,所以强制转换不会做任何转换,所以你可以写成int *c = &a;

【讨论】:

  • 我的错,我错了,因此我编辑了我的帖子,摘录为 char * b = (char *)&a; .此外,int *c = &a 是正确的,但我想强调的是,从我的角度来看,与强制转换相关的唯一重要的事情是读取字节的大小。
  • 此外,使用char 访问较大类型的一部分总是错误的,因为它是一个可能有符号也可能没有符号的类型,这意味着如果存在符号位可能会被设置。要使用的正确类型是 unsigned charuint8_t
  • 现在我明白编译器非常小心并试图警告我我可能做错了什么,因此,我必须强制转换才能告诉编译器我知道我做了什么“疯狂” .
  • @Lundin “几乎总是”:D
  • 另外,我希望在传递“不兼容”指针类型时收到警告而不是编译错误。
【解决方案2】:

只要指针指向一个地址,并且它们的类型仅在涉及指针运算时才重要。

不,不是用于指针算术。它对于访问指针指向的数据很重要,如您的示例中错误的访问方式会导致不正确的结果。

执行 charb = (int)&a 时可能会丢失一部分内存内容,但这是由于 b 的类型是 char* 只能存储 sizeof(char) 个字节记忆,

首先,这样做是错误的(除非我们真的需要从 4 个字节中提取 1 个字节)
其次,指针转换的应用主要用于 w.r.t void*(void pointers) 为可以处理多种不同类型的函数传递数据时,最好的例子是 qsort

【讨论】:

    【解决方案3】:

    指针类型在取消引用时很重要,因为它指示应该读取或存储多少字节。

    执行指针运算时也很重要,因为这是以指针指向的大小为单位完成的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      相关资源
      最近更新 更多