【问题标题】:Type Casting Pointer in CC中的类型转换指针
【发布时间】:2013-02-27 17:25:13
【问题描述】:

我正在阅读 C 代码,想知道我是否正确理解了代码。

头文件中定义了一个结构体BF_salt,如下图:

typedef
{
BF_WORD salt[4];
..
..
} BF_SALT;

在主 C 代码中,有一个函数调用:

function func1()
{
 static BF_SALT salt;
 func2(salt.salt,x,y);
....
}

func2(BF_WORD * dst,x,y)
{
 unsigned char * dptr= (unsigned char*)dst;
 int c1,c2;

 // c1 and c2 are initialized here.

 // in a loop, an operation similar to the below is performed.

 *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
}

我对上面代码的理解是:

在func1中,盐是用BF_SALT结构的数据类型定义的。

我们正在调用 func2,传递结构的盐字段。

salt 字段是一个由 4 个元素组成的数组,每个元素的数据类型为 BF_WORD(32 位字或 4 个字节)

在 func2 中

dst 是指向 BF_WORD 类型元素的数组的名称。

它正在对指针 dst 执行类型转换。

目前,dst 指向数据类型 BF_WORD。 它是类型转换的,因此它指向一个 char(1 字节数据)。

现在它正在对整数 c1 和 c2 执行移位操作,并将输出写入 dptr 指向的内存地址。因此,它正在覆盖最初由 dst 指向的数据(盐数组中的字节)。

c1 和 c2 是 int 数据类型,需要 4 个字节的空间。

dptr 会以什么方式覆盖数组的内容?因为每次我们执行 *dptr++,我们都将指针 dptr 前进 1 个字节,因为它指向一个字符。

但是,我们为它分配了一个大于 1 字节的大小值。数据将如何写入内存?

谢谢。

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    只有结果的最低字节会被写入内存。由于指针指向 char,因此 int 将被截断,并且在转换为左值的类型时会丢失更高的字节;就像您只是将结果分配给 char 变量一样。有关详细信息,请参阅标准部分 6.3.2.1 和 6.5.16.1。

    【讨论】:

      【解决方案2】:

      这里

      *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
      

      执行到unsigned char 的隐式转换,因为dptr 的类型为unsigned char *,所以*dptr 被视为unsigned char

      【讨论】:

      • 谢谢。是的,增量操作是在指针上执行的,因为有一个循环,虽然我没有提到。我已经编辑了帖子以显示有一个循环。
      【解决方案3】:

      你对上面代码的理解,和我很相似,也让我插播一些自己的想法

      unsigned char * dptr= (unsigned char*)dst;
      

      这里的 dst 是 BF_WORD (4 bytes) 类型,被向下转换为 char 类型 (1 byte) 另外值得注意的是,虽然指针的类型是 char ,并且可以导航 一次一个字节,它确实保存了一个 4 字节连续内存位置的地址, 所以从技术上讲,它必须能够导航这 4 个字节,一次一个字节。

      dptr 会以什么方式覆盖数组的内容?

      dptr 现在包含 4 个数字、4 字节数组 salt 的起始地址。 所以它当前访问的是 salt[0]。 这里 salt[0] 的大小是 4 个字节,而 dptr 是 1 个字节的指针,所以它需要四个(dptr++) 递增以覆盖数组 salt[0] 的一个元素。

      现在是另一个问题

      我们为它分配了一个大于 1 字节的值。数据将如何写入内存?

      *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
      

      这里 c1 和 c2 都是 int 类型,所以在按位运算之后,结果是 int 类型。 因此 4 字节的结果被写入 dptr 指向的 salt[0]; 在 dptr 的下一个增量中,指针将指向前 4 个字节的第 2 个字节 result ,因此上一个结果的最后三个字节将被下一个按位结果覆盖。

      【讨论】:

      • "因此 4 字节结果被写入 dptr 指向的 salt[0] ..." 但只有最低字节分配给 dptr 指向的内容,因为它是unsigned char *!并且:请问哪个“...下一个按位结果。”?我看不到循环。
      • @alk 是的,我想到了,如果它被隐式类型转换,则分配最低字节,因此较高的 3 个字节被截断,但我猜隐式类型转换仅发生,如果左手分配是数据类型变量而不是指针。如果我错了,请纠正我
      • 左边有一个 dereferenced 指针。请参阅 Leushenko 的回答,因为他很乐意查找标准。
      • 顺便说一句:指向的指针有一个类型,一个指向它们所指向的指针。
      • 感谢 Barath 调查我给出的解释。我明白了:)
      猜你喜欢
      • 2020-11-17
      • 1970-01-01
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 2014-08-14
      相关资源
      最近更新 更多