社区
C语言
帖子详情
函数值的存储空间是如何分配的?
OneMoreFreeMan
2005-03-12 08:17:35
哪位大侠能详细讲述一下函数值的存储空间是如何分配的。特别是当有值返回的函数,而又不被读去时,则返回的值被存储在何处。
...全文
202
10
打赏
收藏
函数值的存储空间是如何分配的?
哪位大侠能详细讲述一下函数值的存储空间是如何分配的。特别是当有值返回的函数,而又不被读去时,则返回的值被存储在何处。
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
10 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
dongpy
2005-03-13
打赏
举报
回复
特别是当有值返回的函数,而又不被读去时,则返回的值被存储在何处
===================================
如果函数返回值类型不大于寄存器的宽度,即小于等于32位。
那么返回值放在寄存器eax带出函数。
如果返回值类型大于32位,那么返回值的地址放在寄存器eax带出函数。
yuanyou
2005-03-13
打赏
举报
回复
学习!
tabris17
2005-03-13
打赏
举报
回复
上次说了一个C++对象在内存中的实际形式,现在来说说C++中以对象为参数或返回值的函数是如何实现的。在此之前如果你对函数调用的汇编形式毫无概念的话可以先看看这篇文章:http://www.20cn.net/ns/wz/sys/data/20040208183412.htm
来看下面的代码:
class test //sizeof(test) is 24
{
public:
int m1;
int m2;
int m3;
int m4;
int m5;
int m6;
};
test function1()
{
test cls2;
return cls2; // Line 15
}
int function2(test temp)
{
temp.m1=1; // Line 20
return 0; // Line 21
}
int main()
{
test cls1;
cls1=function1(); // Line 27
function2(cls1); // Line 28
return 0;
}
由于VC编译的未优化代码和优化后的代码相差比较大,所以在编译时增加"/02"参数,使用命令行"cl test.cpp /Fa /02"对源文件进行编译。得到的中间汇编代码如下:
PUBLIC ?function1@@YA?AVtest@@XZ ; function1
; COMDAT ?function1@@YA?AVtest@@XZ
_TEXT SEGMENT
_cls2$ = -24
$T295 = 8
?function1@@YA?AVtest@@XZ PROC NEAR ; function1入口
; File main.cpp
; Line 15
mov eax, DWORD PTR $T295[esp-4] ; 将cls1的地址作为返回值保存到eax中
sub esp, 24 ; 分配cls2的内存
mov ecx, 6
push esi
push edi
lea esi, DWORD PTR _cls2$[esp+32]
mov edi, eax
rep movsd ; 将cls2对象复制到cls1中去
pop edi
pop esi
; Line 16
add esp, 24 ; 00000018H
ret 0
?function1@@YA?AVtest@@XZ ENDP ; function1结束
_TEXT ENDS
PUBLIC ?function2@@YAHVtest@@@Z ; function2
; COMDAT ?function2@@YAHVtest@@@Z
_TEXT SEGMENT
?function2@@YAHVtest@@@Z PROC NEAR ; function2入口
; Line 21
xor eax, eax ; Line 20 的操作被优化掉了
; Line 22
ret 0
?function2@@YAHVtest@@@Z ENDP ; function2结束
_TEXT ENDS
PUBLIC _main
; COMDAT _main
_TEXT SEGMENT
$T301 = -24
_main PROC NEAR ; COMDAT
; Line 25
sub esp, 24 ; 分配cls1的内存空间
; Line 27
lea eax, DWORD PTR $T301[esp+24] ; 将cls1的地址送入eax寄存器
push esi
push edi
push eax ; 将cls1的地址作为参数传递给function1
call ?function1@@YA?AVtest@@XZ ; 调用function1
; Line 28
sub esp, 20 ; 恢复堆栈并分配temp对象的空间(24-4=20)
mov ecx, 6
mov esi, eax
mov edi, esp
rep movsd ; 将cls1对象复制到temp对象中去
call ?function2@@YAHVtest@@@Z ; 调用function2
add esp, 24 ; 00000018H
; Line 29
xor eax, eax
; Line 30
pop edi
pop esi
add esp, 24 ; 00000018H
ret 0
_main ENDP
_TEXT ENDS
END
先来看function1的调用过程:1)程序现在堆栈中给cls1分配了24字节的内存;然后将cls1的地址作为参数传递给function1;随后调用function1。2)进入function1中,程序先给cls2分配内存;然后程序将cls2对象复制到cls1中去;把cls1的地址作为返回值。
根据上述过程,"test function1();"的实际形式其实是:
test *function1(test *ptr_cls)
{
test cls2;
memcpy(ptr_cls,&cls2,sizeof(test));
return ptr_cls;
}
而调用代码的实际形式是:
int main()
{
test cls1;
function1(&cls1);
... ...
return 0;
}
再来看function2的调用过程:程序先给temp分配了一个24字节的对象;然后将cls1对象复制到temp对象中去;随后就调用function2。比起function1,function2要简单很多。
lovefly_fanny
2005-03-12
打赏
举报
回复
上面提醒我了,不够严密
指的堆栈是进程堆栈区区别于系统堆栈
谁再来补充,学习···^_^
lovefly_fanny
2005-03-12
打赏
举报
回复
当从主程序进入到一个函数的时候,堆栈中增加一个元组,
存放临时变量,也包括返回值。
当程序返回后,就从堆栈中退栈。如果返回值被赋给某个主调
程序中的变量时,实际上是调用了copy constructor按bite复制了返回值到
主调程序的变量中,(如果自己定义了该类型的copy构造函数的话,就调用
自己定义的copy构造函数把函数的返回值复制到主调程序的变量中)
当这个过程完成后,栈顶元素被释放,这样包括函数中的临时变量和返回值
都被释放掉了。
****************************************
返回值是不可能放在堆栈里的。。。
想想看,当一个函数返回的时候
如果把返回值放在堆栈中,由于
返回函数必须pop到函数返回地址(也就是在函数调用的时候
push进去的地址),而x86机子中堆栈的生长方向是
向下的,必然的这里 你所谓的”返回值“就在返回地址的
下面了,这样在pop的过程中已经将返回值抹去了,也就不存在
返回值拷贝的可能了。
个人认为,返回值作为一个临时变量,由于有返回对象的可能,
所以返回值的地址应该放在寄存器中,临时变量在赋值或者拷贝构造之后
自动清除。。。
yuchengliu
2005-03-12
打赏
举报
回复
有的放在EAX中
有的是系统栈
其他的我没有自己亲自见过!
CharlieBrown
2005-03-12
打赏
举报
回复
另外,如果函数返回值是自己new出来的话,这个在函数返回后都不被清除,
就要自己手动释放。。
CharlieBrown
2005-03-12
打赏
举报
回复
当从主程序进入到一个函数的时候,堆栈中增加一个元组,
存放临时变量,也包括返回值。
当程序返回后,就从堆栈中退栈。如果返回值被赋给某个主调
程序中的变量时,实际上是调用了copy constructor按bite复制了返回值到
主调程序的变量中,(如果自己定义了该类型的copy构造函数的话,就调用
自己定义的copy构造函数把函数的返回值复制到主调程序的变量中)
当这个过程完成后,栈顶元素被释放,这样包括函数中的临时变量和返回值
都被释放掉了。
jsunnygirl
2005-03-12
打赏
举报
回复
我觉的返回的值只是临时变量,应该在堆栈中吧
特别是当有值返回的函数,而又不被读去时,则返回的值没有存储空间.
就像一个函数内的局部变量,函数退出后就没了
nodummy
2005-03-12
打赏
举报
回复
按照cdecl协议的要求,函数的返回值是放在eax寄存器的
另外什么叫函数值?函数返回值?好像不太像……
位运算题目:找到最接近目标
值
的
函数
值
由于遍历
函数
值
的顺序具有单调性,因此相等的
函数
值
在遍历顺序中一定相邻,每次将
函数
值
入队列时判断当前
函数
值
与上一个入队列的
函数
值
是否相等,即可排除重重复元素。实现方面,区分上一轮的
函数
值
和当前轮的
函数
值
的做法有多种,可以创建两个列表分别存储上一轮的
函数
值
和当前轮的
函数
值
,也可以使用队列存储
函数
值
。使用队列的做法如下。作为子数组的右侧端点,当前轮的
函数
值
包括上一轮的每个
函数
值
分别与。,计算当前轮的每个
函数
值
与目标
值
的差的绝对
值
,更新最小差
值
。时,队列中的元素为上一轮的所有
函数
值
,记录此时队列的大小。
python返回
函数
值
并退出
函数
_Python基础:Python
函数
一、
函数
是python中使用最高的对象。
函数
定义的简单规则 :1、用def定义,接着是
函数
名和参数和冒号,格式:2、
函数
内部代码块需要缩进3、使用return返回
函数
值
,默认返回
值
是None格式:def
函数
名(参数) :代码块return #可有可无,也可以在代码块任意位置使用二、
函数
中return的使用:return可以在
函数
的任何地方使用,直接跳出当前
函数
,忽略...
输出
函数
f(a,b)=2×a2+b2的最小的100个
函数
值
及相应的两个参数的
值
最近朋友问了我一道题,看了网上各种思路后,决定用栈来实现它 题目: 设计程序按从大到小的次序依次输出
函数
f(a,b)=2×a2+b2的最小的100个
函数
值
及相应的两个参数的
值
,其中a和b均为自然数。 要求: (1)作为
函数
值
的存储结构应尽可能节省空间。 (2)所设计算法及整个程序的时间复杂度应尽可能小。 思路: 遍历每一个数result,找到符合2*a^2+b^2==result的a和b,下面代码中在0~50中找a和b,本题中可以缩小搜索范围,如果没找到,resul就加1,开始找下一轮。因为题
m个人的成绩存放在score数组中,请编写
函数
fun,它的功能是:将低于平均分的人数作为
函数
值
返回,将低于平均分的分数放在below所指的数组中。
m个人的成绩存放在score数组中,请编写
函数
fun,它的功能是:将低于平均分的人数作为
函数
值
返回,将低于平均分的分数放在below所指的数组中。当解决这个问题时,需要执行以下步骤: 1. 计算所有成绩的总和。 2. 计算平均分,通过将总和除以成绩的总数来获得。 3. 创建一个循环来遍历所有的成绩,检查每个成绩是否低于平均分。 4. 如果成绩低于平均分,则将其放入一个新的数组中,并记录低于平均分的人数。 5. 返回低于平均分的人数作为
函数
值
,并且将低于平均分的成绩存放在指定的数组中。 这个问题可以通过单
数据结构笔记(十三)-- 串的堆
分配
存储表示
串的堆
分配
存储表示 一、堆
分配
存储概述 堆
分配
内存仍是一组地址连续的存储单元来存放串
值
字符序列,但是
存储空间
实在程序执行过程中动态
分配
而得。在C语言中,存在一个称为“堆”的自由存储区,并由C语言的动态
分配
函数
malloc()和free()来管理。利用
函数
malloc()为每个新产生的串
分配
一块实际串长所需的
存储空间
,若
分配
成功,则返回一个指向起始地址的指针,作为串的基址,同时为了方便以后的处理,约定串长也作为存储结构的一部分。 二、串的堆
分配
存储结构 三、串的操作 //1、初始化(产生空串)字符串S v
C语言
70,023
社区成员
243,263
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章