鱼C论坛

 找回密码
 立即注册
查看: 2212|回复: 10

函数中的数组问题

[复制链接]
发表于 2016-4-22 10:12:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include "stdio.h"
  2. main(){
  3.     char s1[1000]="123455556";
  4.     char s2[1000];
  5.     compress(s1,s2);
  6.     printf("%s",&s2);
  7.     }

  8. void compress(char s1[],char s2[]){
  9.     char c;
  10.     int i,ii,iii;
  11.     i=0;
  12.     iii=0;
  13.     char *p=s2;
  14.     while(s1[i]!='\0'){
  15.         if(s1[i]==-1);
  16.         else{
  17.             c=s1[i];
  18.             ii=i+1;
  19.             s2[iii++]=c;
  20.             s2[iii]='\0';
  21.             printf("%s\n",&s2);/*测试语句*/
  22.             while(s1[ii]!='\0'){
  23.             if(c==s1[ii])s1[ii]=-1;
  24.             ii++;
  25.         }
  26.         }
  27.         i++;
  28.     }
  29. }
复制代码


上面是一个吧字符串s1的重复字符删去生成新的字符串s2的函数。
我测试时加了一个语句,但输入的结果却是这样的,
求助大神们“@?“是怎么来的我预想的结果应该是输出1\n   12\n
捕获.PNG
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-4-22 11:19:04 | 显示全部楼层

卤煮,printf("%s\n", &s2);  什么鬼?

你要把数组的地址以字符串形式输出?太凶残了吧?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-4-22 21:43:25 | 显示全部楼层
本帖最后由 小剑剑 于 2016-4-22 21:45 编辑
n0noper 发表于 2016-4-22 11:19
卤煮,printf("%s\n", &s2);  什么鬼?

你要把数组的地址以字符串形式输出?太凶残了吧?


...我一直都是这样写,竟然现在才发现
我印象中的字符串就是一个地址,所以输出时觉得要加取地址符
为何主函数的printf没出错呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-25 09:13:14 | 显示全部楼层
小剑剑 发表于 2016-4-22 21:43
...我一直都是这样写,竟然现在才发现
我印象中的字符串就是一个地址,所以输出时觉得要加取 ...
  1. void fun(char param[])
  2. {
  3.         printf("%s\n", param);        // 这里取得是传入的参数 的存储地址
  4.         printf("%s\n", &param);        // 这里取得是传入的参数 的堆栈地址
  5. }

  6. int _tmain(int argc, _TCHAR* argv[])
  7. {
  8.         char arr[100] = "Hello";

  9.         printf("%s\n", arr);
  10.         printf("%s\n", &arr);        // arr是局部变量 地址固定

  11.         fun(arr);

  12.         return 0;
  13. }
复制代码



main函数中反汇编:
  1.         printf("%s\n", arr);
  2. 0030141B  mov         esi,esp  
  3. 0030141D  lea         eax,[arr]  
  4. 00301420  push        eax  
  5. 00301421  push        305860h  
  6. 00301426  call        dword ptr ds:[3092C8h]  
  7. 0030142C  add         esp,8  
  8. 0030142F  cmp         esi,esp  
  9. 00301431  call        __RTC_CheckEsp (0301145h)  
  10.         printf("%s\n", &arr);
  11. 00301436  mov         esi,esp  
  12. 00301438  lea         eax,[arr]  
  13. 0030143B  push        eax  
  14. 0030143C  push        305860h  
  15. 00301441  call        dword ptr ds:[3092C8h]  
  16. 00301447  add         esp,8  
  17. 0030144A  cmp         esi,esp  
  18. 0030144C  call        __RTC_CheckEsp (0301145h)  
复制代码


fun函数中反汇编结果:
  1.         printf("%s\n", param);
  2. 00E413FE  mov         esi,esp  
  3. 00E41400  mov         eax,dword ptr [param]  
  4. 00E41403  push        eax  
  5. 00E41404  push        0E45858h  
  6. 00E41409  call        dword ptr ds:[0E492C8h]  
  7. 00E4140F  add         esp,8  
  8. 00E41412  cmp         esi,esp  
  9. 00E41414  call        __RTC_CheckEsp (0E4114Ah)  
  10.         printf("%s\n", &param);
  11. 00E41419  mov         esi,esp  
  12. 00E4141B  lea         eax,[param]  
  13. 00E4141E  push        eax  
  14. 00E4141F  push        0E45858h  
  15. 00E41424  call        dword ptr ds:[0E492C8h]  
  16. 00E4142A  add         esp,8  
  17. 00E4142D  cmp         esi,esp  
  18. 00E4142F  call        __RTC_CheckEsp (0E4114Ah)
