哪个大佬给我解释一下这个代码

卡夫� 2019-01-13 03:16:09
谁能给我解释一下这个代码,看不懂他的运行步骤
#include <stdio.h>
#include <string.h>
void main(){
char p[20]={'a','b','c','d'},q[]="abc",r[]="abcde";
strcat(p,r);
strcpy(p+strlen(q),q);
printf("%d\n",p+strlen(p));
return 0;
}
...全文
224 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2019-01-14
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
林多 2019-01-14
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <string.h>
void main(){
char p[20]={'a','b','c','d'},q[]="abc",r[]="abcde";
// 操作完成后。数组p为 abcdabcde\0
strcat(p,r);
// 操作完成后。数组p为 abcadc\0。注意:数组p申请了20个字节的内存。这段内存的内存此时为 abcadc\0de\0
strcpy(p+strlen(q),q);
// 这步并不会越界!!!!!strlen(p)的长度为6。所以指向的内容为p偏移6个字节,其实就是\0。
printf("%d\n",p+strlen(p));
// 如果加上这一条。输出的内容为de。因为指向的是p偏移7个地址,从d开始输出,直到遇到\0。
// 因此,也可以验证,上面说的一切。
printf("%s\n",p+strlen(p) + 1);
return 0;
}


额外:
strcat(des,src), 把src所指向的字符串(包括\0)复制到dest所指向的字符串后面(删除dest末尾原有\0)。
stcpy(des, src),把src所指向的字符串(包括\0)复制到dest所指的地址空间。
只要理解,这两个函数,就可以啦。




棉猴 2019-01-14
  • 打赏
  • 举报
回复
VS2015调试结果如图所示

下面我们分析一下代码:
strcat(p, r);//此时p的内容是"abcdabcde\0"
strcpy(p + strlen(q), q);//此时p的值是abcabc\0de

接下来需要注意的是,此时strlen(p)的值是6
printf("%d\n", p + strlen(p));//输出p的地址再偏移6个字节的地址

以上代码是输出地址,而不是地址中的内容。此时,p的地址是0x004FF81C,再加上6,应该是0x004FF82,把这个值换算成十进制即为上图显示的5240886。正如楼上所说,如果要显示p地址中保存的内容,而不是显示p的地址,需要如下代码:
printf("%d\n", *p);//显示p指向的内容,而不是p的地址

需要注意的是,由于strcpy()、strcat()等函数存在内存泄漏问题,如果要在VS2015中使用这些函数,必须在文件起始位置处加入如下代码
#define _CRT_SECURE_NO_WARNINGS
636f6c696e 2019-01-14
  • 打赏
  • 举报
回复
int i;
    for (i = 0; i < 20; i++)
    {
        printf("%d %d\n", p + i, *(p + i));
    }
加上这个打印,楼主你一定就能理解了
636f6c696e 2019-01-14
  • 打赏
  • 举报
回复
程序里打印的只是地址,不存在越界的问题
引用 1 楼 夕水2018 的回复:
void main(){ char p[20]={'a','b','c','d'},q[]="abc",r[]="abcde"; strcat(p,r); // p = abcdabcde,将p和r进行拼接得到p strcpy(p+strlen(q),q); //q的长度为3,将q复制到p+3的位置,覆盖之前的,此时p=abdabc printf("%d\n",p+strlen(p)); //p的长度为6,p+6刚好是数组越界的位置,输出一个不确定的系统值,程序崩溃。 return 0; }
Jackistang 2019-01-14
  • 打赏
  • 举报
回复
引用 9 楼 lin5161678 的回复:
[quote=引用 2 楼 Jackisy 的回复:]
p[20]不是一个字符串,少了个Null,从strcat就会开始报错

有初始化 没确定的元素 全部是 0
你误会了
p 存字符串这一点没问题的[/quote]感谢,学习了
lin5161678 2019-01-14
  • 打赏
  • 举报
回复
引用 2 楼 Jackisy 的回复:
p[20]不是一个字符串,少了个Null,从strcat就会开始报错

有初始化 没确定的元素 全部是 0
你误会了
p 存字符串这一点没问题的
lin5161678 2019-01-14
  • 打赏
  • 举报
回复
引用 1 楼 夕水2018 的回复:
void main(){
char p[20]={'a','b','c','d'},q[]="abc",r[]="abcde";
strcat(p,r); // p = abcdabcde,将p和r进行拼接得到p
strcpy(p+strlen(q),q); //q的长度为3,将q复制到p+3的位置,覆盖之前的,此时p=abdabc
printf("%d\n",p+strlen(p)); //p的长度为6,p+6刚好是数组越界的位置,输出一个不确定的系统值,程序崩溃。
return 0;
}

有瑕疵
q是3
p+3是d的位置
结果是 abcabc
p+6 不会越界
p一共20个元素 才+6 怎么会越界
结果的确是一个不确定的值
因为输出的是 &p[6]
数组分配在哪里无法确定
但不会越界 也不会崩溃 只是无法确定输出结果
Jackistang 2019-01-13
  • 打赏
  • 举报
回复
p[20]不是一个字符串,少了个Null,从strcat就会开始报错
夕水2018 2019-01-13
  • 打赏
  • 举报
回复
void main(){
char p[20]={'a','b','c','d'},q[]="abc",r[]="abcde";
strcat(p,r); // p = abcdabcde,将p和r进行拼接得到p
strcpy(p+strlen(q),q); //q的长度为3,将q复制到p+3的位置,覆盖之前的,此时p=abdabc
printf("%d\n",p+strlen(p)); //p的长度为6,p+6刚好是数组越界的位置,输出一个不确定的系统值,程序崩溃。
return 0;
}

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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