让人费解的指针??????????

hua_zhixing_ 2009-05-14 03:36:21
#include<iostream>
using namespace std;

char *strCpy(char *strDest,const char *strSrc){
while((*strDest++=*strSrc++)!='\0');//把*strDest++=*strSrc++单独写
return strDest; //一句为什么报错?无法从“const char *”转换为“char *”
} //strDest不是后移的吗,怎么依然返回的是首地址?

int main(){
char *ch="abcdefghij",*strdest;
strdest=(char*)malloc(sizeof(ch));
strCpy(strdest,ch);
cout<<"The source string: "<<ch<<endl
<<"After copy: "<<strdest<<endl;
return 0;
}

问题在程序中。
...全文
270 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
czbever 2009-05-15
  • 打赏
  • 举报
回复
晕 楼主strlen和sizeof还没搞清楚啊
chenxu_ustc 2009-05-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 crst_zh 的回复:]
strdest=(char*)malloc(sizeof(ch));//这个不对吧?
改成:
strdest=(char*)malloc(strlen(ch)+1);

char *strCpy(char *strDest,const char *strSrc){
        char *p=strDest;     
        while((*p++=*strSrc++)!='\0');
        return strDest;                   
}   



[/Quote]
正解 ,楼主,不管你的程序是否正确, 你的编程风格实在太有问题了 ,建一看下the c++ programming style
ShardowM 2009-05-15
  • 打赏
  • 举报
回复
一楼正解
在strCpy中return strDest;的话返回的是执行字符串末尾'\0'的指针
所以这里应该写成return p;

另外在main中strdest的指向并没有改变,调用strCpy是传入的是它的一个
拷贝


其实指针本身也看做一个变量,只是改变量的值是一个内存地址,而这个地址
就是指针指向的对象的地址
alexhilton 2009-05-15
  • 打赏
  • 举报
回复
ch is a pointer, so sizeof( ch ) is 4. use strlen instead
petermjx130684 2009-05-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 bushizhuge 的回复:]
//把*strDest++=*strSrc++单独写一句为什么报错?无法从“const char *”转换为“char *”
单独写也不会报错,出现无法从“const char *”转换为“char *”除非你写成了srtDest=strSrc;还差不多//strDest不是后移的吗,怎么依然返回的是首地址?
显然不是返回的首地址,你是怎么看出来返回首地址的?你根本就没有使用这个函数的返回值
[/Quote]

8楼正解
wangxipu 2009-05-15
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 liooi 的回复:]
程序是有点小问题 写的风格不怎么好
[/Quote]0
liooi 2009-05-15
  • 打赏
  • 举报
回复
程序是有点小问题 写的风格不怎么好
中才德创 2009-05-14
  • 打赏
  • 举报
回复
一:把*strDest++=*strSrc++单独写一句为什么报错?无法从“const char *”转换为“char *”
答:并不报错.在while中不报,在外更不会报错,当然分号是要加的.写成"*strDest++ = *strSrc++;"

二:strDest不是后移的吗,怎么依然返回的是首地址?
答:是后移了,而且返回的也不是首地址.
tangshuiling 2009-05-14
  • 打赏
  • 举报
回复

c/c++两个大的问题,一是指针,二是型别
如果这两样都没弄明白等于还没入门
crst_zh 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tugouxp 的回复:]
//strDest不是后移的吗,怎么依然返回的是首地址?
strDest的值本身没有变化,*strDest++=*strSrc++ 可以看成*(strDest++)=*(strSrc++),可以看到只是将strDest自增,并没有重新赋值给自身,你可能将+=和=混淆了,如果写成 strDest+=1,就改变了strDest,这里的strDest没有发生变化,是地址,可以返回。
你的程序可以运行,我在VC6下运行没有问题
另外支持一楼的观点,必须+1
[/Quote]

VC6下运行没问题仅仅是因为返回的字符串指针没有用到,返回指针也是为了实现链式表达。
如果这样使用
char *p=new char[100];
char s[]="1123456";

char *q;
q=strcpy(p,s);
按理q==p,但是不先保存p而返回strDest的话就不对
papaofdoudou 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 small21 的回复:]
申请空间不对,sizeof(指针)得到的是指针的大小。应该是4字节。。

程序想返回的是赋值后字符串的尾地址吧。。。。。然后判断是否赋值成功什么的。首地址的话在主函数里还是没变,不用返回啥。
[/Quote]
返回可以构成链式表达,建议返回,不过返回前应该先保存首地址,改变后在将首地址赋值给返回变量
慧眼识狗熊 2009-05-14
  • 打赏
  • 举报
回复
申请空间不对,sizeof(指针)得到的是指针的大小。应该是4字节。。

