C++中std::fill/std::fill_n的使用

本文详细介绍了C++标准库中的std::fill与std::fill_n函数的使用方法及区别。std::fill用于将指定范围内的元素设置为同一值,而std::fill_n则用于将指定数量的元素初始化为同一值。通过示例代码展示了如何利用这两个函数高效地进行数据初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

There is a critical difference between std::fill and memset that is very important to understand. std::fill sets each element to the specified value. memset sets each byte to a specified value.

While they won't produce incorrect results when used appropriately, the mem* family of functions is obsolete. In particular, std::copy, std::move, std::fill, and std::equal provide type-safe, more general, and equally efficient interfaces to perform the same tasks as std::memcpy, std::memmove, std::memset, std::memcmp, and their wide variants.

The std::fill() and std::fill_n() algorithms are used to initialize or reinitialize a sequence with a fixed value.

std::fill函数的作用是:将一个区间的元素都赋予指定的值,即在[first, last)范围内填充指定值。

std::fill_n函数的作用是:在[fist, fist + count)范围内填充指定值。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "fill.hpp"
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <list>

///
// reference: http://www.cplusplus.com/reference/algorithm/fill/
int test_fill_1()
{
	std::vector<int> myvector(8); // myvector: 0 0 0 0 0 0 0 0

	std::fill(myvector.begin(), myvector.begin() + 4, 5); // myvector: 5 5 5 5 0 0 0 0
	std::fill(myvector.begin() + 3, myvector.end() - 2, 8); // myvector: 5 5 5 8 8 8 0 0

	std::cout << "myvector contains:";
	for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
		std::cout << ' ' << *it;
	std::cout << '\n';

	return 0;
}

int test_fill_2()
{
	float arr[10];

	std::fill(&arr[0], &arr[0] + 10, 1.23);
	for (int i = 0; i < 10; i++)
		fprintf(stderr, "%f  ", arr[i]);
	fprintf(stderr, "\n");

	return 0;
}

/
// reference: http://www.cplusplus.com/reference/algorithm/fill_n/
int test_fill_n_1()
{
	std::vector<int> myvector(8, 10); // myvector: 10 10 10 10 10 10 10 10

	std::fill_n(myvector.begin(), 4, 20); // myvector: 20 20 20 20 10 10 10 10
	std::fill_n(myvector.begin() + 3, 3, 33); // myvector: 20 20 20 33 33 33 10 10

	std::cout << "myvector contains:";
	for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
		std::cout << ' ' << *it;
	std::cout << '\n';

	return 0;
}

GitHubhttp://github.com/fengbingchun/Messy_Test

<think>好的,用户想了解如何用std::copy和std::copy替换memcpy和memset。首先,我需要回顾这两个C++标准库函数的具体用法和优势。 用户可能已经知道memcpy和memset是C语言中的函数,用于内存操作。但在C++中,尤其是处理对象时,直接内存操作可能会有问题,比如浅拷贝或未定义行为。std::copy和std::fill属于<algorithm>头文件,更安全,适用于STL容器和数组。 接下来,比较memcpy和std::copy。memcpy需要计算字节数,容易出错,而std::copy通过迭代器指定范围,类型安全。例如,拷贝int数组时,std::copy(arr1, arr1+5, arr2)比memcpy(arr2, arr1, 5*sizeof(int))更不容易出错,特别是当元素类型改变时,不需要手动计算字节。 然后考虑memset和std::fill。memset按字节设置,适合POD类型,但对非POD或非0值可能有风险。比如,用memset初始化int数组为1会导致每个字节为1,而不是整数1。而std::fill会正确调用赋值操作,确保每个元素被正确设置。 用户可能需要具体例子来理解转换方法。比如,将memcpy替换为std::copy时,源和目标的范围需要明确,使用指针作为迭代器。对于memset到std::fill的转换,需注意填充的范围和值类型。 还要提到异常安全性和泛型编程的优势。std::copy和std::fill在拷贝或填充时,能正确处理异常,而memcpy和memset不会。此外,标准算法适用于任何迭代器,包括容器迭代器,提高代码的通用性。 最后,需要指出何时仍需使用C函数。例如,处理原始内存块或与C API交互时,可能仍需memcpy。但在大多数C++场景中,优先使用标准库算法更安全、可维护。</think>在C++开发中,建议优先使用标准库算法$\texttt{std::copy}$和$\texttt{std::fill}$代替C语言的$\texttt{memcpy}$和$\texttt{memset}$,主要原因如下: ### 一、类型安全优势 $$\begin{cases} \texttt{memcpy} \rightarrow \text{按字节复制,无类型检查} \\ \texttt{std::copy} \rightarrow \text{通过迭代器实现类型安全复制} \\ \texttt{memset} \rightarrow \text{按字节填充,仅适用POD类型} \\ \texttt{std::fill} \rightarrow \text{通过值语义进行安全填充} \end{cases}$$ ### 二、具体转换示例 #### 1. 替换$\texttt{memcpy}$ ```cpp // C风格 int src[5] = {1,2,3,4,5}; int dest[5]; memcpy(dest, src, 5 * sizeof(int)); // C++风格 std::copy(std::begin(src), std::end(src), std::begin(dest)); ``` #### 2. 替换$\texttt{memset}$ ```cpp // C风格(仅适用于基础类型) char buffer[1024]; memset(buffer, 0, sizeof(buffer)); // C++风格(支持任意可赋值类型) std::fill(std::begin(buffer), std::end(buffer), '\0'); ``` ### 三、核心优势对比 $$ \begin{array}{|l|c|c|} \hline \text{特性} & \text{C函数} & \text{C++算法} \\ \hline 类型安全 & × & √ \\ 支持非POD类型 & × & √ \\ 异常安全 & × & √ \\ 泛型编程支持 & × & √ \\ 容器兼容性 & × & √ \\ \hline \end{array} $$ ### 四、注意事项 1. 对于连续内存块(如数组),使用$\texttt{std::copy}$性能与$\texttt{memcpy}$相当 2. 处理复杂对象时,$\texttt{std::copy}$会调用拷贝构造函数 3. 使用前需包含头文件:$<\texttt{algorithm}>$ ### 五、仍需使用C函数的场景 1. 与C语言API交互时 2. 处理未初始化的原始内存块(配合$\texttt{std::mem\_t}$) 3. 需要极致的底层性能优化时(需通过profile验证) 建议优先使用标准库算法,可使代码更安全、更易维护,同时保持与STL容器良好的兼容性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值