C++ copy()函数用法详解(深入了解,一文学会)

        C++ 算法 copy() 函数用于将容器 [first,last] 的所有元素从结果开始复制到不同的容器中。

        本文介绍了copy、strcpy、strncpy、memcpy、copy_n、copy_if、copy_backward等使用方法和代码示例

本文作者原创,转载请附上文章出处与本文链接。

C++ copy()函数用法详解目录

1 copy

2 strcpy

3 strncpy

4 memcpy

5 copy_n

6 copy_if

7 copy_backward


1 copy

    //declaring & initializing an int array
    int arr[] = { 10, 20, 30, 40, 50 };
    
    //向量声明
    vector v1(5);
    
    //复制数组元素到向量
    copy(arr, arr + 5, v1.begin());

    Output:
    //如果我们打印值
    arr: 10 20 30 40 50
    v1: 10 20 30 40 50

2 strcpy

char* strcpy( char* dest, const char* src );
  • 拷贝src到dest中,包括结束空字符
  • 如果dest不够大或者两个字符串的范围有重叠,其行为未定义
  • 返回值为dest

#include 
#include < cstring >

int main()
{
    // strcpy
    char* s1 ;
    s1 = (char*)"1234";
    char s2[3] = { 0 };

    strcpy(s2, s1);

    std::cout << "s1: " << s1 << std::endl;
    std::cout << "s2: " << s2 << std::endl;

    return 0;
}


3 strncpy

char *strncpy( char *dest, const char *src, std::size_t count );
  • 拷贝src一定数量的字符到dest中,包括结束空字符
  • 如果count比src的长度小,则dest将不是以空字符结尾
  • 如果count比src的长度大,则继续填充空字符到dest中

#include 
#include < cstring >

int main()
{
    // strncpy
    char* s1 = (char*)"1234";
    char s2[10] = { 0 };

    strncpy(s2, s1, 5);

    std::cout << "s1: " << s1 << std::endl;
    std::cout << "s2: " << s2 << std::endl;


    return 0;
}


4 memcpy

void* memcpy( void* dest, const void* src, std::size_t count );
  • 从src中拷贝count个字节到dest中,过程中dest和src均被重新解释为unsigned char数组
  • 如果dest和src有重叠,则行为未定义
  • 如果dest或src为无效的或者空指针,其行为未定义,即使count为0

#include 
#include < cstring >

int main()
{
    // memcpy
    char* s1 = (char*)"1234";
    char s2[10] = { 0 };

    memcpy(s2, s1, 5);

    std::cout << "s1: " << s1 << std::endl;
    std::cout << "s2: " << s2 << std::endl;



    return 0;
}


5 copy_n

        copy_n() 算法可以从源容器复制指定个数的元素到目的容器中。第一个参数是指向第一个源元素的输入迭代器,第二个参数是需要复制的元素的个数,第三个参数是指向目的容器的第一个位置的迭代器。这个算法会返回一个指向最后一个被复制元素的后一个位置的迭代器,或者只是第三个参数——输出迭代器——如果第二个参数为 0。下面是一个使用它的示例:

#include
#include
#include
using namespace std;


int main(int argc, char** argv) 
{

	vector u1 = { 2,6,8,4,9,4 };
	vector u2(6);
	vector u3(6);
	copy(u1.begin(), u1.begin() + 3, u2.begin());
	cout << "The new vector with copy contains:";
	for (int k = 0; k < u2.size(); k++)
		cout << u2[k] << " ";
	copy_n(u1.begin(), 4, u3.begin());
	cout << "\n";
	cout << "The new vector using copy_n contains:";
	for (int m = 0; m < u3.size(); m++)
		cout << u3[m] << " ";


	return 0;
}

6 copy_if

copy_if() 算法可以从源序列复制使谓词返回 true 的元素,所以可以把它看作一个过滤器。前两个参数定义源序列的输入迭代器,第三个参数是指向目的序列的第一个位置的输出迭代器,第 4 个参数是一个谓词。会返回一个输出迭代器,它指向最后一个被复制元素的下一个位置。下面是一个使用 copy_if() 的示例:

#include 
#include 
#include 
#include     // accumulate
#include 
using namespace std;
int main()
{
    std::vector flags{ true, true, false, true };
    std::vector veca{ 0.1, 0.2, 0.3, -0.1 };

    std::vector vecb;
    vecb.reserve(std::accumulate(flags.begin(), flags.end(), 0));

    size_t i = 0;
    // vecb在reserve之后并没有未元素分配内存,插入应该使用back_inserter(vecb)
    // vecb在resize之后为元素分配了内存,使用back_inserter(vecb)会在已经分配内存的元素之后插入
    // 这时应该使用 vecb.begin(),对已经分配的内存进行覆盖
 
    std::copy_if(veca.begin(), veca.end(), std::back_inserter(vecb),
        [&i, &flags](double a) {return flags[i++]; });

    for (auto& s : vecb)
        std::cout << s << std::endl;

    return 0;
}

#include 
#include 
#include 
#include     // accumulate
#include 
using namespace std;
int main()
{
    std::vector flags{ true, true, false, true };
    std::vector veca{ 0.1, 0.2, 0.3, -0.1 };

    std::vector vecb;
    vecb.reserve(std::accumulate(flags.begin(), flags.end(), 0));

    size_t i = 0;

    i = 0;
    std::vector vecc;
    std::remove_copy_if(veca.begin(), veca.end(), std::back_inserter(vecc),
        [&i, &flags](double a){return flags[i++]; });
    std::cout << "veca\n";
    for (auto& s : veca)
        std::cout << s << "\t";
    std::cout << "\nvecc\n";
    for (auto& s : vecc)
        std::cout << s << "\t";

    return 0;
}

 

7 copy_backward

        不要被 copy_backward() 算法的名称所误导,它不会逆转元素的顺序。它只会像 copy() 那样复制元素,但是从最后一个元素开始直到第一个元素。
        copy_backward() 会复制前两个迭代器参数指定的序列。第三个参数是目的序列的结束迭代器,通过将源序列中的最后一个元素复制到目的序列的结束迭代器之前,源序列会被复制到目的序列中,如图 1 所示。copy_backward() 的 3 个参数都必须是可以自增或自减的双向迭代器,这意味着这个算法只能应用到序列容器的序列上。

#include 
#include 
#include 
using namespace std;
void main()
{
	//创建两个容器 和 两个数组
	vector v = { 1,2,3,4,5,6,7,8,9,10 };
	vector v2(10);
	vector::iterator vi;//迭代器
	int arr[10] = { 11,12,13,14,15,16,17,18,19,20 };

	cout << "执行copy算法前:\n";
	// 输出 v
	cout << "容器 v:   ";
	for (vi = v.begin(); vi < v.end(); vi++) { cout << *vi << "\t"; }
	cout << endl;
	// 输出 v2	
	cout << "容器 v2:  ";
	for (vi = v2.begin(); vi < v2.end(); vi++) { cout << *vi << "\t"; }
	cout << endl;
	// 输出 arr	
	cout << "数组 arr: ";
	for (int i = 0; i < 10; i++) { cout << arr[i] << "\t"; }
	cout << endl;


	cout << "\n执行 copy_backward 算法后:\n";
	// STL copy_backward算法
	// 1、拷贝源是容器,拷贝目标是容器
	copy_backward(v.begin(), v.begin() + 5, v2.end());
	// 输出 v2	
	cout << "容器 v2:  ";
	for (vi = v2.begin(); vi < v2.end(); vi++) { cout << *vi << "\t"; }
	cout << endl << endl;

	// 2、拷贝源是数组,拷贝目标是容器
	copy_backward(arr, arr + 5, v2.end() - 1);
	// 输出 v2	
	cout << "容器 v2:  ";
	for (vi = v2.begin(); vi < v2.end(); vi++) { cout << *vi << "\t"; }
	cout << endl << endl;

	// 3、拷贝源是容器,拷贝目标是同一个容器
	copy_backward(v.begin(), v.begin() + 7, v.end());
	// 输出 v2	
	cout << "容器 v :  ";
	for (vi = v.begin(); vi < v.end(); vi++) { cout << *vi << "\t"; }
	cout << endl;
}

C++ copy()函数用法详解(深入了解,一文学会)_第1张图片

你可能感兴趣的:(#,C++,STL基础算法,c++)