void *memset(void *s,int c,size_t n);

时间:2023-01-12 16:10:28
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char p[4]={0xff,0xff,0xff,0xff};
char *q=new char[4];
memset(&q,0,4);
cout<< hex << (int)q << endl;
/*
这个输出是:0;
原型:void *memset(void *s,int c,size_t n);  
memset(q,0,4);这么写不是更合理?q是指针丫丫!
修改后输出这样子的:817a008(还是随机的)
*/
memmove(&q,p,4);
cout<< hex << (int)q << endl;
/*
这个输出是:ffffffff;
原型:void *memmove(void *dest,const void *src,size_t count);  
memmove(q,p,4);这么写不是也更合理?
修改后输出这样子的:817a008(还是随机的)<与上一个结果相同>
这里想问下:q不是指针么?不是与函数原型符合么?怎么还要取地址呢?
*/
return 0;
}

14 个解决方案

#1


 memset(q,0,4);

#2


memmove(q,p,4);

#3


&q是取char *q;这个指针变量的地址,&p因为p是数组,所以还是p[0]的地址,你&&&&&&&一百遍还是第一个元素的地址。

编译器足够聪明帮你解决对数组名&这种毫无意义的做法,但编译器足够公正的告诉你数组就是数组,指针就是指针,你的C语言还没有过关。

#4


memset(&q,0,4); 这样子写是错的& 你覆盖的是指针的地址,而不是指针所指向的地址,已经脏写内存了。
memset(q,0,4);

memmove(&q,p,4) 再次脏写内存
应该是memmove(q,p,4) 

#5


不对吧!
我写这程序的本意是想往内存里面填充42个1,当然要先初始化为42个0。(不要挑剔啦,本来的本来是想填充100000.....这样的数据的。)
源程序的话(memset(&q,0,4);memmove(&q,p,4);)输出是符合我要求的,但是我就是不理解,因为我觉得q是指针了,再取指针的地址不好理解。
可以让我理解接受的是(memset(q,0,4);memmove(q,p,4);),但是得出的输出结果是随机的。
这就是矛盾所在了!

#6


难道此贴就注定这么飘过??问题是问题还没有得到解决呢!!

#7


问题出在输出语句上,应该写为

    char *q=new char[4];
    memset(q,0,4);
    cout<< hex <<*(int*)q << endl;


因为q保存的是char[4]地址,需要解引用才能得到值

如果直接解引用,就是q[0]这个字符

要按整型解引用,就得先把地址转为int*

你用&q去memset,然后又输出q,其实相当于你自己实现了一层指针

#8


楼主,你输出的这个817a008是一个地址,如果你要输出数组里的元素,就不应该是cout<<(int) q << endl;
而应该是,因为你是要输出整形,而不是字符串。

for(int i=0;i<4;i++)
{
cout<<(int) q[i] << endl;
}

而你是用memset(&q,0,4);而不是memset(q,0,4);所以相当于将q这个指针本身的值改变成0,而不是改变指针指向的值,所以你用cout<<(int) q << endl显示出来q本身的值,就是0。
看你的程序应该是要修改指针指向的值,也就是数组里的元素,那么你可以试试:

/* memset example */
#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
    char p[4]={0xff,0xff,0xff,0xff};
    char *q=new char[4];
    memset(q,0,4);
cout<<(int) q << endl; //显示q这个指针本身的值
for(int i=0;i<4;i++)//以16进制整数形式显示q指向的值
{
cout<<(int) q[i] << endl;
}

memmove(q,p,4);
    cout<< hex << (int)q << endl;//显示q这个指针本身的值
for(int i=0;i<4;i++)//以16进制整数形式显示q指向的值
{
cout<<(int) q[i] << endl;
}

system("pause");
return 0;
}

#9


引用 3 楼 qq120848369 的回复:
&amp;q是取char *q;这个指针变量的地址,&amp;p因为p是数组,所以还是p[0]的地址,你&amp;&amp;&amp;&amp;&amp;&amp;&amp;一百遍还是第一个元素的地址。

编译器足够聪明帮你解决对数组名&amp;这种毫无意义的做法,但编译器足够公正的告诉你数组就是数组,指针就是指针,你的C语言还没有过关。

++++

#10


引用 9 楼 luciferisnotsatan 的回复:
引用 3 楼 qq120848369 的回复:

