好,有了这个认识呢我们就可以来做几道题了。ok我们来看这样一道思考题。 第一道题,读一下这个程序,请你想象一下这个程序的 执行结果。 我们来看一下这个程序。从主程序开始。 主程序里头呢定义了两个变量,a和b,分别赋值3和5。 然后调用了一个函数change。调用完这个函数之后呢把a和b的结果打印 出来。那就希望检测a和b到底有没有被改变。我们来看一下这个函数。这个函数是这样的。 它有两个形参,c和d,然后在函数 提议里头呢它对c赋值为30, d呢赋值为50。那现在问题很明确。我就是想问大家,在这儿a和b 打印出来到底会是多少呢?是3和5呢?还是30 和50呢?也就是说现在这个change的这个 函数到底有没有改变a和b的值? 到底有没有改变? 好这个程序我们运行我们就知道它没有改变。为什么没有改变呢?我们来 解释一下这个函数的执行过程大家就明白了。那么要执行这样一个程序我们首先还是把右边蓝色的 区域看作一片内存空间。 那么要执行的话呢,首先我开辟一片内存空间来放入 main函数。那么在main函数里头呢我定义了两个变量。 a和b。a的值呢是3,b的值呢是5。然后呢在main函数里头我 调用了change这个函数。只要我一调用,系统呢就会在内存空间里面 再开辟出一片区域来放入change。那么因为呢在change这个函数中 定义了两个形式参数,所以说呢就相当于在change的内存空间中 开辟了两个变量,一个是c,一个是d,而且呢由于main函数在 调用change的时候啊传递了两个参数,一个是a一个是b。 根据刚才我们所讲过的,把a的值传递给c就相当于把a的值 copy了一份给c。a的值是多少?是3。所以说copy了一份给c。 c的值也是3。然后呢b的值也一样,b的值呢也copy了一份给 d,所以d的值呢是5。然后呢这个change还是说开始执行。 在执行的过程呢,c和d被重新赋值了。c和d的值由原来的3和5变成了 30和50。 那么执行完这一句程序之后呢,change这个函数就执行完毕了。 change这个函数在定义的时候我们指定它的类型是void的类型。 所以说它不需要返回任何的值给main函数。于是 change这个函数在执行完,在把c和d换成了30和50以后 就执行完了。在执行完以后change这个函数就消失掉了。 就被释放掉了。 因为它没有返回任何的值,所以说对main函数没有任何的影响。main函数继续往下执行。执行到了 c out <<a和<<b。 那请问main函数呢它在a和b被修改过吗?当然没有。 a还是原来的a,b还是原来的b。 因为传递参数来说呢都是 copy了一份,都是复制了一份。所以说 a和b没有受到任何的影响。所以这个时候打印出来a和b的值仍然是3 和5。那么透过这个例子大家就可以进一步的理解 这个参数的传递。什么叫做copy? 那么之所以反复的强调呢是因为有它的书少,关于这个问题的解释太过于笼统。 那么很多时候呢一句直传递就结束了关于这个问题的解释了,那什么叫做直传递? 在这儿我特别打这个比方。copy。 copy。ok这是第一道题目。 那么接下来我对这个题目稍做修改。我们来看这个程序。 这个程序跟刚才那个程序有什么不同呢?不同处在这儿。 刚才那个程序的形式的参数的名字是c和d。 那么在这儿呢这个程序呢它的形式参数的名字被 改成了a和b,那么当然在这里头呢相应的 改成对a复制对b进行复制。ok那么对这样一个程序 请问在主函数里头把a和b的值打印出来的时候a和b的值会改变吗? 我们也看一下这个程序的运行过程。 仍然假设蓝色的区域是内存。那么要运行这个程序我首先开辟一片内存空间 把main函数放进去。那么在main函数里头呢定义了两个 变量,分别叫做a和b,那么值呢分别是3和5。 然后呢接下来main函数开始执行,执行到了change a, b,既然呢要调用到change函数,所以 在内存里面再开辟一片内存空间 来放这个change函数,因为它定义了两个形参,所以在change这个函数里头 有两个变量a和b。在main函数里面调用change函数 的时候我给这个change函数赋的值是a和b,那么这个a的值呢是3 于是呢copy一份给a,于是a的值呢变成3。 那么然后呢copy一份给这个b,于是b的值呢变成5,那么接下来呢 change函数继续往下执行,对a和b进行重新复制,a变成了30,b呢变成了50。 那么执行完这个过程以后有没有返回任何的值啊?没有,因为change这个函数的 类型是void的类型,所以这个函数不会返回任何值给main,那么既然它已经执行完了 所以接下来它会被释放掉。被释放掉而且没有返回任何的值 那么main函数呢继续往下执行。c out <<a和<<b。那会打印出多少来?3和5。 因为在main函数空间里的这个a和b从来 没有被修改过,它传递给函数的这个 a和b呢都是copy了一份。 那么在这儿呢我们想说明的是这样的一个问题。虽然我们在定义函数的时候使用了跟 main函数里头名字看似一样的变量作为函数的形式参数 但实际上这个地方把cd改成ab 有影响吗?没有任何的影响,因为你所定义的这个ab是在哪里呀? 它是在change这个函数的自己的内存空间里头。 那么这个ab在哪里呀?这个ab在main函数的内存空间里头。 你说虽然两个都是ab,但是它们却在完全不同的内存空间里。 也就是说这两个ab虽然都叫ab但它们互不干涉。 没有任何的互相干涉的地方。所以说呢在main函数里头的 ab不会被改变。也就是说最后的结果会是 3和5。这就是这个程序的一段执行过程。 好下面我们再来看一道题。再来巩固一下,因为太重要了。 好这里又有一个程序,在主程序里头定义了两个变量a,b, 并且在主程序呢调用了一个函数,就是change a, b 最后呢再把a和b都打印出来,确认一下有没有变化。 那么这个函数是这样的。两个参数,一个参数是a,一个参数是b,如果 a小于b的话,我就做这么一个操作,大家一看就知道,是a b互换位置。 也就是说如果a小于b的话,我就把a和b的位置互换一下。 对于这样的一个程序它的运行结果应该是怎样的呢? 好那我们来快速的分析一下。 我们想要运行这个程序的时候我们首先开辟一片内存空间把main函数放进去。 在main函数里头会有两变量,一个呢被初始化为3,一个被初始化为5,然后呢main函数开始 执行一条语句叫exchange (a, b),把ab当作参数来调用exchange这个函数。 那么既然要调用exchange,于是在内存里面生出一片新的内存空间 然后呢把exchange放进去,在exchange的内存空间中呢有两个变量a和b。 那么又在调用的过程中呢main函数把a的值传给了这个a。 把b的值呢传给了这个b。这个怎么去传递的?我们是不是很清楚了?copy, copy, copy! 把a的值copy一份给a,所以说a的值是3,把b的值copy一份给b,所以b变成5。 然后接下来呢在exchange的内存空间中a和b 因为满足了a小于b这个条件,所以说a和b进行了一个 互换。然后呢exchange又执行完了,并且呢没有返回任何的东西给main函数。 于是exchange在执行完之后它就消失掉了。 消失掉了之后呢main函数在从exchange调用之后 继续往下执行c out打印出a和b来。所以最后的结果是3和5。 是不是一样的道理呀?这个程序跟刚才那个程序 完全一样的道理。在这儿之所以反复强调是因为 太重要了。 我希望大家能够彻底的理解这一点。