复制代码


如果懂汇编,就不用看下边了,如果没学过,那就稍微理解一下下边这张图:
栈.jpg


有什么问题,再讨论。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-25 20:42:57 | 显示全部楼层
n0noper 发表于 2016-4-25 09:13
main函数中反汇编:

我明白fun函数的printf为什么出错,因为&param是param的地址,但param存放的是另一个地址所以打印出错,但我不懂为什么主函数没有出错。看不懂汇编,查了一下汇编指令单还没看懂,解释一下主函数的两个printf的第二句(一个是mov一个是lea)为什么不同可能我就懂了,内存位置地址这些只是我还懂一些。鱼油真的很热心,谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-25 23:48:45 | 显示全部楼层
看看
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-4-26 09:28:31 | 显示全部楼层
小剑剑 发表于 2016-4-25 20:42
我明白fun函数的printf为什么出错,因为&param是param的地址,但param存放的是另一个地址所以打印出错, ...
  1. mov         esi,esp                     ; 暂存esp寄存器的值,为了后边的堆栈平衡检测 - 因为不平衡会死人的!
  2. lea         eax,[arr]                   ; arr数组的地址 给eax寄存器
  3. push        eax                         ; arr数组的地址 入栈
  4. push        305860h                     ; 这里这个内存地址,存放的就是你的"%s\n"这个常量格式字符串
  5. call        dword ptr ds:[3092C8h]      ; 调用printf函数
  6. add         esp,8                       ; 你两次push操作,这条指令相当于两次pop,堆栈平衡
  7. cmp         esi,esp                     ; 比较esi(之前保存esp值)和当前esp值是否相同,就是为了检测堆栈平衡
  8. call        __RTC_CheckEsp (0301145h)   ; 这个我猜测是VS添加的安全机制,还是为了安全 - -
复制代码


卤煮,别说看不懂,我真的会砍死你!

arr是个局部变量,存放的字符串就在局部变量的内存中,所以没办法,输出解析就成功了;
如果不是很清楚,画画图,就很容易理解了。(不会画?找我啊,收徒,200一位,包教包会~~   )

PS:以上言论纯属扯淡!有啥问题,卤煮再讨论哈。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-26 11:15:33 | 显示全部楼层
n0noper 发表于 2016-4-26 09:28
卤煮,别说看不懂,我真的会砍死你!

arr是个局部变量,存放的字符串就在局部变量的内 ...
  1. #include "stdio.h"
  2. main(){
  3.      char a[100]="sb";
  4.      printf("%d  %d",a,&a);}
复制代码

我懂了,a虽然存了一个地址,但这个地址就是它本身的地址,a后面接的就是字符‘s’

运行结果

运行结果
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-26 11:50:04 | 显示全部楼层
小剑剑 发表于 2016-4-26 11:15
我懂了,a虽然存了一个地址,但这个地址就是它本身的地址,a后面接的就是字符‘s’


卤煮,你弄个字符串内容啥意思?是不是挑事?我不行了,我想打架了- -

虽然我不想打击你,但是我想说:内存中,没有a这么个东西,他只不过是一个名字而已。
学学调试,对自学有巨大巨大的好处。

如果不懂?问我啊!反正我也不会告诉你
Q1263591465 等我写一篇调试基础,通知你。记得评论回复!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-26 12:54:20 | 显示全部楼层
本帖最后由 小剑剑 于 2016-4-26 12:56 编辑
n0noper 发表于 2016-4-26 11:50
卤煮,你弄个字符串内容啥意思?是不是挑事?我不行了,我想打架了- -

虽然我不想打击你,但是我想 ...


莫激动,且听我慢慢道来
  1. #include "stdio.h"
  2. main(){
  3.     char a[]="sb";
  4.     printf("%d  %d\n",a,&a);
  5.     dizhi(a);
  6. }
  7. void dizhi(char s[]){
  8.     printf("%d  %d",s,&s);
  9. }
复制代码

我也会画图,主函数中a就是一个地址,&a就根本没意义,&a=0
但在自定义的函数中呢,把地址a赋值给了另一个变量s
&s就是s的地址,&s=4.错了不要打我

结果

结果
无标题.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-4-26 13:03:09 | 显示全部楼层
小剑剑 发表于 2016-4-26 12:54
莫激动,且听我慢慢道来

我也会画图,主函数中a就是一个地址,&a就根本没意义,&a=0


哎呀,小伙纸,腻害啊!

就是这个意思,细节上以后再说就行了。

大侠如此厉害,在下实在佩服!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-13 04:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表