将一种类型的数组转换为另一种

时间:2016-10-16 16:34:40

标签: c++ c arrays pointers casting

基本上我有一系列双打。我想将此数组传递给一个函数(ProcessData),它将它们视为短整数。创建一个短指针并将其指向数组,然后将此指针传递给函数ok(代码1)?

这实际上与创建一个短数组相同,迭代每个元素并将double数组的每个元素转换为short,然后传递短数组指针(代码2)?感谢

//code 1
//.....
short* shortPtr = (short*)doubleArr;
ProcessData(shortPtr);

...

//code 2
//...
short shortArr [ARRSIZE];
int i;
for (i = 0; i < ARRSIZE; i++)
{
    shortArr[i] = (short)doubleArr[i];
}
ProcessData(shortArr);

4 个答案:

答案 0 :(得分:3)

正如各种评论所说,你不能只是施展。但是如果你使用迭代器,你可以获得或多或少相同的效果:

void do_something_with_short(short i) {
    /* whatever */
}

template <class Iter>
void do_something(Iter first, Iter last) {
    while (first != last)
        do_something_with_short(*first++);
}

您可以使用迭代器将该模板函数调用为任何算术类型的数组(实际上,任何可隐式转换为short的类型,或者,如果您在调用{{1}时添加强制转换},具有需要强制转换的类型:

do_something_with_short

答案 1 :(得分:2)

不,你不能那样做。这至少有一个原因:

数组是通过索引访问的几个内存分配的连续序列,如此

[----][----][----]

注意方括号内的四个破折号。这表明在C / C ++的大多数情况下,int 四个字节长。可以通过索引访问数组单元格,因为如果我们知道第一个单元格(m)的内存地址,并且我们知道每个单元格的大小(c) - 在这种情况下,四个通过执行m + index * c

,我们可以轻松找到任何索引的内存位置
[----][----][----]
^ array[0]


[----][----][----]
 ----  ----  ^ array[2]

从根本上说,这就是为什么指针可以像C / C ++中的数组一样对待,因为当你访问数组时,你基本上都在做指针运算。

在大多数情况下,在C / C ++中,短的 2个字节长,所以以相同的方式表示

[--][--][--]

如果您创建一个short指针,并尝试将其用作数组,则应指向与上述类似的内容。如果你试图对它进行索引,则会出现问题:如果你处理的是一组short,那么array [2]的位置与m + 2 * index相同,如下所示

[--][--][--]
 --  --  ^ array[2] (note moving along four bytes)

但是由于我们实际上处理的是整数数组,所以会发生以下情况

[----][----][----]
 ----  ^ array[2] (again moving along four bytes)

这显然是错误的

答案 2 :(得分:0)

不,因为++ptr实际上执行ptr = (char*)ptr + sizeof *ptr(根据定义sizeof (char)为1)。因此,递增double指针会将其移动(通常)8个字节,而递增short指针只会将其移动2个字节。

答案 3 :(得分:0)

假设您的孩子学习钢琴,偶尔会要求您扫描一堆由{20}出生的老师给他们的sheet music(就像您自己一样)。您将这些床单带到办公室并将它们送到复印机。它可以创建体面的数字扫描,让您的孩子可以在配备触摸屏的钢琴上使用。一切顺利,直到有一天孩子带给你一套罕见的vinyl records。她不顾一切地找到乐谱形式的旋律,但要求你至少复制唱片。在音乐方面缺乏经验,你把这些磁盘带到你的办公室,把它们装在扫描仪的automatic document feeder里,然后意识到你已经深陷......呃...只有当你听到乙烯基磁盘的声音时才是垃圾打破愚蠢的机器。即使复印机没有配备ADF,并且您必须手动将所有原件放在玻璃平板上,当您将扫描结果发送给您的女儿时,您几乎不会得到公平的赞誉。

扫描仪并不关心您放入的内容 - 只要它适合内部。它做到了最好,但结果不符合预期。但是,如果您首先将黑胶唱片录制给经验丰富的音乐家,并将其作为乐谱写下来,那么扫描这些唱片会让您的孩子感到非常高兴。

在C ++中,不同类型可能会有不同的程度,即打印的纸张与CD不同。期望接收short s数组的C ++函数将处理任何字节/位序列作为short s的数组。它并不关心存储区实际上是否填充了不同类型的值,具有完全不同的表示,就像扫描仪不关心ADF上堆栈的内容一样。假设一个函数将内部将数组的每个元素从double转换为short,就像认为复印机包括留声机和音乐家一样,它会自动将黑胶唱片转录成纸张形式。请注意,后者是真实世界复印机的可能设计,其他一些编程语言也是如此。但不是 1 C ++的现有实现。

1 从理论上讲,C / C ++的标准兼容实现是可能的,它可以解释语言中UB的所有条款,有利于你的问题的相反答案,而不是赞成最好的性能。但对于像C / C ++这样的语言来说,这没什么意义。