免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: 党妈妈
打印 上一主题 下一主题

初学C语言请教一个返回struct的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-04-11 15:28 |只看该作者

回复 #10 bugboy_bugboy 的帖子

对应的汇编:
///////////////////可以运行的//////////////////////////////
        .file        "t.c"
        .text
.globl B
        .type        B, @function
B:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $16, %esp
        movl        8(%ebp), %edx
        movb        $97, -12(%ebp)
        movb        $0, -11(%ebp)
        movl        -16(%ebp), %eax
        movl        %eax, (%edx)
        movl        -12(%ebp), %eax
        movl        %eax, 4(%edx)
        movl        -8(%ebp), %eax
        movl        %eax, 8(%edx)
        movl        -4(%ebp), %eax
        movl        %eax, 12(%edx)
        movl        %edx, %eax
        leave
        ret        $4
        .size        B, .-B
        .section        .rodata
.LC0:
        .string        "%s\n"
        .text
.globl main
        .type        main, @function
main:
        leal        4(%esp), %ecx
        andl        $-16, %esp
        pushl        -4(%ecx)
        pushl        %ebp
        movl        %esp, %ebp
        pushl        %ecx
        subl        $36, %esp
        leal        -20(%ebp), %eax
        movl        %eax, (%esp)
        call        B
        subl        $4, %esp
        movl        -16(%ebp), %eax
        movl        %eax, 4(%esp)
        movl        -12(%ebp), %eax
        movl        %eax, 8(%esp)
        movzwl        -8(%ebp), %eax
        movw        %ax, 12(%esp)
        movl        $.LC0, (%esp)
        call        printf
        movl        -4(%ebp), %ecx
        leave
        leal        -4(%ecx), %esp
        ret
        .size        main, .-main
        .ident        "GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3)"
        .section        .note.GNU-stack,"",@progbits

////////////////////挂掉的汇编////////////////////////////
        .file        "t1.c"
        .text
.globl B
        .type        B, @function
B:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $16, %esp
        movl        8(%ebp), %edx
        movb        $97, -12(%ebp)
        movb        $0, -11(%ebp)
        movl        -16(%ebp), %eax
        movl        %eax, (%edx)
        movl        -12(%ebp), %eax
        movl        %eax, 4(%edx)
        movl        -8(%ebp), %eax
        movl        %eax, 8(%edx)
        movl        -4(%ebp), %eax
        movl        %eax, 12(%edx)
        movl        %edx, %eax
        leave
        ret        $4
        .size        B, .-B
        .section        .rodata
.LC0:
        .string        "%s\n"
        .text
.globl main
        .type        main, @function
main:
        leal        4(%esp), %ecx
        andl        $-16, %esp
        pushl        -4(%ecx)
        pushl        %ebp
        movl        %esp, %ebp
        pushl        %ecx
        subl        $52, %esp
        leal        -20(%ebp), %eax
        movl        %eax, (%esp)
        call        B
        subl        $4, %esp
        movl        -16(%ebp), %eax
        movl        %eax, 4(%esp)
        movl        -12(%ebp), %eax
        movl        %eax, 8(%esp)
        movzwl        -8(%ebp), %eax
        movw        %ax, 12(%esp)
        movl        $.LC0, (%esp)
        call        printf
        movl        -4(%ebp), %ecx
        leave
        leal        -4(%ecx), %esp
        ret
        .size        main, .-main
        .ident        "GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3)"
        .section        .note.GNU-stack,"",@progbits

论坛徽章:
0
12 [报告]
发表于 2008-04-11 20:19 |只看该作者
原帖由 党妈妈 于 2008-4-11 11:38 发表

多谢版主!版主能不能介绍一下这个微妙的区别?谢谢!!


在 C 语言中,所有函数的返回值(如程序中的 B())是非左值(non-lvalue)表达式。相应地,非左值的成员也是非左值(如 B().b)。

程序中的问题出现在 C89 和 C99 标准对于非左值数组的不同处理上。

在 C89 中,只有左值数组对象才可以转换为指针来使用,也才可以进行数组下标运算;而非左值数组(如 B().b)则不能转换为指针(它始终是一个数组),所以也不能进行数组下标运算(注意:有的编译器的扩展功能允许)。在 C 语言中,如果数组不能够转换为指针,则除了 sizeof 之外,对数组不能进行任何其它运算。程序中试图对非左值数组进行求值运算,所以是非法的。

在 C99 中对于非左值的数组规定进行了变更,允许非左值的数组和左值数组一样使用。这样按照 C99 标准程序就是合法的了。

论坛徽章:
0
13 [报告]
发表于 2008-04-11 21:29 |只看该作者
原帖由 whyglinux 于 2008-4-11 20:19 发表


在 C 语言中,所有函数的返回值(如程序中的 B())是非左值(non-lvalue)表达式。相应地,非左值的成员也是非左值(如 B().b)。

程序中的问题出现在 C89 和 C99 标准对于非左值数组的不同处理上。

...


楼上回答很精彩,受教

论坛徽章:
0
14 [报告]
发表于 2008-04-12 14:48 |只看该作者
原帖由 whyglinux 于 2008-4-11 20:19 发表


在 C 语言中,所有函数的返回值(如程序中的 B())是非左值(non-lvalue)表达式。相应地,非左值的成员也是非左值(如 B().b)。

程序中的问题出现在 C89 和 C99 标准对于非左值数组的不同处理上。

...

非常感谢,虽然我似懂非懂但是已经清楚了很多了。您对标准实在太熟悉了,佩服。

论坛徽章:
0
15 [报告]
发表于 2008-04-12 15:09 |只看该作者
原帖由 whyglinux 于 2008-4-11 20:19 发表


在 C 语言中,所有函数的返回值(如程序中的 B())是非左值(non-lvalue)表达式。相应地,非左值的成员也是非左值(如 B().b)。

程序中的问题出现在 C89 和 C99 标准对于非左值数组的不同处理上。

...


简单的C语言细节还真多啊,不过写了这么多年程序,还真没这么用过,这左值非左值好像还没搞明白,俺都是怎么简单怎么直观怎么来,只要用着不出错就成

[ 本帖最后由 bierdaci 于 2008-4-12 15:12 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP