是否具有在C / C ++中复制数组的功能?


91

我是一名学习C / C ++的Java程序员。所以我知道Java具有类似System.arraycopy();的功能。复制数组。我想知道在C或C ++中是否有一个函数可以复制数组。我只能通过使用for循环,指针等来找到复制数组的实现。有可以用来复制数组的函数吗?


7
man memmoveman memcpy
Tim Cooper

28
不要用memcpy,用std::copy。如果您的类型具有有意义的副本构造函数,则将memcpy做错事情。
Ed S.

10
您实际上是在尝试同时学习C和C ++吗?它们是非常不同的语言。
Ferruccio

1
好吧,我学了一点C语言,现在我最近开始学习C ++。根据我从在线资源中读到的内容,我认为C ++只是一种语言,它具有C语言许多附加功能。
JL 2013年

6
我之所以这样说,是因为以前没有人提到它:在C ++中,几乎在所有情况下都应使用std :: vector。在某些情况下,其他容器也是有用的,但在大多数情况下,std :: vector将是最佳选择。不要在C ++中使用原始数组,除非有必要,否则请尽量避免使用std :: array。
Skalli 2013年

Answers:


79

从C ++ 11开始,您可以直接使用复制数组std::array

std::array<int,4> A = {10,20,30,40};
std::array<int,4> B = A; //copy array A into array B

这是关于std :: array的文档


@XAleXOwnZX:与支持副本分配的任何其他类型相同。B = A
swalog

2
我认为函数是将A的内存地址复制到B。如果我尝试在不更改B的内存地址的情况下将A的项目值复制到B。我怎样才能做到这一点?
亚伦·李

@Aaron_Lee:我刚刚对其进行了测试,它确实将元素复制到位于单独存储位置的数组中。数组类显然对赋值运算符有其自己的重载。
Dave Rove

4
你们知道在这两行代码中没有赋值运算符,对吗?即使表示法看起来像赋值运算符,也就是被调用的复制构造函数。
白化病Cordeiro

138

由于您要求使用C ++解决方案...

#include <algorithm>
#include <iterator>

const int arr_size = 10;
some_type src[arr_size];
// ...
some_type dest[arr_size];
std::copy(std::begin(src), std::end(src), std::begin(dest));

2
erreur:'begin'不是'std'的成员
David天宇Wong 2014年

23
@David天宇Wong:您正在使用旧的编译器,或者未包含标头。它在<iterator>
Ed S.

9
也许您应该说出其中包括您的需要。复制在<algorithm>吗?
杰里·耶利米

15
我只问是因为您是否必须解释std :: begin在<iterator>中,这意味着人们不会在Google搜索std :: begin来查找它所在的标头,因此他们不太可能使用Google std :: copy来查找同一标头原因。如果没有人要问只在评论中回答的问题,它会提供更好的答案。也许我应该只是编辑答案,而不要提示您去做。
杰里·耶利米

3
您可以将begin(src)更改为src,将end(src)更改为src + arr_size
Calvin

82

正如其他人提到的,在C中,您将使用memcpy。但是请注意,这会进行原始内存复制,因此,如果您的数据结构具有指向自身或彼此的指针,则副本中的指针仍将指向原始对象。

在C ++中,你也可以使用memcpy,如果你的数组成员是POD(即你也可能用于在C不变,基本类型),但在一般情况下,memcpy不会被允许。正如其他人提到的,要使用的函数是std::copy

话虽如此,在C ++中,您很少应该使用原始数组。相反,您应该使用标准容器之一(std::vector是最接近内置阵列,也是我认为最接近Java数组-比普通的C接近++阵列,确实是- ,但std::deque还是std::list可以在某些情况下更合适)或者,如果您使用的是C ++ 11,std::array它与内置数组非常接近,但是具有类似于其他C ++类型的值语义。我在这里提到的所有类型都可以通过赋值或复制构造来复制。此外,您可以使用迭代器语法从opne“交叉复制”到另一个(甚至从内置数组)。

这给出了可能性的概述(我假设已经包括了所有相关的标头):

int main()
{
  // This works in C and C++
  int a[] = { 1, 2, 3, 4 };
  int b[4];
  memcpy(b, a, 4*sizeof(int)); // int is a POD

  // This is the preferred method to copy raw arrays in C++ and works with all types that can be copied:
  std::copy(a, a+4, b);

  // In C++11, you can also use this:
  std::copy(std::begin(a), std::end(a), std::begin(b));

  // use of vectors
  std::vector<int> va(a, a+4); // copies the content of a into the vector
  std::vector<int> vb = va;    // vb is a copy of va

  // this initialization is only valid in C++11:
  std::vector<int> vc { 5, 6, 7, 8 }; // note: no equal sign!

  // assign vc to vb (valid in all standardized versions of C++)
  vb = vc;

  //alternative assignment, works also if both container types are different
  vb.assign(vc.begin(), vc.end());

  std::vector<int> vd; // an *empty* vector

  // you also can use std::copy with vectors
  // Since vd is empty, we need a `back_inserter`, to create new elements:
  std::copy(va.begin(), va.end(), std::back_inserter(vd));

  // copy from array a to vector vd:
  // now vd already contains four elements, so this new copy doesn't need to
  // create elements, we just overwrite the existing ones.
  std::copy(a, a+4, vd.begin());

  // C++11 only: Define a `std::array`:
  std::array<int, 4> sa = { 9, 10, 11, 12 };

  // create a copy:
  std::array<int, 4> sb = sa;

  // assign the array:
  sb = sa;
}

1
memcpy的例子是错误的。源和目标已切换。
AT-学生

1
实际上,这并不是memcpy示例中的唯一错误;大小也错了。我已经解决了,谢谢。
celtschk 2015年

为什么您一直都在编写std而不是仅使用std的名称空间?
2015年

你不能做memcpy(b,a,sizeof a); 太?
Rodi 2015年

Java数组std:array比like更像std::vector,因为它具有固定的大小。
Bart van Heukelom

17

您可以使用memcpy()

void * memcpy ( void * destination, const void * source, size_t num );

memcpy()num字节值source直接从指向的位置复制到指向的存储块destination

如果destinationsource重叠,则可以使用memmove()

void * memmove ( void * destination, const void * source, size_t num );

memmove()num字节的值从指向的位置复制到指向source的存储块destination。复制就像使用中间缓冲区一样进行,从而允许目标和源重叠。


3
这里必须-1。OP专门要求使用C ++解决方案,该回答没有说​​明memcpy错误的情况,即复制字节不足。
Ed S.

2
@EdS。如果您没有注意到,OP现在正在要求CC ++解决方案。
自闭症

4
当我回答时,OP要求C / C ++解决方案,尽管我个人认为“ C / C ++”侮辱这两种语言。:)
Deepu

公平地说,我没有意识到它正在改变。也许它甚至早一点说了,但我错过了。-1删除。
Ed S.

2
@EdS我以为是2分钟,但是无论如何,在发布此答案时,问题都涉及到C和C ++。即使我做错了,在某个时候问题只说了C ++,也没有必要提出否决票。
吉姆·巴尔特

16

使用memcpy在C,std::copyC ++中。


对于一个小数组,我假设都不引起任何函数调用开销(memcpy应该是编译器固有的)吗?
wcochran

@Mehrdad,我没有说其他的话;只是发表评论。我也没有投票反对。
MD XF

12

我喜欢Ed S.的答案,但这仅适用于固定大小的数组,不适用于将数组定义为指针的情况。

因此,C ++解决方案将数组定义为指针:

#include<algorithm>
...
const int bufferSize = 10;
char* origArray, newArray;
std::copy(origArray, origArray + bufferSize, newArray);

注意:无需扣除buffersize1:

  1. 从第一个开始复制并复制到最后一个-1范围内的所有元素

请参阅:https//en.cppreference.com/w/cpp/algorithm/copy


10

在C中,您可以使用memcpy。在C ++中使用std::copy从所述<algorithm>报头中。


3

在C ++ 11中,您可以将Copy()其用于std容器

template <typename Container1, typename Container2>
auto Copy(Container1& c1, Container2& c2)
    -> decltype(c2.begin())
{
    auto it1 = std::begin(c1);
    auto it2 = std::begin(c2);

    while (it1 != std::end(c1)) {
        *it2++ = *it1++;
    }
    return it2;
}

std::end出于性能原因(退出循环期间c1不会更改或使迭代器无效,因此不必重新计算结束),退出循环是一个更好的主意。
celtschk's

3

我在这里给出了两种应对数组的方法,适用于C和C ++语言。memcpycopy都可以在C ++上使用,但copy不适用于C,如果要在C中复制数组,则必须使用memcpy

#include <stdio.h>
#include <iostream>
#include <algorithm> // for using copy (library function)
#include <string.h> // for using memcpy (library function)


int main(){

    int arr[] = {1, 1, 2, 2, 3, 3};
    int brr[100];

    int len = sizeof(arr)/sizeof(*arr); // finding size of arr (array)

    std:: copy(arr, arr+len, brr); // which will work on C++ only (you have to use #include <algorithm>
    memcpy(brr, arr, len*(sizeof(int))); // which will work on both C and C++

    for(int i=0; i<len; i++){ // Printing brr (array).
        std:: cout << brr[i] << " ";
    }

    return 0;
}

4
using namespace std;这是不好的做法。永远不要使用它。请使用cppreference.com而不是cplusplus.com,它包含了更好的标准文档。stdio.hC ++中的等效项是cstdio,请改用。此外,该代码是相当惯用的C ++。我认为如果您展示了针对C和C ++的单独解决方案,那将会更加清楚。
tambre

3

只需在代码中包含标准库即可。

#include<algorithm>

数组大小将表示为 n

你的旧数组

int oldArray[n]={10,20,30,40,50};

声明新数组,您必须在其中复制旧数组值

int newArray[n];

用这个

copy_n(oldArray,n,newArray);

1

首先,由于要切换到C ++,建议使用vector代替传统的array。此外,要复制数组或向量,std::copy是您的最佳选择。

访问此页面以获取如何使用复制功能: http //en.cppreference.com/w/cpp/algorithm/copy

例:

std::vector<int> source_vector;
source_vector.push_back(1);
source_vector.push_back(2);
source_vector.push_back(3);
std::vector<int> dest_vector(source_vector.size());
std::copy(source_vector.begin(), source_vector.end(), dest_vector.begin());
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.