C++中编译时遇到函数的定义,编译器做了哪些事,

"由于定义函数时编译器并不会分配内存,因此引用修饰符“&”不再其作用"这句话怎么理解;不分配内存,当调用时又怎么能找到;定义数组时编译器就分配内存,在内存哪里;还有编译器... "由于定义函数时编译器并不会分配内存,因此引用修饰符“&”不再其作用"这句话怎么理解;不分配内存,当调用时又怎么能找到;定义数组时编译器就分配内存,在内存哪里;还有编译器编译时怎么能分配内存
原来是这样,不认真看书自己给自己设绊——程序一开始执行时就已经分配了一大块连续内存,用一个变量记录这块连续内存的首地址,然后程序中所有用到的,程序员以为是向操作系统分配的内存都可以通过那个首地址加上相应偏移来得到正确位置,而这很明显地由编译器做了。因此实际上等同于在编译时期(即编译器编译程序的时候)就已经分配了内存
展开
 我来答
爱德IV菠萝
2011-12-04 · TA获得超过161个赞
知道小有建树答主
回答量:108
采纳率:0%
帮助的人:90.1万
展开全部
我个人的见解是这样的,数组因为在定义的时候确定了数组的大小所以编译器才可以为其分配内存。函数名和数组名就是内存的首地址,所以函数名是代表的入口地址,当你主程序真正调用的这个函数时候,才会为从入口地址进入,并且为这个分配其确定大小的内存。事先不执行的内存都是为空,不为其分配,只有用到了并且明确了其所需多少内存时候才会分配。比如说一个函数仅仅定义了它,在没用在调用它的时候系统是不能知道所占用的内存,并且没必要去开辟内存。只有执行到需要调用的,只需要如函数名(即入口的内存地址)开始分配并调用即可。
至于编译为什么能分配内存,这个是由操作系统和编译器共同完成,内存是动态变化的,所以第三方用户的程序使用的内存是执行时候系统和编译器临时给的地址。
这是鄙人的一些见解,如有不对请指出
enochwills
推荐于2016-01-26 · TA获得超过4793个赞
知道大有可为答主
回答量:2031
采纳率:96%
帮助的人:1639万
展开全部
哦。。。你可能断章取义了。我猜猜看,应该是说“在类的声明中,由于定义函数时编译器。。。”
这样还差不多。
对于c语言,你的理解问题不大,因为一个函数的声明默认都是静态的,也就是编译器把需要分配内存的所有变量和函数都统计出来:
int add(int a, int b) { return a+b;}
等于
static int add(int a, int b) { return a+b};
void * token = (void*)&add; // <-这样是可以的。

但是c++就不是特别一样了,类成员函数,由于是和“实例(instance)“捆绑在一起的,所以一般来说,都是动态声明的,除非用静态声明定义,否则无法在编译器阶段获取地址:
class CFunction {
public:
int add(int, int);
int minus(int, int);
};
void * token = (void*)&CFunction::add; // <-这样写是错误的,因为类是一个结构性声明,在没有实例化以前,是没有具体地址的;
CFunction *myFunc = new CFunction;
void *token = (void*)(myFunc->add); // <-这样写是可以的,但是有一定的风险,因为类的实例释放时不会通知到token已失效!