程序想返回的是赋值后字符串的尾地址吧。。。。。然后判断是否赋值成功什么的。首地址的话在主函数里还是没变,不用返回啥。
papaofdoudou 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tugouxp 的回复:]
strDest的值本身没有变化,*strDest++=*strSrc++ 可以看成*(strDest++)=*(strSrc++),可以看到只是将strDest自增,并没有重新赋值给自身,你可能将+=和=混淆了,如果写成 strDest+=1,就改变了strDest,这里的strDest没有发生变化,是地址,可以返回。
你的程序可以运行,我在VC6下运行没有问题
另外支持一楼的观点,必须+1
[/Quote]
更正一下,刚才没睡醒,return strDest;是不对的,strDest已经改变了,指向末尾的元素了。至于你输出为什么没有出错是因为调用的时候你是这样 strCpy(strdest,ch);调用的,并没有返回一个指针赋值给另外一个指针变量。strcpy传递指针值完成拷贝的操作是没有问题的。
你可以做个实验:
#include<iostream>
using namespace std;

char *strCpy(char *strDest,const char *strSrc){
cout<<(int*)strDest<<endl;
while((*strDest++=*strSrc++)!='\0');
cout<<(int*)strDest<<endl;
return strDest;

}

int main()
{
char *ch="abcdefghij",*strdest;
strdest=(char*)malloc(sizeof(ch));
char* c=strCpy(strdest,ch);
cout<<"The source string: "<<ch<<endl
<<"After copy: "<<strdest<<endl;
cout<<c<<endl;
return 0;
}

不知道你从哪本书看到的这类代码,strcpy这样返回肯定是不对的,自增已经改变了strDest的值。
xmanlin 2009-05-14
  • 打赏
  • 举报
回复
我对很多的解析很无语............
findcsdn 2009-05-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 haoshen1987 的帖子:]

char *strCpy(char *strDest,const char *strSrc){
while((*strDest++=*strSrc++)!='\0');
return strDest;
} //strDest不是后移的吗,怎么依然返回的是首地址?

[/Quote]

你的strCpy传进去的是strDest指针的复制品,不是实际指针,虽然函数里假strDest发生变化,但真的strDest指针没有改。


strCpy(strdest,ch);
改成
strDest = strCpy(strdest,ch);

就对了
GaA_Ra 2009-05-14
  • 打赏
  • 举报
回复
也许我想复杂了,如7楼所言-__-
GaA_Ra 2009-05-14
  • 打赏
  • 举报
回复
//strDest不是后移的吗,怎么依然返回的是首地址?
我用vc6 debug编译
从调试来看,应该是编译器做的优化

004011F9 . 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 上面是malloc分配的指针地址,放到EBP-8里面
004011FC . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
004011FF . 50 PUSH EAX
00401200 . 8B4D F8 MOV ECX,DWORD PTR SS:[EBP-8]
00401203 . 51 PUSH ECX
00401204 . E8 A6FEFFFF CALL test.004010AF 这里就是call strCpy,参数是EAX,ECX,他们是栈中的局部变量
00401209 . 83C4 08 ADD ESP,8
0040120C . 68 28104000 PUSH test.00401028
00401211 . 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8] 调用cout的时候,仍旧使用EBP-8,跟上面一样
00401214 . 52 PUSH EDX
00401215 . 68 34204300 PUSH test.00432034 ; After copy:
0040121A . 68 28104000 PUSH test.00401028
0040121F . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00401222 . 50 PUSH EAX
00401223 . 68 1C204300 PUSH test.0043201C ; The source string:
00401228 . 68 28954300 PUSH test.00439528
0040122D . E8 6EFEFFFF CALL test.004010A0

编译器在调用cout时默认就用了EBP-8的指针(strDest),应该是编译器的缘故,所以strCpy里面strDest虽然增加了,但是对cout没影响

不知道我说明白了没有 - -
bushizhuge 2009-05-14
  • 打赏
  • 举报
回复
//把*strDest++=*strSrc++单独写一句为什么报错?无法从“const char *”转换为“char *”
单独写也不会报错,出现无法从“const char *”转换为“char *”除非你写成了srtDest=strSrc;还差不多//strDest不是后移的吗,怎么依然返回的是首地址?
显然不是返回的首地址,你是怎么看出来返回首地址的?你根本就没有使用这个函数的返回值
papaofdoudou 2009-05-14
  • 打赏
  • 举报
回复
//strDest不是后移的吗,怎么依然返回的是首地址?
strDest的值本身没有变化,*strDest++=*strSrc++ 可以看成*(strDest++)=*(strSrc++),可以看到只是将strDest自增,并没有重新赋值给自身,你可能将+=和=混淆了,如果写成 strDest+=1,就改变了strDest,这里的strDest没有发生变化,是地址,可以返回。
你的程序可以运行,我在VC6下运行没有问题
另外支持一楼的观点,必须+1
xzz1008 2009-05-14
  • 打赏
  • 举报
回复
我这里运行正常.....
加载更多回复(5)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