&amp;amp;q是取char *q;这个指针变量的地址,&amp;amp;p因为p是数组,所以还是p[0]的地址,你&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;一百遍还是第一个元素的地址。

编译器足够聪明帮你解决对数组名&amp;amp;这种毫无意义的……
狂冒汗!指责得对,不过还是没能给解决问题!前面那个我知道,就是忽略了输出的样式!罪过罪过!

#11


#include <iostream> 
#include <cstring> 
using namespace std; 
int main(){
char a[]="ffff";
cout << sizeof(a) << ";" << a << endl;//退化为数组头指针地址
char b[]={'a','b','c','d'};
cout << sizeof(b) << ";" << b << endl;//这个b跟后面那个d要怎么归类呢?
char *c=a;
cout << c << endl;
int d[]={15,24,32,54};
cout << sizeof(d) << ";" << d << endl;//这个d跟后面那个b要怎么归类呢?
cout << *d << endl;
return 0;
 }

#12


引用 10 楼 huang793807836 的回复:
狂冒汗!指责得对,不过还是没能给解决问题!前面那个我知道,就是忽略了输出的样式!罪过罪过!


呵呵,这里q和&q完全不同,#3楼文不对题,你们还又是顶又是指责得对

对此我狂汗……

#13


VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。

#14


/*
说实在的,我确实c学得不好,觉得这东西不可能一蹴而就,是慢慢熬出来的,所以我现在在慢慢熬,当我能写出像《unix环境高级编程》《C++编程思想》等那样的杰作来我就敢说我学得很好无敌了。
我嘛觉得技术这活,学了没用、用不上,就等于白学。成熟总在反复磨练中嘛!
不过3楼应该是版主的样子,我看他很多回复的,任务可能重了点,所以没时间看仔细,是有点文不对题之嫌,理解理解!
作为曾经在学校茫茫然混过日子的同学们,我不敢怎么反驳啦,努力还看现在,大家过来人,理解了过去,看到了未来,知道现在要什么了,静静地思过就行。
目光再长远点的、有忧国忧民意识的、对祖国下一代关切的,去多指点一下迷途的学生吧,而不要去指责,他们不该是一文不值的一代和自卑的一代,个人微薄之力,能做点总比不做好。
至今有记老师的那些话:你们很好的,就是懒了点,你们是很聪明的,要是你们肯努力专心用功点,你们还是很优秀的......(老师几乎每节课都这么说的,用意很让我感动,是负责任的好老师,中国的大学环境这样,能改变什么呢?不过还是要赞一下老师的为人的!!!)
不同意的不要喷哈!
*/

#1


 memset(q,0,4);

#2


memmove(q,p,4);

#3


&q是取char *q;这个指针变量的地址,&p因为p是数组,所以还是p[0]的地址,你&&&&&&&一百遍还是第一个元素的地址。

编译器足够聪明帮你解决对数组名&这种毫无意义的做法,但编译器足够公正的告诉你数组就是数组,指针就是指针,你的C语言还没有过关。

#4


memset(&q,0,4); 这样子写是错的& 你覆盖的是指针的地址,而不是指针所指向的地址,已经脏写内存了。
memset(q,0,4);

memmove(&q,p,4) 再次脏写内存
应该是memmove(q,p,4) 

#5


不对吧!
我写这程序的本意是想往内存里面填充42个1,当然要先初始化为42个0。(不要挑剔啦,本来的本来是想填充100000.....这样的数据的。)
源程序的话(memset(&q,0,4);memmove(&q,p,4);)输出是符合我要求的,但是我就是不理解,因为我觉得q是指针了,再取指针的地址不好理解。
可以让我理解接受的是(memset(q,0,4);memmove(q,p,4);),但是得出的输出结果是随机的。
这就是矛盾所在了!

#6


难道此贴就注定这么飘过??问题是问题还没有得到解决呢!!

#7


问题出在输出语句上,应该写为

    char *q=new char[4];
    memset(q,0,4);
    cout<< hex <<*(int*)q << endl;


因为q保存的是char[4]地址,需要解引用才能得到值

如果直接解引用,就是q[0]这个字符

要按整型解引用,就得先把地址转为int*

你用&q去memset,然后又输出q,其实相当于你自己实现了一层指针

#8


楼主,你输出的这个817a008是一个地址,如果你要输出数组里的元素,就不应该是cout<<(int) q << endl;
而应该是,因为你是要输出整形,而不是字符串。

for(int i=0;i<4;i++)
{
cout<<(int) q[i] << endl;
}

而你是用memset(&q,0,4);而不是memset(q,0,4);所以相当于将q这个指针本身的值改变成0,而不是改变指针指向的值,所以你用cout<<(int) q << endl显示出来q本身的值,就是0。
看你的程序应该是要修改指针指向的值,也就是数组里的元素,那么你可以试试:

/* memset example */
#include <iostream>
#include <cstring>
using namespace std;

int main ()
{
    char p[4]={0xff,0xff,0xff,0xff};
    char *q=new char[4];
    memset(q,0,4);
cout<<(int) q << endl; //显示q这个指针本身的值
for(int i=0;i<4;i++)//以16进制整数形式显示q指向的值
{
cout<<(int) q[i] << endl;
}

memmove(q,p,4);
    cout<< hex << (int)q << endl;//显示q这个指针本身的值
for(int i=0;i<4;i++)//以16进制整数形式显示q指向的值
{
cout<<(int) q[i] << endl;
}

system("pause");
return 0;
}

#9


引用 3 楼 qq120848369 的回复:
&amp;q是取char *q;这个指针变量的地址,&amp;p因为p是数组,所以还是p[0]的地址,你&amp;&amp;&amp;&amp;&amp;&amp;&amp;一百遍还是第一个元素的地址。

编译器足够聪明帮你解决对数组名&amp;这种毫无意义的做法,但编译器足够公正的告诉你数组就是数组,指针就是指针,你的C语言还没有过关。

++++

#10


引用 9 楼 luciferisnotsatan 的回复:
引用 3 楼 qq120848369 的回复:

&amp;amp;q是取char *q;这个指针变量的地址,&amp;amp;p因为p是数组,所以还是p[0]的地址,你&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;&amp;amp;一百遍还是第一个元素的地址。

编译器足够聪明帮你解决对数组名&amp;amp;这种毫无意义的……
狂冒汗!指责得对,不过还是没能给解决问题!前面那个我知道,就是忽略了输出的样式!罪过罪过!

#11


#include <iostream> 
#include <cstring> 
using namespace std; 
int main(){
char a[]="ffff";
cout << sizeof(a) << ";" << a << endl;//退化为数组头指针地址
char b[]={'a','b','c','d'};
cout << sizeof(b) << ";" << b << endl;//这个b跟后面那个d要怎么归类呢?
char *c=a;
cout << c << endl;
int d[]={15,24,32,54};
cout << sizeof(d) << ";" << d << endl;//这个d跟后面那个b要怎么归类呢?
cout << *d << endl;
return 0;
 }

#12


引用 10 楼 huang793807836 的回复:
狂冒汗!指责得对,不过还是没能给解决问题!前面那个我知道,就是忽略了输出的样式!罪过罪过!


呵呵,这里q和&q完全不同,#3楼文不对题,你们还又是顶又是指责得对

对此我狂汗……

#13


VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。

#14


/*
说实在的,我确实c学得不好,觉得这东西不可能一蹴而就,是慢慢熬出来的,所以我现在在慢慢熬,当我能写出像《unix环境高级编程》《C++编程思想》等那样的杰作来我就敢说我学得很好无敌了。
我嘛觉得技术这活,学了没用、用不上,就等于白学。成熟总在反复磨练中嘛!
不过3楼应该是版主的样子,我看他很多回复的,任务可能重了点,所以没时间看仔细,是有点文不对题之嫌,理解理解!
作为曾经在学校茫茫然混过日子的同学们,我不敢怎么反驳啦,努力还看现在,大家过来人,理解了过去,看到了未来,知道现在要什么了,静静地思过就行。
目光再长远点的、有忧国忧民意识的、对祖国下一代关切的,去多指点一下迷途的学生吧,而不要去指责,他们不该是一文不值的一代和自卑的一代,个人微薄之力,能做点总比不做好。
至今有记老师的那些话:你们很好的,就是懒了点,你们是很聪明的,要是你们肯努力专心用功点,你们还是很优秀的......(老师几乎每节课都这么说的,用意很让我感动,是负责任的好老师,中国的大学环境这样,能改变什么呢?不过还是要赞一下老师的为人的!!!)
不同意的不要喷哈!
*/