除非:
class CFun {
public:
static int add(int, int);
};
void * token = (void*)&(CFun::add); // <-只有很少量的编译器支持这种方式的地址。总之不提倡!
追问
我现在迷惑的是,对C++编译器来说,遇到哪些东西的定义会分配内存,如果说在编译时期就分配内存,那最后生成的EXE文件运行,又怎么分配内存;遇到函数的定义,编译时是否必定生成代码在代码段,当遇到该函数调用时,再取这段代码段内容,如果这样的话,怎么又说定义函数时引用修饰符“&”不起作用(不是特指类中的成员函数,就是一般情况。已经困惑很久,我还是菜鸟,希望还能讲细点
追答
呵呵,只要是定义的东西肯定都分配内存的,但是静态分配还是动态分配,就不单单是编译器的问题了,还要看操作系统。

EXE文件只是一张为计算机运行程序时提供的特殊的“图纸”,你可以这样理解,这张图纸告诉计算机的CPU,代码段总共有多大,数据段总共有多大,堆栈段是怎么安排的,而已。

在DOS时代,你必须要亲自考虑这些事情,因为可分配的内存是非常紧张而有限的。比如,我玩DOS 6.22时,必须用Turbo C一点一点考虑已经分配的内存是否超过512KB,也就是0.5MB。

在WINDOWS / LINUX / MAC OS X 时代,大家很少去考虑这些事情,因为操作系统已经把这个事情大包大揽了,你只需要了解如果用new或者malloc分配地址时,如果返回为空,表示内存已经不足,即可。WIN7 和 FEDORA / LION 直接支持的内存已经达到8GB或者更多(WIN XP仅能支持3GB)。

比C++更先进的下一代语言,比如C#、JAVA、Object C(如果你希望在你的iPhone手机上编写比愤怒的小鸟更彪悍的程序),甚至干脆取消了对函数指针的直接管理,改为“引用”(可以理解为一种非常安全的指针),因为往往操作系统在提供库函数的时候,干脆提供的是类似DLL/ ACTIVE X这样的动态链接库,编译器的工作已经退化为“对内存的申请”,而不是“对内存的管理”。

更先进的处理方法是,在云计算时代,你的函数运行时,可能指向的是某个网络上的节点计算机提供的运算服务。

所以说来说去,既然不需要关心的事情,那么在编程时就不需要去关心。

面对对象的语种:Visual Basic .net /C#/Object - C,其精髓在于对象、实例、消息、界面、属性和方法,这一点,和C语言时代、处于过渡阶段的C++来说,与结构、函数、变量的区别非常大。在苹果公司的xcode 4.2 object C编程环境中,甚至不需要进行代码编写,只需要用界面工具将各个控件的关系用特殊方法关联起来,就可以形成新的应用程序;“面对对象的编程”,你只需要关心某个对象的某个实例在接到某个消息后处理某个特殊的事件即可,不再需要通篇考虑整个应用程序的程序代码组织。

举个例子,如同一块电路板,古典的方法是用很多的电线去连接各个部件;新的方法使用集成电路,所有芯片都采用了标准的电气针脚和连接方法,你需要做的,仅仅是升级某个部件的内容,而不要因为某个新需要的功能而重新在几个管脚之间增加飞线。这种“飞线”就如同“函数指针”,是在面对对象编程里竭力避免的。如有特殊需要,必须对照这个特殊函数的使用手册。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
yidetion
2011-12-04 · 超过19用户采纳过TA的回答
知道答主
回答量:53
采纳率:0%
帮助的人:49.4万
展开全部
程序在内存中分为四部分
代码段 (程序代码,比如你的函数)
静态段 (存放静态变量和全局变量,还有用到的字面值常量)
堆 (由程序员自己管理的内存,动态分配用的就是这部分内存) //动态分配的数组在这里
栈 (由操作系统管理,局部变量和临时变量存在这里) //自己定义的数组在这里

现在你应该知道自己定义的普通数组在哪里,动态分配的数组又在哪里了吧.

调用函数时都是值传递,就是把变量的值复制一份给函数这时就会新分配一块内存给函数中
接收这个值的那个变量,当函数结束时,这个变量被释放
引用调用不是值传递,而是让函数直接操作你传递的实参
高级一点: 引用其实也是值传递这种方式,只不过编译器偷偷给你变成了指针
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
圣鸾OJ
2015-09-29 · TA获得超过1629个赞
知道小有建树答主
回答量:1136
采纳率:96%
帮助的人:113万
展开全部
哦。。。你可能断章取义了。我猜猜看,应该是说“在类的声明中,由于定义函数时编译器。。。”
这样还差不多。
对于c语言,你的理解问题不大,因为一个函数的声明默认都是静态的,也就是编译器把需要分配内存的所有变量和函数都统计出来:
int add(int a, int b) { return a+b;}
等于
static int add(int a, int b) { return a+b};
void * token = (void*)&add; // <-这样是可以的。

但是c++就不是特别一样了,类成员函数,由于是和“实例(instance)“捆绑在一起的,所以一般来说,都是动态声明的,除非用静态声明定义,否则无法在编译器阶段获取地址:
class CFunction {
public:
int add(int, int);
int minus(int, int);
};
void * token = (void*)&CFunction::add; // <-这样写是错误的,因为类是一个结构性声明,在没有实例化以前,是没有具体地址的;
CFunction *myFunc = new CFunction;
void *token = (void*)(myFunc->add); // <-这样写是可以的,但是有一定的风险,因为类的实例释放时不会通知到token已失效!

除非:
class CFun {
public:
static int add(int, int);
};
void * token = (void*)&(CFun::add); // <-只有很少量的编译器支持这种方式的地址。总之不提倡!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
o00RAINBOW00o
2011-12-04 · TA获得超过458个赞
知道答主
回答量:67
采纳率:0%
帮助的人:73万
展开全部
我自己理解的意思是 C++不像C语言那样函数随意堆积也不像JAVA一样必须将函数封装到类里,对于放到类中的函数只须把类放到内存中,调用的时候到构造函数里去找,再通过域解析符来确定调用的函数是哪个类里去找就可以。如果是不放到类中的函数那可能要先在内存中登个记,可能是类似指针的东西,等到调用的时候在去具体读取该函数。呵呵只是自己理解的在上面这些大家们面前现丑了
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式