玩美主义 发表于 2017-5-18 15:57:57

return的一个鸟问题

实不相瞒,吾乃小白一枚,初入C道,不得其法。吾今求一良师,必当勤学苦练,师若不弃,或跪或躺,岂不快哉?

好吧,大脑刚刚短路了一下,下面进入正题:

就是说,有一个很小的程序想请各位大神看一下子,为啥输出的是这些乱七八糟的玩意...

程序是这样纸的:

#include<stdio.h>

char foo(int a,int b);

char foo(int a,int b)
{
   return ;
}

int main()
{
    intx,y,z;

    z=foo(x,y);
    printf("%d\n",z);

    return 0;
}

我是用gcc编译的,程序编译通过输出16. 如果将char替换成int输出134513424;如果将char替换成float输出-2147483648.

小编看到结果的时候顿时就蒙圈啦!不同编译器输出会有差别吗?具体的原理是啥呢?

帮帮我吧,不然晚上又要失眠啦,呜呜~

Kiopler 发表于 2017-5-18 15:57:58

1.你那个函数根本没有返回值,所以无论你的返回类型变成 int或者 char无论什么类型,编译器由于没找到返回值就在内存里随地找了个数字,那个结果是不确定的. 至于你那个主函数里的z = foo (x, y)后面那函数部分输不输入值根本没啥意义,,,,因为没有返回值,所以结果都是不确定的.

2. char类型占1个字节也就是最多4位, int和float都是4个字节最多32位,编译器可能只是随意在这些范围内从内存里找个数字罢了。

我觉得这个版主好过分啊, 你厉害你看得懂就解释下,贴个新学的人看不懂的代码装隔壁。真以为自己牛逼死了

menkey 发表于 2017-5-18 16:49:31

这个在VS下报错的,foo没有一个反回值,我加了一个反回值return 'a'; a 的ASCII 值是97。输出结果是97。不知道对你没有帮助!

玩美主义 发表于 2017-5-18 16:54:15

menkey 发表于 2017-5-18 16:49
这个在VS下报错的,foo没有一个反回值,我加了一个反回值return 'a'; a 的ASCII 值是97。输出结果是97。 ...

谢谢!不过就是想测试return空语句怎么执行

人造人 发表于 2017-5-18 17:42:00

玩美主义 发表于 2017-5-18 16:54
谢谢!不过就是想测试return空语句怎么执行

这是反汇编,自己看看吧
        .file        "tmp.c"
        .intel_syntax noprefix
        .text
        .globl        foo
        .type        foo, @function
foo:
.LFB0:
        .cfi_startproc
        push        rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov        rbp, rsp
        .cfi_def_cfa_register 6
        mov        DWORD PTR , edi
        mov        DWORD PTR , esi
        nop
        nop
        pop        rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size        foo, .-foo
        .section        .rodata
.LC0:
        .string        "%d\n"
        .text
        .globl        main
        .type        main, @function
main:
.LFB1:
        .cfi_startproc
        push        rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov        rbp, rsp
        .cfi_def_cfa_register 6
        sub        rsp, 16
        mov        edx, DWORD PTR
        mov        eax, DWORD PTR
        mov        esi, edx
        mov        edi, eax
        call        foo
        movsx        eax, al
        mov        DWORD PTR , eax
        mov        eax, DWORD PTR
        mov        esi, eax
        mov        edi, OFFSET FLAT:.LC0
        mov        eax, 0
        call        printf
        mov        eax, 0
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size        main, .-main
        .ident        "GCC: (GNU) 7.1.0"
        .section        .note.GNU-stack,"",@progbits

玩美主义 发表于 2017-5-19 09:10:05

看不大懂,是否可以帮忙解释一下呢{:5_92:}

dust188 发表于 2017-5-19 12:48:46

为什么还在return个0?

玩美主义 发表于 2017-5-19 13:21:20

dust188 发表于 2017-5-19 12:48
为什么还在return个0?

return 0是main函数的

人造人 发表于 2017-5-19 23:07:52

玩美主义 发表于 2017-5-19 09:10
看不大懂,是否可以帮忙解释一下呢

看不懂就去学汇编语言

1314xxxxxx 发表于 2017-5-21 12:46:01

首先,第一个函数foo的类型只能是int或void,压根儿没有char这种类型(可能有,但鄙人不知)。然后,foo函数的return根本没有返回值。
还有,x和y根本就没有赋值。。。

Hacker_Jack 发表于 2017-5-21 17:33:42

首先返回值很明显是随机的,不信你多运行几次,应该是内存中固定一块区域内的值,在我的机器上跟你的输出不一样,float输出的是0,非gcc内核的基本都报错。既然返回值是随机的,那么原理应该是编译器从栈里随便拿了个什么数据就当结果塞给你了。甲鱼的汇编我就学了一半,4楼的代码我也看不大懂。

玩美主义 发表于 2017-5-22 16:59:58

感谢,不过我这边用GCC编译运行结果前后是一致的

zsy_ 发表于 2017-6-8 17:11:45

你主函数的C是用来接收返回值的,但是你的c是int类型,而你的返回值类型是char类型,所以不对,。

zsy_ 发表于 2017-6-8 17:13:13

而且你相应的printf()里输出格式也要相应改变。

也许,心累 发表于 2017-6-11 12:00:53

很简单,,,返回什么值 取决于eax寄存器里面存的是什么东西。。

yq2424281391 发表于 2017-6-12 08:12:19

提问的楼主很萌,你连c语言都还没入门。
1 你的函数没返回值 。
2 这段代码有错误:
intx,y,z;

    z=foo(x,y);//由于函数为返回任何值赋给
变量z所以z所存的值未知。
其实Kiopler兄弟回答的非常好了。
学c要仔细,要认真。
正确代码如下:
#include<stdio.h>

char foo(int a,int b);

char foo(int a,int b)
{   
   printf("我的邮箱\n") ;
   return'c';
}

int main()
{
    intx,y,z;

    z=foo(x,y);
    printf("%d   %c\n",    z    ,   z    );

    return 0;
}

world.com 发表于 2017-6-12 21:06:59

本帖最后由 world.com 于 2017-6-12 21:09 编辑

不知道是不是想要这个效果,蓝笔圈起来那一块定义的函数没用到

玩美主义 发表于 2017-7-3 09:22:46

yq2424281391 发表于 2017-6-12 08:12
提问的楼主很萌,你连c语言都还没入门。
1 你的函数没返回值 。
2 这段代码有错误:


感谢你的分享{:5_110:}
页: [1]
查看完整版本: return的一个鸟问题