鱼C论坛

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

函数中的数组问题

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

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

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

x
#include "stdio.h"
main(){
    char s1[1000]="123455556";
    char s2[1000];
    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[i]!='\0'){
        if(s1[i]==-1);
        else{
            c=s1[i];
            ii=i+1;
            s2[iii++]=c;
            s2[iii]='\0';
            printf("%s\n",&s2);/*测试语句*/
            while(s1[ii]!='\0'){
            if(c==s1[ii])s1[ii]=-1;
            ii++;
        }
        }
        i++;
    }
}

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

使用道具 举报

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

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

你要把数组的地址以字符串形式输出?太凶残了吧?
想知道小甲鱼最近在做啥?请访问 -> 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没出错呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

        fun(arr);

        return 0;
}


main函数中反汇编:
        printf("%s\n", arr);
0030141B  mov         esi,esp  
0030141D  lea         eax,[arr]  
00301420  push        eax  
00301421  push        305860h  
00301426  call        dword ptr ds:[3092C8h]  
0030142C  add         esp,8  
0030142F  cmp         esi,esp  
00301431  call        __RTC_CheckEsp (0301145h)  
        printf("%s\n", &arr);
00301436  mov         esi,esp  
00301438  lea         eax,[arr]  
0030143B  push        eax  
0030143C  push        305860h  
00301441  call        dword ptr ds:[3092C8h]  
00301447  add         esp,8  
0030144A  cmp         esi,esp  
0030144C  call        __RTC_CheckEsp (0301145h)  

fun函数中反汇编结果:
        printf("%s\n", param);
00E413FE  mov         esi,esp  
00E41400  mov         eax,dword ptr [param]  
00E41403  push        eax  
00E41404  push        0E45858h  
00E41409  call        dword ptr ds:[0E492C8h]  
00E4140F  add         esp,8  
00E41412  cmp         esi,esp  
00E41414  call        __RTC_CheckEsp (0E4114Ah)  
        printf("%s\n", ¶m);
00E41419  mov         esi,esp  
00E4141B  lea         eax,[param]  
00E4141E  push        eax  
00E4141F  push        0E45858h  
00E41424  call        dword ptr ds:[0E492C8h]  
00E4142A  add         esp,8  
00E4142D  cmp         esi,esp  
00E4142F  call        __RTC_CheckEsp (0E4114Ah) 

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


有什么问题,再讨论。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

发表于 2016-4-25 23:48:45 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

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

PS:以上言论纯属扯淡!有啥问题,卤煮再讨论哈。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

arr是个局部变量,存放的字符串就在局部变量的内 ...
#include "stdio.h"
main(){
     char a[100]="sb";
     printf("%d  %d",a,&a);}
我懂了,a虽然存了一个地址,但这个地址就是它本身的地址,a后面接的就是字符‘s’

运行结果

运行结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

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

如果不懂?问我啊!反正我也不会告诉你
Q1263591465 等我写一篇调试基础,通知你。记得评论回复!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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.错了不要打我

结果

结果
无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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


哎呀,小伙纸,腻害啊!

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

大侠如此厉害,在下实在佩服!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-27 02:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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