免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 67163 | 回复: 15
打印 上一主题 下一主题

[C] 请教:C语言函数的返回值类型能否为结构体? [复制链接]

论坛徽章:
0
1 [报告]
发表于 2010-01-26 17:02 |显示全部楼层
原帖由 daybreakcx 于 2010-1-26 16:59 发表
可以的,但是我认为但是如果结构体比较大的话,直接返回结构体不太好,因为如果外部用一个变量接着就还需要一次拷贝,可以用指针传


似懂非懂 , 误导人了!

论坛徽章:
0
2 [报告]
发表于 2010-01-26 17:15 |显示全部楼层
原帖由 c/unix 于 2010-1-26 17:12 发表


意思是你传的时候可以用指针传,返回就不要用指针了,如果是栈上的怎么办。


不是这个意思. 再大的结构都可以返回 , 没有所谓拷贝的过程.

你们可以想想 , 如果要拷贝 , 具体怎么拷贝 ?!

论坛徽章:
0
3 [报告]
发表于 2010-01-26 17:23 |显示全部楼层
原帖由 daybreakcx 于 2010-1-26 17:15 发表
传入时候是指针传入被操作结构体地址,直接原地操作,我的意思是这样


这就说明你还没太懂.

论坛徽章:
0
4 [报告]
发表于 2010-01-26 17:25 |显示全部楼层
原帖由 daybreakcx 于 2010-1-26 17:23 发表

结构体返回的话一般来说都不会只有一个成员变量,所以一般返回后需要一个结构体变量接着它的返回值,就像2楼的程序一样,平时我一般都是这么干的,我认为这里就有一次整个结构体的拷贝,不知道你所说的是什么 ...


你给我解释拷贝过程 , 你将漏洞百出 , 无法自圆其说.

论坛徽章:
0
5 [报告]
发表于 2010-01-26 17:42 |显示全部楼层
原帖由 wsw1wsw2 于 2010-1-26 17:40 发表


返回的结构体就是根据该结构的大小,有几个字节拷贝出几个字节。
有怀疑可以看看编译出来的汇编。

C语言中一般不怎么玩,一般是传给函数一个结构体指针,由该函数修改这个结构。如果非要函数返回结构实 ...


拷贝? 在返回之前还是之后 ?

论坛徽章:
0
6 [报告]
发表于 2010-01-26 17:45 |显示全部楼层
在之前, 拷贝的目的地在哪里 ?
之后 , 拷贝的源又在哪里?

论坛徽章:
0
7 [报告]
发表于 2010-01-26 18:11 |显示全部楼层
FUNCTION_STRUCT ReturnStruct(void)
{
    FUNCTION_STRUCT internalData;
    internalData.m_Member1 = 1;
    internalData.m_Member2 = 2;
    strcpy(&(internalData.m_String[0]), "Hello World!\n");

    return internalData;
}


难道有人认为 internalData 就是拷贝之源 ?
那么按照一般的理解internalData可是在堆栈中生成的 , 如果是这样的话 ,函数一返回 , internalData岂不是没了.

"松饼熊"是正确的,他在2楼的程序实际上是这样的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int    m_Member1;
    int    m_Member2;
    char m_String[20];
}FUNCTION_STRUCT;

void ReturnStruct(FUNCTION_STRUCT *internalData)
{
    internalData->m_Member1 = 1;
    internalData->m_Member2 = 2;
    strcpy(internalData->m_String, "Hello World!\n");   
}

int main(int argc, char *argv[])
{
    FUNCTION_STRUCT externalData;
    ReturnStruct(&externalData);
    
    printf("%d, %d, %s",
            externalData.m_Member1,
            externalData.m_Member2,
            &externalData.m_String[0]);
    
    system("AUSE");   
    return 0;
}



这跟 "OneWaterloo" 说的结构体大小没有关系 , 都是这样的.

[ 本帖最后由 老手 于 2010-1-26 18:14 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2010-01-26 21:07 |显示全部楼层
下面这个程序没问题吧
#include <stdio.h>

struct atomic_t {
  int val ;
} ;

struct atomic_t GetAtomic()
{
  struct atomic_t a ;
  
  a.val = 0x33 ;

  return a ;
}


int main()
{
  struct atomic_t b ;

  b = GetAtomic() ;

  return b.val>0 ? 1 : 0 ;
}


去掉截屏 , 免得flw老大不高兴.


[ 本帖最后由 老手 于 2010-1-26 22:30 编辑 ]

ret_stru.jpg (291 Bytes, 下载次数: 117)

ret_stru.jpg

论坛徽章:
0
9 [报告]
发表于 2010-01-26 21:18 |显示全部楼层
那就从汇编的角度看看吧:
GetAtomic proc near

var_4= dword ptr -4
arg_0= dword ptr  8

push    ebp
mov     ebp, esp
sub     esp, 10h
mov     edx, [ebp+arg_0]
mov     [ebp+var_4], 33h
mov     eax, [ebp+var_4]
mov     [edx], eax
mov     eax, edx
leave
retn    4
GetAtomic endp



public main
main proc near

var_24= dword ptr -24h
arg_0= byte ptr  4

lea     ecx, [esp+arg_0]
and     esp, 0FFFFFFF0h
push    dword ptr [ecx-4]
push    ebp
mov     ebp, esp
push    ecx
sub     esp, 18h
lea     eax, [ebp-18h]
mov     [esp+24h+var_24], eax
call    GetAtomic
sub     esp, 4
mov     eax, [ebp-18h]
mov     [ebp-8], eax
mov     eax, [ebp-8]
test    eax, eax
setnle  al
movzx   eax, al
mov     ecx, [ebp-4]
leave
lea     esp, [ecx-4]
retn
main endp


gcc 4.1.1 编译 O2优化 , 请"OneWaterloo"看看VC++是不是这样的, 我没有VC.

论坛徽章:
0
10 [报告]
发表于 2010-01-26 23:44 |显示全部楼层
原帖由 w_anthony 于 2010-1-26 23:31 发表
最烦那些一上来就装X的,摆出一付自己高人一等架势的家伙。就算你再牛X,谦虚一点不行么?更何况凡是人,都有出错的可能,给别人点面子,也给自己留条后路。

void func(struct A* p)
{
&nbsp;&nbsp;&nbsp;&nbsp;struct A a;
&nbsp;&nbsp;&nbsp;&nbsp;a.i = 0;
&nbsp;&nbsp;&nbsp;&nbsp;*p = a;        //拷贝发生在这里


}



请搞清楚再说.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP