fill和memset函数详细说!(以及其中的inf=0x3f3f3f3f给int型赋值)【c++】

本文详细介绍了C++中使用fill函数和memset函数进行数组初始化的方法,对比了它们在不同场景下的适用性和效率,特别是如何利用memset高效地将数组初始化为无穷大值。

fill函数:

  • 在头文件< algorithm >中
  • 按照单元赋值,即将一个区间中的元素都赋同一个值
fill(arr, arr + n, 要填入的内容);   //普通数组
fill(v.begin(), v.end(), -1);       //vector
fill(f[0], f[0]+N*N, 要填入的内容);    //二维数组

fill应该是不可以给三维数组赋初值的(测试了一下),你们也可以尝试一下。(在之前写代码的时候想用,发现用不了)

memset函数:

  • 在头文件< cstring >中
  • 按照字节填充某字符

因为memset函数按照字节填充,所以一般memset只能用来填充char型数组,(因为只有char型占一个字节)如果填充int型数组,除了0和-1,其他的不能。因为只有00000000 = 0,-1同理,如果我们把每一位都填充“1”,会导致变成填充入“11111111”。

理论上只能初始化为0和-1,但是!

	memset()函数还能将int型数组初始化为INF(0x3f3f3f3f)

以下内容参考自:https://blog.youkuaiyun.com/Karen_Yu_/article/details/78660591

首先来说说 inf=0x3f3f3f3f:

0x3f3f3f3f的十进制是1061109567,也就是10^9级别的(和0x7fffffff(32-bit int的最大值)一个数量级),而一般场合下的数据都是小于10^9的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。

另一方面,由于一般的数据都不会大于10^9,所以当我们把无穷大加上一个数据时,它并不会溢出(这就满足了“无穷大加一个有穷的数依然是无穷大”),事实上0x3f3f3f3f+0x3f3f3f3f=2122219134,这非常大但却没有超过32-bit int的表示范围,所以0x3f3f3f3f还满足了我们“无穷大加无穷大还是无穷大”的需求。


最大好处:
如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a)),但是当我们想将某个数组全部赋值为无穷大时(例如解决图论问题时邻接矩阵的初始化),就不能使用memset函数了,因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0,现在好了,如果我们将无穷大设为0x3f3f3f3f,那么奇迹就发生了,0x3f3f3f3f的每个字节都是0x3f!

所以要把一段整型数组全部置为无穷大,我们只需要 memset(a,INF,sizeof(a))。


编程中无穷大的设定:(主要介绍优点)
很多人可能设为0x7fffffff,这个数的确是32-bit int的最大值,符号位为0,其他的都是1

但在很多情况下,0x7fffffff会出现错误,比如溢出,这样两个无穷大数相加会变成负数,还有如在做dijkstra求最短路时,当做松弛操作,判断if (d[u]+w[u][v]<d[v]) d[v]=d[u]+w[u][v]时,若u到v没有路劲,w[u][v]=0x7fffffff,这样d[u]+w[u][v]会变成负数,这就产生了错误。

为了尽量避免以上的错误,我们可以改变无穷大的设定,可以将0x3f3f3f3f设为无穷大,0x3f3f3f3f的10进制表示为1061109567,这个数已达到10^9,足以表示无穷大,又0x3f3f3f3f+0x3f3f3f3f=2122219134,满足无穷大+无穷大仍为无穷大

当把无穷大设为0x3f3f3f3f时,在做初始化时也很方便,比如在初始化数组a时,可以使用

Memset(a,0x3f,sizeof(a)),因为0x3f3f3f3f的每个字节都是0x3f,如果使用0x7fffffff,需要循环赋值,耗费更多时间。

#include <cstring>
#define inf 0x3f3f3f3f
//#define memset(a,b) memset(a,b,sizeof(a))
using namespace std;
int main(){
    int a[20];
    memset(a,inf,sizeof(a)); 
    memset(a,0x3f,sizeof(a));
    return 0;
}

以上两种方式都一样(亲测有效)。

在这段代码中,`const long long INF = 0x3f3f3f3f3f3f3f3f;` 是一个全局常量的定义,其主要功能是**定义一个表示“无穷大”(或极大值)的常量 `INF`,用于后续逻辑中的边界判断特殊状态处理**。以下是对其具体作用功能的细分析: --- ### 常量解析 - **类与修饰符:** - `const long long` 表示这是一个不可修改的、长整整数常量,适合存储非常大的数值(可达到约 9e18),足以覆盖本题中可能的乘积与差值范围。 - **十六进制值 `0x3f3f3f3f3f3f3f3f` 的含义:** - 这是一个精心选择的极大值,具有以下优点: 1. **数值足够大但不溢出:** 十进制约为 `4.55e18`,远大于一般运算结果,但在 `long long` 范围内,避免了加法或比较时的溢出问题。 2. **便于调试初始化:** 字节模式 `0x3f` 在内存中重复,易于识别,也常用于初始化数组(如 `memset(dp, 0x3f, sizeof(dp))`)来设置为“无穷大”。 3. **支持加法不轻易溢出:** 若用于动态规划中状态转移(如 `dp[i] = min(dp[i], dp[j] + cost)`),即使加上一些值也不会迅速溢出。 - **在当前代码中的语义作用:** - 它被用作一种“非法选择”的标记返回值。 - 在 `dfs(x, s, b_sum)` 函数中: ```cpp if (s == 1 && b_sum == 0) return INF; ``` 这个条件判断的是:**是否从未选择任何调料**(因为初始调用是 `dfs(1, 1, 0)`,而如果一路都没选,则最终 `s=1`, `b_sum=0`)。 - 题目隐含要求:必须至少选择一种调料(否则没有意义),因此这种“全都不选”的情况应被排除。 - 返回 `INF` 意味着这种情况的成本极高,在后续 `min()` 比较中会被自动淘汰,从而确保答案来自至少选了一种调料的合法组合。 --- ### 总结功能 该行代码的作用是: > **定义一个代表“无穷大”的常量 `INF`,用于标识非法或不可接受的状态(即未选择任何调料),并在最小化搜索中将其排除。** 它保证了即使递归枚举了所有子集(包括空集),最终结果也会正确忽略空集这一无效解,从而得到符合题意的最小绝对差。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值