我确实在msdn和cplusplus.com上读过memset的用法,我知道(如果我错了,请纠正我):
int p =3;
// p = object value
// &p = memory address where p is stored那么有什么不同呢:
char szMain[512];
memset( szMain, 0x61, sizeof( szMain ) );
cout << szMain[4];和:
char szMain[512];
memset( &szMain, 0x61, sizeof( szMain ) );
cout << szMain[4];(0x61 = a,ASCII表十六进制)
为什么两者都有相同的行为?如果这不是一个建设性的问题,请原谅我。我在c++上是个新手,我似乎无法理解。
发布于 2012-06-26 07:25:35
szMain是数组的标识符。在大多数上下文中,数组标识符会衰减为指向数组中第一个元素的指针,换句话说就是&szMain[0]。
因此,在您的第一个示例中,您将数组的第一个元素的地址传递给memset。在第二个示例中,您将数组本身的地址传递给它。然而,这两个地址是完全相同的。
发布于 2012-06-26 07:30:47
所发生的事情在标准中被描述为数组到指针的转换。
4.2数组到指针转换conv.array
“T的数组”或“T的未知界数组”类型的左值或右值可以转换为“指向T的指针”类型的右值。结果是指向数组第一个元素的指针。
上面的代码表明,在您第一次调用memset时,szMain被转换为一个指针(更具体地说,是一个指向char的指针),该指针存储了数组中第一个元素的地址。
在第二个调用中,&szMain将产生一个char (*)[512]类型的指针,即。指向与szMain具有相同类型的数组的指针,存储数组本身的地址。
这两个表达式都将产生相同的值,因为(szMain[0]),的起始地址与szMain的第一个元素的地址相同,但请注意,它们的类型不同。
memset接受void*作为第一个参数,因此可以隐式使用任何指针类型来调用该函数。
发布于 2012-06-26 07:37:35
是的,在这种情况下,两者具有相同的行为,但不一定总是这样。
大多数数组名称的使用给出了数组的第一个元素的地址。对于T数组,指针的类型将是T *。
如果显式获取数组的地址,则会得到相同的地址,但类型不同(“指向类型为T的N个对象的数组的指针”,而不是“指向T的指针”)。
在这种情况下,您传递的地址被转换为void *,因此类型上的差异立即被丢弃--但是如果您在另一个上下文中使用它们,而不是立即丢弃类型上的差异,那么它们不一定具有相同的效果。例如,如果您想保留数组的第一个元素未初始化,您可能会这样做:
memset(szMain+1, 'a', sizeof(szMain));由于类型(在本例中)是“指向char的指针”,它将根据需要从数组中的第二个char开始。但是,如果你这样做了:
memset(&szMain+1, 'a', sizeof(szMain));它不是添加1,而是添加一个数组的大小,因此您将在数组末尾传递地址,而不是第二个元素的地址。
顺便说一句:如果你想要'a',我建议直接使用它,而不是像你在问题中所做的那样用十六进制编码。至少,它的可读性要好得多。理论上它也更便于移植,尽管很少有人真正关心十六进制值无法正常工作的机器(主要是IBM大型机)。
https://stackoverflow.com/questions/11198776
复制相似问题