• 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

    1. //declaring & initializing an int array
    2. int arr[] = { 10, 20, 30, 40, 50 };
    3. //向量声明
    4. vector<int> v1(5);
    5. //复制数组元素到向量
    6. copy(arr, arr + 5, v1.begin());
    7. Output:
    8. //如果我们打印值
    9. arr: 10 20 30 40 50
    10. v1: 10 20 30 40 50

    2 strcpy

    char* strcpy( char* dest, const char* src );
    • 拷贝src到dest中,包括结束空字符
    • 如果dest不够大或者两个字符串的范围有重叠,其行为未定义
    • 返回值为dest
    1. #include
    2. #include < cstring >
    3. int main()
    4. {
    5. // strcpy
    6. char* s1 ;
    7. s1 = (char*)"1234";
    8. char s2[3] = { 0 };
    9. strcpy(s2, s1);
    10. std::cout << "s1: " << s1 << std::endl;
    11. std::cout << "s2: " << s2 << std::endl;
    12. return 0;
    13. }

    3 strncpy

    char *strncpy( char *dest, const char *src, std::size_t count );
    • 拷贝src一定数量的字符到dest中,包括结束空字符
    • 如果count比src的长度小,则dest将不是以空字符结尾
    • 如果count比src的长度大,则继续填充空字符到dest中
    1. #include
    2. #include < cstring >
    3. int main()
    4. {
    5. // strncpy
    6. char* s1 = (char*)"1234";
    7. char s2[10] = { 0 };
    8. strncpy(s2, s1, 5);
    9. std::cout << "s1: " << s1 << std::endl;
    10. std::cout << "s2: " << s2 << std::endl;
    11. return 0;
    12. }

    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
    1. #include
    2. #include < cstring >
    3. int main()
    4. {
    5. // memcpy
    6. char* s1 = (char*)"1234";
    7. char s2[10] = { 0 };
    8. memcpy(s2, s1, 5);
    9. std::cout << "s1: " << s1 << std::endl;
    10. std::cout << "s2: " << s2 << std::endl;
    11. return 0;
    12. }

    5 copy_n

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

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. int main(int argc, char** argv)
    6. {
    7. vector<int> u1 = { 2,6,8,4,9,4 };
    8. vector<int> u2(6);
    9. vector<int> u3(6);
    10. copy(u1.begin(), u1.begin() + 3, u2.begin());
    11. cout << "The new vector with copy contains:";
    12. for (int k = 0; k < u2.size(); k++)
    13. cout << u2[k] << " ";
    14. copy_n(u1.begin(), 4, u3.begin());
    15. cout << "\n";
    16. cout << "The new vector using copy_n contains:";
    17. for (int m = 0; m < u3.size(); m++)
    18. cout << u3[m] << " ";
    19. return 0;
    20. }

    6 copy_if

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

    1. #include
    2. #include
    3. #include
    4. #include // accumulate
    5. #include
    6. using namespace std;
    7. int main()
    8. {
    9. std::vector<bool> flags{ true, true, false, true };
    10. std::vector<double> veca{ 0.1, 0.2, 0.3, -0.1 };
    11. std::vector<double> vecb;
    12. vecb.reserve(std::accumulate(flags.begin(), flags.end(), 0));
    13. size_t i = 0;
    14. // vecb在reserve之后并没有未元素分配内存,插入应该使用back_inserter(vecb)
    15. // vecb在resize之后为元素分配了内存,使用back_inserter(vecb)会在已经分配内存的元素之后插入
    16. // 这时应该使用 vecb.begin(),对已经分配的内存进行覆盖
    17. std::copy_if(veca.begin(), veca.end(), std::back_inserter(vecb),
    18. [&i, &flags](double a) {return flags[i++]; });
    19. for (auto& s : vecb)
    20. std::cout << s << std::endl;
    21. return 0;
    22. }

    1. #include
    2. #include
    3. #include
    4. #include // accumulate
    5. #include
    6. using namespace std;
    7. int main()
    8. {
    9. std::vector<bool> flags{ true, true, false, true };
    10. std::vector<double> veca{ 0.1, 0.2, 0.3, -0.1 };
    11. std::vector<double> vecb;
    12. vecb.reserve(std::accumulate(flags.begin(), flags.end(), 0));
    13. size_t i = 0;
    14. i = 0;
    15. std::vector<double> vecc;
    16. std::remove_copy_if(veca.begin(), veca.end(), std::back_inserter(vecc),
    17. [&i, &flags](double a){return flags[i++]; });
    18. std::cout << "veca\n";
    19. for (auto& s : veca)
    20. std::cout << s << "\t";
    21. std::cout << "\nvecc\n";
    22. for (auto& s : vecc)
    23. std::cout << s << "\t";
    24. return 0;
    25. }

     

    7 copy_backward

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

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. void main()
    6. {
    7. //创建两个容器 和 两个数组
    8. vector<int> v = { 1,2,3,4,5,6,7,8,9,10 };
    9. vector<int> v2(10);
    10. vector<int>::iterator vi;//迭代器
    11. int arr[10] = { 11,12,13,14,15,16,17,18,19,20 };
    12. cout << "执行copy算法前:\n";
    13. // 输出 v
    14. cout << "容器 v: ";
    15. for (vi = v.begin(); vi < v.end(); vi++) { cout << *vi << "\t"; }
    16. cout << endl;
    17. // 输出 v2
    18. cout << "容器 v2: ";
    19. for (vi = v2.begin(); vi < v2.end(); vi++) { cout << *vi << "\t"; }
    20. cout << endl;
    21. // 输出 arr
    22. cout << "数组 arr: ";
    23. for (int i = 0; i < 10; i++) { cout << arr[i] << "\t"; }
    24. cout << endl;
    25. cout << "\n执行 copy_backward 算法后:\n";
    26. // STL copy_backward算法
    27. // 1、拷贝源是容器,拷贝目标是容器
    28. copy_backward(v.begin(), v.begin() + 5, v2.end());
    29. // 输出 v2
    30. cout << "容器 v2: ";
    31. for (vi = v2.begin(); vi < v2.end(); vi++) { cout << *vi << "\t"; }
    32. cout << endl << endl;
    33. // 2、拷贝源是数组,拷贝目标是容器
    34. copy_backward(arr, arr + 5, v2.end() - 1);
    35. // 输出 v2
    36. cout << "容器 v2: ";
    37. for (vi = v2.begin(); vi < v2.end(); vi++) { cout << *vi << "\t"; }
    38. cout << endl << endl;
    39. // 3、拷贝源是容器,拷贝目标是同一个容器
    40. copy_backward(v.begin(), v.begin() + 7, v.end());
    41. // 输出 v2
    42. cout << "容器 v : ";
    43. for (vi = v.begin(); vi < v.end(); vi++) { cout << *vi << "\t"; }
    44. cout << endl;
    45. }

  • 相关阅读:
    03-node基础
    【毕业设计】基于java的健康食谱推荐小程序源码
    「iOS」暑假第一周 —— ZARA的仿写
    响应10毫米内的请求如何处理
    自动编码器简单理解及简单使用描述
    springboot源码理解四、自动配置(项目根目录下的bean)
    CSPM值得考吗?一篇文章说透!(附报名流程)
    java计算机毕业设计物业综合信息管理系统MyBatis+系统+LW文档+源码+调试部署
    如何使用API数据接口给自己创造收益
    计算机毕业设计Java居民个人健康信息与个人健康服务综合平台(源码+mysql数据库+系统+lw文档)
  • 原文地址:https://blog.csdn.net/qq_37529913/article/details/125419341