84215045
?int grid[110];
int main()
{
memset(grid, 5, 100 * sizeof(int));
printf("%d", grid[0]);
return 0;
}
84215045
?int grid[110];
int main()
{
memset(grid, 5, 100 * sizeof(int));
printf("%d", grid[0]);
return 0;
}
memset
函数将目标缓冲区的每个字节设置为指定的值。在你的系统上,一个int
占四个字节,每个字节在调用memset
后都被设置为5。因此,grid[0]
的值为0x05050505
(十六进制),对应的十进制是84215045
。
一些平台提供了替代的API来向目标缓冲区写入更宽的模式;例如,在OS X或iOS上,你可以使用:
int pattern = 5;
memset_pattern4(grid, &pattern, sizeof grid);
想要得到您期望的行为,您是针对哪个平台进行开发?
在 C++ 中,您只需使用std::fill_n
:
std::fill_n(grid, 100, 5);
std::fill
即可。 - Stephen Canonint
和uintptr_t
是相同的(第一个示例假设int
是四个字节,但在memset_pattern4
API可用的情况下,这是一个有效的假设)。 - Stephen Canonmemset(grid, 5, 100 * sizeof(int));
你正在设置从(char*)grid
开始,长度为400字节,结束于(char*)grid + (100 * sizeof(int))
的值为5
的内存块(这里需要进行强制类型转换,因为memset
处理的是字节,而指针运算处理的是对象
)。
十六进制中的84215045
等同于0x05050505
;由于int
在你的平台/编译器等上被表示为四个字节,所以当你打印它时,会输出"四个五"。
&grid [0]
开始,是吗? - johnsywebmemset
是用于设置字节而非值的。在 C++ 中设置数组值的众多方法之一是 std::fill_n
:
std::fill_n(grid, 100, 5);
std::fill_n
都转换成优化的代码序列,使用宽对齐存储(可能是向量),或者调用已知在目标平台上快速的库函数。 - Stephen Canonfor(int i=0; i<110; ++i)
grid[i] = 5;
memset
更容易做到正确无误,因为您可以简单地使用sizeof array
。这样,如果将来更改数组的大小,则初始化会自动保持同步。 - Stephen Canonstd::fill
。 - Stephen Canon对于 memset
函数来说,它会以所选值填充字节。因此,一个 int 类型的变量看起来可能像这样:
00000101 00000101 00000101 00000101
这将被解释为84215045。
您并没有明确说明您的程序想要做什么。
假设您想将grid
的前100个元素设置为5(忽略100
与110
之间的差异),只需执行以下操作:
for (int i = 0; i < 100; i ++) {
grid[i] = 5;
}
memset()
很可能已经被优化过了,因此比简单循环更快。另一方面,优化很可能包括一次写入多个字节,而这正是这个循环所做的。另一方面,memset()
本身就是一个循环;明确编写循环而不是将其隐藏在函数调用中并没有改变这一点。最后,即使循环很慢,也不太可能有影响;专注于编写清晰的代码,并在实际测量表明存在显著性能问题时考虑进行优化。grid
的时间多得多。memset()
没有达到你想要的效果,那么它的速度再快也无济于事。(完全不设置 grid
更快!)man memset
,它会告诉您:简单的英文解释是,它用值
void * memset(void *b, int c, size_t len)
c
填充长度为len
的字节字符串b
。memset(grid, 5, 100 * sizeof(int));
sizeof(int)==4
,因此上述代码段看起来像这样:for (int i=0; i<100; i++)
grid[i]=0x05050505;
或者
char *grid2 = (char*)grid;
for (int i=0; i<100*sizeof(int); i++)
grid2[i]=0x05;
它将打印出84215045
但在大多数C代码中,我们希望将一块内存块初始化为零值。
char
类型--> \0
或NUL
int
类型-->0
float
类型-->0.0f
double
类型-->0.0
nullptr
而且,无论是gcc还是clang等现代编译器都可以自动地为您处理这些。
// variadic length array (VLA) introduced in C99
int len = 20;
char carr[len];
int iarr[len];
float farr[len];
double darr[len];
memset(carr, 0, sizeof(char)*len);
memset(iarr, 0, sizeof(int)*len);
memset(farr, 0, sizeof(float)*len);
memset(darr, 0, sizeof(double)*len);
for (int i=0; i<len; i++)
{
printf("%2d: %c\n", i, carr[i]);
printf("%2d: %i\n", i, iarr[i]);
printf("%2d: %f\n", i, farr[i]);
printf("%2d: %lf\n", i, darr[i]);
}
由于memset写入字节,我通常将其用于将int数组设置为零,例如:
int a[100];
memset(a,0,sizeof(a));
或者您可以使用它来设置一个字符数组,因为一个字符恰好是一个字节:
char a[100];
memset(a,'*',sizeof(a));
memset(a,-1,sizeof(a));
这段代码已经过测试。以下是一种将“整数”数组的所有元素设置为0到255之间某个值的方法。
MinColCost=new unsigned char[(Len+1) * sizeof(int)];
memset(MinColCost,0x5,(Len+1)*sizeof(int));
memset(MinColCost,0xff,(Len+1)*sizeof(int));