现代编程语言对于值传递与引用传递的支持程度是比较不同的

首先介绍值传递与引用传递的概念

值传递

将变量a传递到其他的函数并对其更改,不能影响a的值

引用传递

在其他的作用域对传入的变量a的更改可以影响a的值

Note:

在这里的值的概念,对于原始类型,指的就是字面的值,如1,2,'a';

而对于动态内存分配/类,则指的是指向这个分配内存/类的引用,而非解引用后指向的内存/类所保存的值

C语言

C语言本身只支持值传递,但是通过指针这一概念,通过解引用可以达到引用传递的效果

C++

作为C语言的超集发展起来的语言,C++支持C语言的值传递与指针传递,同时C++还添加了引用传递(某种意义上是指针的语法糖),所以C++实际上通过两种语法支持引用传递

下面演示C/C++的值传递与引用传递

#include <iostream>#include <vector>#include <algorithm>using namespace std;/// 基础类型热引用void swap_ref(int &a, int &b) {    int t = a;    a = b;    b = t;}/// 类的引用void swap_ref(string &a, string &b) {    string t = a;    a = b;    b = t;}/// 值传递void swap_val(int a, int b) {    int t = a;    a = b;    b = t;}/// 类的值传递void swap_val(string a, string b) {    string t = a;    a = b;    b = t;}/// 基于指针进行引用传递void swap_ptr(int *a, int *b) {    int t = *a;    *a = *b;    *b = t;}void swap_ptr(string *a, string *b) {    string t = *a;    *a = *b;    *b = t;}int main() {    int a = 1;    int b = 2;    swap_ref(a, b);//引用传递    printf("%d %d\n", a, b);    swap_val(a, b);//值传递    printf("%d %d\n", a, b);    string x = "x", y = "y";    swap_ref(x, y);//引用传递    cout << x << " " << y << endl;    swap_val(x, y);//值传递 无效果    cout << x << " " << y << endl;    /// \brief  使用指针本身进行值传递 通过解引用达到了解引用的效果    swap_ptr(&a, &b);//通过指针引用传递    printf("%d %d\n", a, b);    swap_ptr(&x, &y);//指针的引用传递    cout << x << " " << y << endl;    return 0;}
$ ./main.exe2 12 1y xy x1 2x y

Notes:

  • 使用指针可以改变其指向的对象的值,但是其无法改变其指针自己的值,如果想改变指针指向的对象,如果想在其他函数改变指针的值,只能取这个指针的指针,这又回到了swap这个问题

Java

Java可能是处于控制语言的复杂度的考虑,只支持值传递。

同样的还有Python

public class type {    public static void main(String[] args) {        String s = "One String";        System.out.println(s);        changeString(s);        System.out.println(s);    }    public static void changeString(String s) {        s = "Yet Another String";    }}

C

C#在很多特性是和Java很类似,但是在类型系统中,C#同时支持值类型与引用类型。

namespace ConsoleApp1{    class Program    {        static void Main(string[] args)        {            int a = 1, b = 2;            swap(ref a, ref b);            Console.WriteLine($"a = {a} b = {b}");            swap(a, b);            Console.WriteLine($"a = {a} b = {b}");            string x = "x-ray", y = "y-ray";            swap(ref x, ref y);            Console.WriteLine($"x = {x} y = {y}");            swap(x, y);            Console.WriteLine($"x = {x} y = {y}");        }        private static void swap(int a, int b)        {            int t = a;            a = b;            b = t;        }        private static void swap(ref int a, ref int b)        {            int t = a;            a = b;            b = t;        }        private static void swap(string a, string b)        {            string t = a;            a = b;            b = t;        }        private static void swap(ref string a, ref string b)        {            string t = a;            a = b;            b = t;        }    }}
$a = 2 b = 1a = 2 b = 1x = y-ray y = x-rayx = y-ray y = x-ray