[C]值传递、指针传递、引用传递

来源:互联网 发布:伊戈达拉数据虎扑 编辑:程序博客网 时间:2024/04/28 12:48

C语言值传递怎么用,引用传递怎么用?

以表格来简要说明并区分这几种传递到底在做什么:

类型 传递对象 传递行为 内存关系 适用情况 区别与联系 举例 值传递 数值 将实参的数值拷贝到另一块独立的内存上,在新的内存上操作 形参和实参占用不同的内存 函数内部需要修改参数,并且希望此改变的作用域不涉及调用者 传递是单向的,实参->形参 函数调用时,参数为数值 地值传递 地址 直接在实参所在的内存上操作 形参指向的和实参所在的是一块内存 内部对变量进行操作,并且希望此操作的作用域包括调用者;返回值传递 传递是双向的,实参<->实参 函数调用时,参数为地址 引用传递 别名 同上 形参和实参是同一个变量的不同名字,拥有相同的内存 同上 同上 实参代替了形参

具体说来,引用/地址传递在返回值传递上的应用是指:
假设函数需要有多个返回值,而显式上不能有返回值或者只能有一个返回值,则此时可利用指针/引用传递,对其他需要返回的变量进行修改,并将修改返回给调用者,完成隐式的返回值传递。
下面我们用代码来直接证明这三种传递在做什么:

#include<iostream>#include<stdlib.h>using namespace std;void swap_value(int a, int b){    cout << "swap 前,形参的数值和地址:" << endl;    cout << "value(a) = " << a << "," << "变量a的地址:" << &a << endl;    cout << "value(b) = " << b << "," << "变量b的地址:" << &b << endl;    int tmp;    tmp = a;    a = b;    b = tmp;    cout << "swap 后,形参的数值和地址:" << endl;    cout << "value(a) = " << a << "," << "变量a的地址:" << &a << endl;    cout << "value(b) = " << b << "," << "变量b的地址:" << &b << endl;}void swap_adress_value(int *a, int *b){    cout << "swap 前,形参的地址和指向的数值:" << endl;    cout << "value(a) = " << a << "," << "*a:" << *a << endl;    cout << "value(b) = " << b << "," << "*b:" << *b << endl;    int *tmp;    tmp = a;    a = b;    b = tmp;    cout << "swap 后,形参的地址和指向的数值:" << endl;    cout << "value(a) = " << a << "," << "*a:" << *a << endl;    cout << "value(b) = " << b << "," << "*b:" << *b << endl;}void swap_pointer(int *a, int *b){    cout << "swap 前,形参的地址和指向的数值:" << endl;    cout << "value(a) = " << a << "," << "*a:" << *a << endl;    cout << "value(b) = " << b << "," << "*b:" << *b << endl;    int tmp;    tmp = *a;    *a = *b;    *b = tmp;    cout << "swap 后,形参的地址和指向的数值:" << endl;    cout << "value(a) = " << a << "," << "*a:" << *a << endl;    cout << "value(b) = " << b << "," << "*b:" << *b << endl;}void swap_reference(int &a, int &b){    cout << "swap 前,形参的地址和指向的数值:" << endl;    cout << "value(a) = " << a << "," << "a存储地址:" << &a << endl;    cout << "value(b) = " << b << "," << "b存储地址:" << &b << endl;    int tmp;    tmp = a;    a = b;    b = tmp;    cout << "swap 后,形参的地址和指向的数值:" << endl;    cout << "value(a) = " << a << "," << "a存储地址:" << &a << endl;    cout << "value(b) = " << b << "," << "b存储地址:" << &b << endl;}int main(){    cout << "值传递:" << endl;    int x = 10;    int y = -1;    cout << "swap 前,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    swap_value(x, y);    cout << "swap 后,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    system("pause");    cout << endl;    cout << endl;    cout << endl;    cout << "传递地址且对地址进行修改:" << endl;    x = 10;    y = -1;    cout << "swap 前,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    swap_adress_value(&x, &y);    cout << "swap 后,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    system("pause");    cout << endl;    cout << endl;    cout << endl;    cout << "指针传递:" << endl;    x = 10;    y = -1;    cout << "swap 前,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    swap_pointer(&x, &y);    cout << "swap 后,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    system("pause");    cout << endl;    cout << endl;    cout << endl;    cout << "引用传递:" << endl;    x = 10;    y = -1;    cout << "swap 前,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    swap_reference(x, y);    cout << "swap 后,实参的数值和地址:" << endl;    cout << "value(x) = " << x << "," << "变量x的地址:" << &x << endl;    cout << "value(y) = " << y << "," << "变量y的地址:" << &y << endl;    system("pause");    cout << endl;    cout << endl;    cout << endl;}

再来看执行结果:

值传递:swap 前,实参的数值和地址:value(x) = 10,变量x的地址:0046FD4Cvalue(y) = -1,变量y的地址:0046FD40swap 前,形参的数值和地址:valuea) = 10,变量a的地址:0046FC68value(b) = -1,变量b的地址:0046FC6Cswap 后,形参的数值和地址:valuea) = -1,变量a的地址:0046FC68value(b) = 10,变量b的地址:0046FC6Cswap 后,实参的数值和地址:value(x) = 10,变量x的地址:0046FD4Cvalue(y) = -1,变量y的地址:0046FD40请按任意键继续. . . 传递地址且对地址进行修改:swap 前,实参的数值和地址:value(x) = 10,变量x的地址:0046FD4Cvalue(y) = -1,变量y的地址:0046FD40swap 前,形参的地址和指向的数值:valuea) = 0046FD4C,*a:10value(b) = 0046FD40,*b:-1swap 后,形参的地址和指向的数值:valuea) = 0046FD40,*a:-1value(b) = 0046FD4C,*b:10swap 后,实参的数值和地址:value(x) = 10,变量x的地址:0046FD4Cvalue(y) = -1,变量y的地址:0046FD40请按任意键继续. . . 指针传递:swap 前,实参的数值和地址:value(x) = 10,变量x的地址:0046FD4Cvalue(y) = -1,变量y的地址:0046FD40swap 前,形参的地址和指向的数值:valuea) = 0046FD4C,*a:10value(b) = 0046FD40,*b:-1swap 后,形参的地址和指向的数值:valuea) = 0046FD4C,*a:-1value(b) = 0046FD40,*b:10swap 后,实参的数值和地址:value(x) = -1,变量x的地址:0046FD4Cvalue(y) = 10,变量y的地址:0046FD40请按任意键继续. . . 引用传递:swap 前,实参的数值和地址:value(x) = 10,变量x的地址:0046FD4Cvalue(y) = -1,变量y的地址:0046FD40swap 前,形参的地址和指向的数值:valuea) = 10,a存储地址:0046FD4Cvalue(b) = -1,b存储地址:0046FD40swap 后,形参的地址和指向的数值:valuea) = -1,a存储地址:0046FD4Cvalue(b) = 10,b存储地址:0046FD40swap 后,实参的数值和地址:value(x) = -1,变量x的地址:0046FD4Cvalue(y) = 10,变量y的地址:0046FD40请按任意键继续. . . 

      我们结合运行结果来分析一下:
      调用swap_xxx函数之前,变量x,y分别有自己的地址和数值。
      调用函数swap_value时,相当于做了以下2个赋值操作:

a = x;b = y;

     这只是说把x、y的value分别赋给a、b。
     可以通过结果看出,a、b有自己的内存,内存地址与x、y不同。且调出swap_value之后,发生数值交换的仅是内部变量而已,外部变量x、y的地址和数值并没受到影响。
     调用swap_adress_value/swap_pointer时,相当于做了以下2个赋值操作:

*a = &x*b = &y

     这里&是取地址的意思,是把x、y的地址分别赋给指针变量a、b,也就是说a有自己的内存地址,这块内存存储的就是x的地址,也即a指向了x。
     只不过,在函数swap_adress_value内部,只是将指针变量a和b的value做了交换。所以外部变量x、y不受任何影响,而内部变量a、b有自己的内存地址,a和b的地址未发生改变,但是a和b的value改变了,a和b指向的变量改变了。
     而在swap_pointer里面,则是将a和b指向的内容作了交换,a和b的value未发生改变,依然指向之前的内存,但是它们指向的内存里面所存储的内容作了交换。同时在外部,x和y依然对应着原来的内存,所以x和y的地址都没有改变,但是里面写入的值却发生了改变。也就是说内部变量交换的时候,是在外部变量所对应的同一块内存空间上进行的。
     调用swap_reference时,相当于做了以下2个赋值操作:

&a = x;&b = y;

     这里&是引用的意思,是说a和x对应着同一块内存,对其中任何一个的修改,另一个都会受到影响,a和x相当于同一个变量的两个名字。所以内部变量a和x的地址一样,数值一样。交换之后,a和x的数值、地址依然一样。

#define

#ifdef的用途

#include的作用

#include是文件包含指令,在程序编译时,把#include后面指定文件的内容包含进当前的文件中。主要有2种形式:
1、#include<file.h>
从标准库中寻找file.h文件,是系统库头文件,根据一定的规则查找filh.h。
2、#include”file.h”
从工程目录下开始寻找file.h文件,是自定义的头文件,在源文件所在位置查找filh.h。

typedef

C语言工程的编译过程

如下图所示:
这里写图片描述

C程序的内存分布

数组的初始化

数组和指针的联系与区别

为什么数组不能更改指向地址?这样设计的动机是什么?

void指针是什么?

函数指针怎么定义?

函数指针的用途是什么?

malloc和free,什么时候需要用它们?

0 0
原创粉丝点击