C与C++的比较:参数传递


1. C语言

1.1 一般参数

#include <stdio.h>

void f(int i) // 置0
{
    printf("f   : %p %d\n", &i, i);
    i = 0;
    printf("f   : %p %d\n", &i, i);
}

int main()
{
    int a = 1;
    printf("main: %p %d\n", &a, a);
    f(a);
    printf("main: %p %d\n", &a, a);

    return 0;
}

运行结果

分析:因为实参地址(0022FEDC)和形参地址(0022FEC0)不同,所以实参p和形参i不是同一变量。修改i不会改变a。

1.2 指针参数

#include <stdio.h>

void f(int *i) // 修改指针
{
    printf("f   : %p %p %d\n", &i, i, *i);
    int m = 0;
    i = &m;
    printf("f   : %p %p %d\n", &i, i, *i);
}

int main()
{
    int a = 1;
    int *p = &a;
    printf("main: %p %p %d\n", &p, p, *p);
    f(p);
    printf("main: %p %p %d\n", &p, p, *p);

    return 0;
}

运行结果

分析:因为实参指针地址(0022FED8)和形参指针地址(0022FEC0)不同,实参p和形参i是两个不同的指针。因为p和i的值相等,都是0022FEDC,所以它们指向同一变量。修改i不会改变p。

#include <stdio.h>

void f(int *i) // 修改指针指向的值
{
    printf("f   : %p %p %d\n", &i, i, *i);
    *i = 0;
    printf("f   : %p %p %d\n", &i, i, *i);
}

int main()
{
    int a = 1;
    int *p = &a;
    printf("main: %p %p %d\n", &p, p, *p);
    f(p);
    printf("main: %p %p %d\n", &p, p, *p);

    return 0;
}

运行结果

分析:因为实参指针地址(0022FED8)和形参指针地址(0022FEC0)不同,实参p和形参i是两个不同的指针。因为p和i的值相等,都是0022FEDC,所以它们指向同一变量。修改*i会改变*p。

1.3 数组参数

#include <stdio.h>

void f(int i[]) // 修改数组i
{
    printf("f   : %p %p %d\n", &i, i, *i);
    int m = 0;
    i = &m;
    printf("f   : %p %p %d\n", &i, i, *i);
}

int main()
{
    int a[3] = {1, 2, 3};
    printf("main: %p %p %d\n", &a, a, *a);
    f(a);
    printf("main: %p %p %d\n", &a, a, *a);

    return 0;
}

运行结果

#include <stdio.h>

void f(int i[]) // 修改数组元素i[0]
{
    printf("f   : %p %p %d\n", &i, i, *i);
    i[0] = 0;
    printf("f   : %p %p %d\n", &i, i, *i);
}

int main()
{
    int a[3] = {1, 2, 3};
    printf("main: %p %p %d\n", &a, a, *a);
    f(a);
    printf("main: %p %p %d\n", &a, a, *a);

    return 0;
}

运行结果

分析:传递数组,实际是传递数组起始元素的位置或地址。实参a与形参i是两个不同的数组名,但它们的值都是0022FED4,指向同一变量。修改i不会改变a,修改i[0]才会改变a[0]。

扫描二维码关注公众号,回复: 10238577 查看本文章

1.4 总结

  1. 在C语言中,所有函数参数都是值传递,地址也是一种值。函数调用时,实参的被赋给形参,修改形参不会改变实参。
  2. 传递指针实际是传递变量的地址。形参和实参是不同指针,但指向同一变量。修改形参不会改变实参,修改形参指向的变量会改变实参指向的对象。
  3. 传递数组实际是传递数组起始元素的地址。与指针类似,修改形参不会改变实参,修改形参的数组元素会改变实参的数组元素。

2. C++语言

2.1 一般参数

#include "iostream"
using namespace std;

void f(int i) // 置0
{
    cout << "f   : " << &i << " " << i << endl;
    i = 0;
    cout << "f   : " << &i << " " << i << endl;
}

