类型铸造指针在C

问题描述:

我正在通过一个C代码,并想知道我是否正确地理解了代码。类型铸造指针在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中,salt定义为BF_SALT结构的数据类型。

我们调用func2,传递结构的盐场。

盐字段是4个元素的阵列,每个数据类型BF_WORD(32位字或4个字节)中FUNC2

DST

的是阵列的指向的元素的名称键入BF_WORD。

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

当前,dst指向数据类型BF_WORD。 它是类型铸造,以便它指向一个字符(1字节数据)。

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

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

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

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

谢谢。

你上面的代码的理解,类同我的,也让我的芯片在我自己的一些想法

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

这里DST它的类型是BF_WORD(4个字节),则向下铸造到一个字符类型(1字节) 另外值得注意的是,虽然指针的类型是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个字节,因此前一个结果的最后三个字节将由下一个按位结果溢出。

+0

“*因此,4字节结果写入由dptr指向的salt [0] ... *”,但只有最低字节被分配给'dptr'指向的内容,因为它是'unsigned char *'!并且:哪个“* ...下一个按位结果。*”?我看不到任何回路。 – alk 2013-02-27 18:11:23

+0

@alk是的,我想到了,最低字节分配,如果其隐式typecasted,因此较高的3个字节被截断, 但我猜只隐含类型转换,如果左手分配是一个数据类型变量,而不是一个指针。 纠正我,如果我错了 – 2013-02-27 18:17:22

+0

在左边有**取消引用**指针。请看* Leushenko *的答案,因为他非常善良地查找标准。 – alk 2013-02-27 18:19:24

这里

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

执行隐式转换到unsigned char,如dptrunsigned char *类型,因此*dptr被视为unsigned char

+0

谢谢。是的,增量操作是在指针上执行的,因为有一个循环,虽然我没有提到。我已编辑帖子以显示有一个循环。 – 2013-02-27 18:31:59

+0

@NeonFlash:我明白了,所以更新了我的答案。 – alk 2013-02-28 05:53:56

只有结果的最低字节将被写入内存。由于指针指向一个char,所以int将被截断,并且在转换为左值的类型时,较高的字节将会丢失;与将结果简单分配给char变量相同的规则。有关详细信息,请参阅标准章节6.3.2.1和6.5.16.1。