小剑剑 发表于 2016-4-22 10:12:29

函数中的数组问题

#include "stdio.h"
main(){
    char s1="123455556";
    char s2;
    compress(s1,s2);
    printf("%s",&s2);
    }

void compress(char s1[],char s2[]){
    char c;
    int i,ii,iii;
    i=0;
    iii=0;
    char *p=s2;
    while(s1!='\0'){
      if(s1==-1);
      else{
            c=s1;
            ii=i+1;
            s2=c;
            s2='\0';
            printf("%s\n",&s2);/*测试语句*/
            while(s1!='\0'){
            if(c==s1)s1=-1;
            ii++;
      }
      }
      i++;
    }
}

上面是一个吧字符串s1的重复字符删去生成新的字符串s2的函数。
我测试时加了一个语句,但输入的结果却是这样的,
求助大神们“@?“是怎么来的我预想的结果应该是输出1\n   12\n

n0noper 发表于 2016-4-22 11:19:04


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

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

小剑剑 发表于 2016-4-22 21:43:25

本帖最后由 小剑剑 于 2016-4-22 21:45 编辑

n0noper 发表于 2016-4-22 11:19
卤煮,printf("%s\n", &s2);什么鬼?

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

...我一直都是这样写,竟然现在才发现{:9_240:}
我印象中的字符串就是一个地址,所以输出时觉得要加取地址符
为何主函数的printf没出错呢

n0noper 发表于 2016-4-25 09:13:14

小剑剑 发表于 2016-4-22 21:43
...我一直都是这样写,竟然现在才发现
我印象中的字符串就是一个地址,所以输出时觉得要加取 ...

void fun(char param[])
{
        printf("%s\n", param);        // 这里取得是传入的参数 的存储地址
        printf("%s\n", &param);        // 这里取得是传入的参数 的堆栈地址
}

int _tmain(int argc, _TCHAR* argv[])
{
        char arr = "Hello";

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

        fun(arr);

        return 0;
}


main函数中反汇编:
        printf("%s\n", arr);
0030141Bmov         esi,esp
0030141Dlea         eax,
00301420push      eax
00301421push      305860h
00301426call      dword ptr ds:
0030142Cadd         esp,8
0030142Fcmp         esi,esp
00301431call      __RTC_CheckEsp (0301145h)
        printf("%s\n", &arr);
00301436mov         esi,esp
00301438lea         eax,
0030143Bpush      eax
0030143Cpush      305860h
00301441call      dword ptr ds:
00301447add         esp,8
0030144Acmp         esi,esp
0030144Ccall      __RTC_CheckEsp (0301145h)

fun函数中反汇编结果:
        printf("%s\n", param);
00E413FEmov         esi,esp
00E41400mov         eax,dword ptr
00E41403push      eax
00E41404push      0E45858h
00E41409call      dword ptr ds:
00E4140Fadd         esp,8
00E41412cmp         esi,esp
00E41414call      __RTC_CheckEsp (0E4114Ah)
        printf("%s\n", &param);
00E41419mov         esi,esp
00E4141Blea         eax,
00E4141Epush      eax
00E4141Fpush      0E45858h
00E41424call      dword ptr ds:
00E4142Aadd         esp,8
00E4142Dcmp         esi,esp
00E4142Fcall      __RTC_CheckEsp (0E4114Ah)

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



有什么问题,再讨论。

小剑剑 发表于 2016-4-25 20:42:57

n0noper 发表于 2016-4-25 09:13
main函数中反汇编:




我明白fun函数的printf为什么出错,因为&param是param的地址,但param存放的是另一个地址所以打印出错,但我不懂为什么主函数没有出错。看不懂汇编,查了一下汇编指令单还没看懂,解释一下主函数的两个printf的第二句(一个是mov一个是lea)为什么不同可能我就懂了,内存位置地址这些只是我还懂一些。鱼油真的很热心,谢谢{:5_92:}

xls6688 发表于 2016-4-25 23:48:45

看看{:5_92:}

n0noper 发表于 2016-4-26 09:28:31

小剑剑 发表于 2016-4-25 20:42
我明白fun函数的printf为什么出错,因为&param是param的地址,但param存放的是另一个地址所以打印出错, ...

mov         esi,esp                     ; 暂存esp寄存器的值,为了后边的堆栈平衡检测 - 因为不平衡会死人的!
lea         eax,                   ; arr数组的地址 给eax寄存器
push      eax                         ; arr数组的地址 入栈
push      305860h                     ; 这里这个内存地址,存放的就是你的"%s\n"这个常量格式字符串
call      dword ptr ds:      ; 调用printf函数
add         esp,8                     ; 你两次push操作,这条指令相当于两次pop,堆栈平衡
cmp         esi,esp                     ; 比较esi(之前保存esp值)和当前esp值是否相同,就是为了检测堆栈平衡
call      __RTC_CheckEsp (0301145h)   ; 这个我猜测是VS添加的安全机制,还是为了安全 - -

卤煮,别说看不懂,我真的会砍死你!{:10_277:}

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

PS:以上言论纯属扯淡!有啥问题,卤煮再讨论哈。

小剑剑 发表于 2016-4-26 11:15:33

n0noper 发表于 2016-4-26 09:28
卤煮,别说看不懂,我真的会砍死你!

arr是个局部变量,存放的字符串就在局部变量的内 ...

#include "stdio.h"
main(){
   char a="sb";
   printf("%d%d",a,&a);}

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

n0noper 发表于 2016-4-26 11:50:04

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


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

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

如果不懂?问我啊!反正我也不会告诉你{:10_256:}
Q1263591465 等我写一篇调试基础,通知你。记得评论回复!!!

小剑剑 发表于 2016-4-26 12:54:20

本帖最后由 小剑剑 于 2016-4-26 12:56 编辑

n0noper 发表于 2016-4-26 11:50
卤煮,你弄个字符串内容啥意思?是不是挑事?我不行了,我想打架了- -

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

莫激动,且听我慢慢道来
#include "stdio.h"
main(){
    char a[]="sb";
    printf("%d%d\n",a,&a);
    dizhi(a);
}
void dizhi(char s[]){
    printf("%d%d",s,&s);
}

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

n0noper 发表于 2016-4-26 13:03:09

小剑剑 发表于 2016-4-26 12:54
莫激动,且听我慢慢道来

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



哎呀,小伙纸,腻害啊!

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

大侠如此厉害,在下实在佩服!{:10_254:}
页: [1]
查看完整版本: 函数中的数组问题