int main()
{
    int a = 1;
    cout << "main: " << &a << " " << a << endl;
    f(a);
    cout << "main: " << &a << " " << a << endl;

    return 0;
}

运行结果

分析:&a是0x22fecc,&i是0x22feb0,a和i是不同变量,修改a不会改变i。

2.2 指针参数

#include "iostream"
using namespace std;

void f(int *i) // 修改指针
{
    cout << "f   : " << &i << " " << i << " " << *i << endl;
    int m = 0;
    i = &m;
    cout << "f   : " << &i << " " << i << " " << *i << endl;
}

int main()
{
    int a = 1;
    int *p = &a;
    cout << "main: " << &p << " " << p << " " << *p << endl;
    f(p);
    cout << "main: " << &p << " " << p << " " << *p << endl;

    return 0;
}

运行结果

#include "iostream"
using namespace std;

void f(int *i) // 修改指针指向的变量
{
    cout << "f   : " << &i << " " << i << " " << *i << endl;
    i[0] = 0;
    cout << "f   : " << &i << " " << i << " " << *i << endl;
}

int main()
{
    int a = 1;
    int *p = &a;
    cout << "main: " << &p << " " << p << " " << *p << endl;
    f(p);
    cout << "main: " << &p << " " << p << " " << *p << endl;

    return 0;
}

运行结果

分析:传递指针时,会将实参拷贝给形参。形参i与实参p是两个不同的指针,它们都指向同一变量a。修改i不会改变p,修改*i会改变*p。

2.3 数组参数

#include "iostream"
using namespace std;

void f(int i[]) // 修改数组
{
    cout << "f   : " << &i << " " << i << " " << *i << endl;
    int m[3] = {0, 0, 0};
    i = m;
    cout << "f   : " << &i << " " << i << " " << *i << endl;
}

int main()
{
    int a[3] = {1, 2, 3};
    cout << "main: " << &a << " " << a << " " << *a << endl;
    f(a);
    cout << "main: " << &a << " " << a << " " << *a << endl;

    return 0;
}

运行结果

#include "iostream"
using namespace std;

void f(int i[]) // 修改数组元素
{
    cout << "f   : " << &i << " " << i << " " << *i << endl;
    i[0] = 0;
    cout << "f   : " << &i << " " << i << " " << *i << endl;
}

int main()
{
    int a[3] = {1, 2, 3};
    cout << "main: " << &a << " " << a << " " << *a << endl;
    f(a);
    cout << "main: " << &a << " " << a << " " << *a << endl;

    return 0;
}

运行结果

分析:传递数组时,实际上传递的是指向数组首元素的指针。形参i与实参a是两个不同的指针,它们都指向同一变量。修改i不会改变a,修改i[0]会改变a[0]。

2.4 引用参数

#include "iostream"
using namespace std;

void f(int &i) // 修改i
{
    cout << "f   : " << &i << " " << i << endl;
    i = 0;
    cout << "f   : " << &i << " " << i << endl;
}

int main()
{
    int a = 1;
    cout << "main: " << &a << " " << a << endl;
    f(a);
    cout << "main: " << &a << " " << a << endl;

    return 0;
}

运行结果

分析:形参i是引用类型,i引用a,即i是a的别名。对i的操作实际上是对a进行操作,故修改i会改变a。

注意:C语言中,形参不能是引用类型。

#include <stdio.h>

void f(int &i)
{
    printf("f   : %p %d\n", &i, i);
    i = 0;
    printf("f   : %p %d\n", &i, i);
}

int main()
{
    int a = 1;
    printf("main: %p %d\n", &a, a);
    f(a);
    printf("main: %p %d\n", &a, a);

    return 0;
}

编译错误

运行错误

2.5 总结

  1. 在C++中,参数传递分为值传递引用传递两种。程序调用函数时会创建形参,并用实参对形参初始化。
  2. 传递数组实际上是传递指向数组首元素的指针。数组传递和指针传递都算是值传递。
  3. C++中形参可以是引用类型,C中不可以。
发布了77 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34801642/article/details/104945020