Kur*_*o95 5 c arrays function concatenation memcpy
我想将两个相同类型的数组连接成一个具有相同类型的新数组。但是问题是我必须使用void指针,从某种意义上说,我的代码从第三个元素开始将无法工作。我在互联网上搜索了一下,但似乎没人遇到这个问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void array_float_fill(float *arr1, float *arr2, int n, int m){
for(int i = 0;i<n;i++){
*(arr1+i)=i+n;
}
for(int i = 0;i<m;i++){
*(arr2+i)=i+m;
}
}
void array_concat(void *arr1, void *arr2, void *arr3, int n, int m,int size){
for(int i=0;i<n;i++){
memcpy((arr3+i),(arr1+i),size);
}
for(int i=0;i<m;i++){
memcpy((arr3+i+n),(arr2+i),size);
}
}
int main(int argc, char const *argv[])
{
int n=10;
int m=10;
float f1[n];
float f2[m];
array_float_fill(f1,f2,n,m);
printf("%f",*(f1+3));
float* f3 = malloc((n+m) * sizeof(float));
array_concat(f1,f2,f3,n,m,sizeof(float));
printf("%f",*(f3+3));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用for-loop 尝试了将每个元素复制到新数组,因为该函数只会给我一个指向数组开始的指针。邓诺(Dunno)为什么不起作用。任何帮助和提示将不胜感激
void*指针算术......在标准 C 中实际上是不允许的。gcc 允许它并假设基本操作数大小为 1。因此它如下
使用 时,您将字节与索引混淆了memcpy。
当(非标准地)将整数添加到void指针时,整数的含义(在 gcc 中)是字节偏移量的含义。这与类型指针不同,编译器将为您进行适当的缩放:
void *p;
int i;
p[i]; // This will be literally p+i after compiling on your compiler
Run Code Online (Sandbox Code Playgroud)
但例如:
float *p;
int i;
p[i]; // This will be p+i*sizeof(float) after compiling.
Run Code Online (Sandbox Code Playgroud)
所以而不是...
for(int i=0;i<n;i++){
memcpy((arr3+i),(arr1+i),size);
}
for(int i=0;i<m;i++){
memcpy((arr3+i+n),(arr2+i),size);
}
Run Code Online (Sandbox Code Playgroud)
...你必须写(这仍然是特定于编译器的):
for(int i=0;i<n;i++){
memcpy((arr3+i*size), (arr1+i*size), size);
}
for(int i=0;i<m;i++){
memcpy((arr3+i*size+n*size), (arr2+i*size), size);
}
Run Code Online (Sandbox Code Playgroud)
...或遵循标准:
for(int i=0;i<n;i++){
memcpy((char*)arr3+i*size, (char*)arr1+i*size, size);
}
for(int i=0;i<m;i++){
memcpy((char*)arr3+i*size+n*size, (char*)arr2+i*size, size);
}
Run Code Online (Sandbox Code Playgroud)
通过转换为char*,您可以强制将基本操作数大小设置为 1 个字节(更准确地说,1 个 C 字节),考虑到 concat 函数的通用性质,这正是您想要的。
请注意,您可以将任意步长传递给memcpy,但实际上并不需要循环;相反,只需执行以下操作:
memcpy((char*)arr3, arr1, size*n);
memcpy((char*)arr3+n*size, arr2, size*m);
Run Code Online (Sandbox Code Playgroud)
仅在进行算术运算时才需要转换。