- C++
关于memset的小提示
- 2025-8-13 22:51:21 @
前言:本讨论是作者由于在给数组赋初值时过大而返回Nan(非数,数过大或过小返回的内容),故写下此讨论以示后人
一 memset是什么?
memset是 C 标准库中的内存操作函数,其头文件为cstring。memset用于将一段内存区域设置为指定的值,简单来说就是批量赋值。其定义如下:
void memset(void dest, int ch, size_t count);**
dest: 指向目标内存块的指针
ch: 要设置的字节值(0-255 范围)
count: 要填充的字节数
返回值: 返回 dest指针
要注意的是,count通常为sizeof(dest)
举个例子:
int a = 10086;
memset(a, 0, sizeof(a));
cout << a << endl;
// 输出:
// 0
int b[11] = {1,1,1,1,1,1,1,1,1,1};
memset(b, 0, sizeof(b));
for (int i = 0; i < 11; i ++)
{
cout << b[i] << ' ';
}
// 输出
// 0 0 0 0 0 0 0 0 0 0
二 注意事项
1 值截断问题
memset的第二个参数虽然是 int 类型,由于menset是按字节赋值,所以实际会被截断为 unsigned char(0-255 范围),举个例子:
int c[11] = {1,1,1,1,1,1,1,1,1,1};
memset(c, 114514, sizeof(c));
for (int i = 0; i < 11; i ++)
{
cout << c[i] << ' ';
}
//输出:
//1381126738 1381126738 1381126738 1381126738 1381126738 1381126738 1381126738 1381126738 1381126738 1381126738 1381126738
为什么会这样呢?(如果不想了解请跳转至加租部分) 首先,memset实际处理的是字节,而不是整型元素,所以它要先考虑将整型转成字节,如下:
114514 & 0xFF = 114514 % 256 = 82 = 0x52(十六进制)
所以对于每个c数组中的元素,初始状态如下:
[01 00 00 00] [01 00 00 00] // 都为1
更改后变成:
[52 52 52 52] [52 52 52 52]
最后输出是为十进制数,故而进行转换:
0x52525252 (十六进制) = 5×16⁷ + 2×16⁶ + ... (展开公式) = 1381126738 (十进制)
最后得到了1381126738这个数。
所以,在使用memset时,ch部分最好为1,0或-1,其他可能会出意想不到问题!!!
2 关于浮点数
可以发现,ch的类型为int,所以当dest为浮点数时,会出现很大的问题。举个例子:
double d = 1.5;
memset(d, 1, sizeof(d));
cout << d << endl;
// 输出
// nan
输出的是nan,非数,当数过大或过小或不符合规定时返回的内容。
对于一般的,将一个整型赋给浮点型会有隐式转换做保证,但当直接修改字节内容时就会出错,这本质上是整型和浮点型字节上存储的方式不同!
三 其他的
memset有些时候和for循环赋值是一样的(时间复杂度为O(n),结果也一致),有时甚至不如,但简洁就是力量,有时后适当的,合法的使用memset会使代码更优雅,更美观,这或许就是算法的意义吧
1 条评论
-
Luftmensch_zcx 404 Not Found LV 6 @ 2025-8-13 22:52:50
太腻害啦!!!
🤣 1
- 1