牛骨文教育服务平台(让学习变的简单)
博文笔记

memset初始化详解

创建时间:2018-04-06 投稿人: 浏览次数:250

参考文档

Function
void * memset ( void * ptr, int value, size_t num );
Fill block of memory
Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).


Parameters
ptr
Pointer to the block of memory to fill.
value
Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.
num
Number of bytes to be set to the value.
size_t is an unsigned integral type.

参数含义

参数名称 参数含义
ptr 内存块的地址(起始位置)
value 要填充的内容
num 要填充的内存块的大小

初始化char类型数组

memset采用的填充方式为按位(byte)填充

因此,在初始化char类型数组时,可以使用任何字符对数组进行初始化

#include <cstring>
#define CHAR * // $ # ^ ) - / , o q, a, e, f... 
···
int main() {
    char c[1000];
    memset(c, CHAR, sizeof(c));
    return 0;
}

初始化int类型数组

特殊情况

如果在对int型数组进行初始化时,我们仍可以进行一些特殊的初始化
如:

  1. 初始化数组元素都为0
  2. 初始化数组元素都为-1

原因:
由于int类型占4byte,即32bit
0的二进制形式表示为0000 0000 0000 0000 0000 0000 0000 0000
-1的二进制形式表示为1111 1111 1111 1111 1111 1111 1111 1111
在使用memset时,将用value的最低位的1byte(8bit)来填充内存块,即用1111 1111来填充。所以数组中每个元素的二进制表示形式还是1111 1111 1111 1111 1111 1111 1111 1111。0的情况同理。

#include <cstring>
···
int main() {
    int a[1000];
    memset(a, 0, sizeof(a));
    return 0;
}
初始化为1
使用memset

1的二进制形式为0000 0000 0000 0000 0000 0000 0000 0001
在使用memset时,将用最低位的1bye(8bit)来填充内存块,即用0000 0001来填充。所以数组中每个元素的二进制形式就表示位0000 0001 0000 0001 0000 0001 0000 0001。十进制形式位16843009。

使用fill

当然你可以使用void fill (ForwardIterator first, ForwardIterator last, const T& val); 函数来实现对数组进行初始化位1的操作。

#include <cstring>
···
int main() {
    int a[1000];
    fill(a, a+1000, 1);
    return 0;
}

更多的应用

//#include <climits>     INT_MAX的头文件
//#define INF 999999999  写法1
//#define INF INT_MAX    写法2
//#define INF 0x3f3f3f3f 写法3

在算法竞赛中,我们经常使用写法1,原因是,如果我们对INT_MAX进行加法运算,会导致溢出,并且运算时会转换为无符号数,再次存放到int时,会再转换为有符号数,这时会将无符号数的最高位,但是超过了有符号数的最高位的数字全部丢掉,导致结果出错,但是不会报错,导致无形bug闪亮登场。

如果使用999999999虽然没有INT_MAX大,如果比题目中给定的数据范围大,那么就可以使用,并且999999999+999999999=1999999998仍然在INT_MAX范围之内。避免了bug的出现。

例如,在Dijkstra算法中,初始化结点之间的路为INF,当然直接用fill函数是也可以的。那么能不能使用memset()函数呢。答案是肯定的。只要采用写法3,就可以直接使用memset函数进行初始化。

原因:
这里的0x3f3f3f3f为16进制的写法,0x为前缀。3f3f3f3f3f每一个字母表示4bit,两个字母表示8bit即1byte。如果使用memset函数,则使用3f对内存块进行填充,那么每个元素得到的就是0x3f3f3f3f

附:

  1. byte 字节; bit 比特(位);
  2. 1byte = 8bit
  3. 二进制代码中,如0011(十进制中的3)每一数字占用1bit,一共占用4bit,0.5byte
  4. char类型占用1bye
  5. int类型占用4byte
  6. INT_NAX = 2147483647 大约为10^9.331930
  7. 999999999 为 10^9-1
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。