2013-10-06 44 views
0

铸造双指针字符指针有什么不妥?以下代码的目标是以三种不同的方式更改1元素。铸造/取消引用双数组字符指针

double vec1[100]; 
double *vp = vec1; 
char  *yp = (char*) vp; 
vp++; 
vec1[1] = 19.0; 
*vp = 12.0; 
*((double*) (yp + (1*sizeof (vec1[0])))) = 34.0; 
+1

运行它时发生了什么? –

+1

这段代码与double vec1 [100]有什么不同? vec1 [1] = 34.0;'? – Dan

+0

OP说目标是以多种方式操纵相同的元素 –

回答

0

这种类型的演员属于“如果你知道自己在做什么,但是如果你不知道如何做到危险”。

例如,在这种情况下,您已经知道“yp”的指针值(它指向double),因此在技术上可以安全地将其值增加double的大小并将其重新转换回double*

一个反例:假设你没有知道char*来自哪里...说,它是作为一个函数参数给你的。现在,你的演员阵容将是一个大问题:由于char*在技术上是1字节对齐的,而double通常是8字节对齐的,所以你不能确定你是否得到了8字节对齐的地址。如果它对齐,你的算术将产生一个有效的double*;如果不是这样,它会在解除引用时崩溃。

这只是演员如何出错的一个例子。你在做什么(乍看之下)看起来会起作用,但总的来说,当你投掷东西时你必须注意。

+0

请注意,对齐不是使双重有效的唯一的事情。许多位模式并不代表有效的双精度...并且这也可能会根据您的FPU设置产生中断。 –

+0

这是真的,但在这种情况下,他明确地通过每个指针分配有效的浮点数。 –

0

对于较新的INTEL处理器,您可以运行的主要问题是对齐。说你写这样的事:

*((double*) (yp + 4)) = 34.0; 

那么你很可能有一个运行时错误,因为双应在8个字节对齐。处理器如68k或MIPS也是如此。

这类似于具有结构并在该结构上进行投射。你不可能破坏事物。

在大多数情况下,如果您可以避免这种情况,您的代码会更强大。就我个人而言,在阅读文件时我甚至不使用这种类型的演员。相反,我从文件中获取数据并根据需要将其放入结构中。说我在一个缓冲区中读取4个字节转换为整数,我会写这样的事:

unsigned char buf[4]; 
... 
fread(buf, 1, 4, f); 
my_struct.integer = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 

现在我没有做一个丑陋的演员和我可以控制文件中的整数的字节序什么您正在运行的处理器的末端。

+0

这不符合OP的代码--OP使用的是单个元素的'sizeof',所以没有可以想象的对齐问题。 –

+0

为什么你需要使用'char *'指针,如果你手边有'vec1'数组?我觉得奇怪的是,他使用'sizeof(vec1 [0])'而不是'sizeof(double)',但没有发现它与我的答案有关。 –

+0

那么,这个代码的*目的*当然是笼罩在神秘之中的。我只是指出,如OP所写,这是安全的。建议使用'sizeof(vec1 [0])',因为这意味着你不重复数据类型,因此一旦你改变了声明类型并且忘记改变类型其他使用地点。 –