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

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.csdn.net/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;
}

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

猜你喜欢

转载自blog.csdn.net/sun9979/article/details/84990276