2015-11-03 12 views
1

C是否犯了Vaxocentrism是一个数组块的memcpy?是C Vaxocentrist中的数组memcpy?

实施例:

double A[10]; 
double B[10]; 
// ... do stuff ... 
// copy elements 3 to 7 in A to elements 2 to 6 in B 
memcpy(B+2, A+3, 5*sizeof(double) 

作为一个相关的问题,从阵列中铸造的指针Vaxocentrist?

char A[10]; 
char* B = (char*)A; 
B[0]=2; 
A[1]=3; 
B[2]=5; 

我当然明白编写在不同的计算机体系结构和不同的编译器代码工作的想法,但如果我申请类型安全发挥到了极致,将削弱许多C'S实用的功能!对于编译器如何实现数组/指针/等,我可以假设多少/少?

+0

(一)没有,真的没有。 (b)不,不是。你可以看看标准,看看它说什么。它确实为编译器提供了很大的自由度,但是你必须走出你的主要问题。如果你尝试,你当然可以自己钉;大多数人不觉得有必要努力尝试。 –

+1

该链接的文章很长;你关心的具体失败模式是什么? –

回答

6

memcpy适用的模型在C语言标准指定的抽象机器中定义,与任何可能运行的特定物理机器无关。特别地,C中的所有对象都具有表示,其被定义为类型unsigned char[sizeof object]的重叠数组,并且memcpy适用于该表示。同样,通过强制转换或隐式转换将数组“指向”衰减“在抽象机器上完全定义,并且与物理机器无关。

此外,链接文章中没有任何一点与您询问的代码有关。

+0

是的,这不是列出的要点之一。这就是为什么我不确定它是否是vaxocentrist。 –

0

在C代码中,memcpy()在几种情况下可以是一种有用的优化。首先,如果内存数组非常小,那么复制操作通常可以直接由编译器内联,而不是调用函数。这可能是一个运行很多的紧密循环中的重大胜利。其次,在阵列非常大的情况下,硬件支持某些对齐内存情况下更快的内存访问模式,那么更快的代码可以用于绝大多数内存。你真的不想知道对于不同硬件的对齐和复制操作的可怕细节,最好只将这些东西放在memcpy()中,让每个人都使用它。

+0

我不明白这是如何回答这个问题的。 –

+0

好的,简短的回答是“不”。这个描述详细说明了为什么你不想假设硬件的问题,以及memcpy()如何/何时可以在没有这种假设的情况下为你带来好处。 – MoDJ

-2

对于第一个示例,您正确使用了+运算符。你想要尊重它指向的元素。这是安全的,因为两个数组的大小都是10,并且在为数组分配内存时,所有地址都相对于元素0是连续的。另外,您的复制不会超出您正在复制的声明数组的范围于B.

memcpy(&B[2], &A[3], 5*sizeof(double)); 

在您的相关点,你犯同样的错误,你要做到以下几点:

char A[10]; 
char* B = &A[0]; 
B[0]=2; 
A[1]=3; 
B[2]=5; 
+0

“你错误地使用了+运算符”你觉得呢? –

+0

我有理由使用加法运算符。指针运算让我抵消一个数组。问题是这是否是vaxocentrist。 –

+1

@BigEndian有趣的是,你理解指针衰变的概念,它使'B + 2'成为'memcpy'的一个有效参数,但是你选择询问'(char *)A'是否是'A'的表达式, ,衰变后,转换为**它已经有**的类型,是Vaxocentrism。 –