按值传递与按引用传递的内存使用情况

问题描述 投票:-1回答:1

在过去的几天中,我试图了解按值传递和按引用传递是否会对内存产生不同的影响。在查询此查询时,人们一直在重复关于按值传递创建的副本以及按值传递引用对原始值的影响。但是我想知道是否有人可以将内存部分归零。

memory pass-by-reference pass-by-value
1个回答
0
投票

这个问题实际上在很大程度上取决于特定的语言,因为有些允许您明确并定义何时要按值传递变量以及何时按引用传递变量,而某些变量对不同类型的变量总是使用相同的方式。

一种非常流行的行为类型是在简单的时间使用按值传递(默认情况下:如int,string,long,float,double,bool等。

让我们展示一下记忆对理论语言的影响:

int $myVariable = 5;

目前,您已经在内存中创建了一个变量,该变量的大小存储整数(让我们说32位)。

现在您要将其传递给函数:

function someFunction(int parameter)
{
    printOnScreen(parameter);
}

所以您的代码看起来像:

function someFunction(int $parameter)
{
    printOnScreen($parameter);
}

int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
...rest of the code //Position C

由于简单类型通过值传递,因此该值将在内存中复制到另一个存储位置-因此:

在位置A期间,您的内存被一个int占用(值为5);在位置B期间,由于$ myVariable已复制到内存中,因此您的内存被两个整数(值为5)占用在位置C期间,您又一次被一个int(值为5)占用的内存,因为第二个已经被破坏,因为仅在执行函数时才需要它。

这还有其他一些含义:对通过值传递的变量进行的修改不会影响原始变量,例如:

function someFunction(int $parameter)
{
    $parameter = $parameter + 1;
    printOnScreen($parameter);
}

int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
printOnScreen($myVariable); //Position C

在位置A期间,您在变量$ myVariable下设置值为5。在位置B期间,将其按值传递给一个函数,该函数会将传递的值加1。但是,由于它是一个简单的类型,通过值进行传递,因此实际上它是在LOCAL变量(即变量的COPY)上操作的。因此,位置C将再次只写5(您的原始变量,因为它没有被修改)。

某些语言允许您明确表示,并使用特殊运算符(例如&)通知您要传递引用,而不是值本身。因此,让我们再次按照相同的示例进行操作,但要使用要引用的显式信息(在函数的参数中)-注意&):

function someFunction(int &$parameter)
{
    $parameter = $parameter + 1;
    printOnScreen($parameter);
}

int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
printOnScreen($myVariable); //Position C

这次的操作和内存含义将有所不同。

在位置A期间创建一个int(每个变量始终由两个元素组成:内存中的位置和一个指针,即它所在的标识符。为便于处理,我们说指针始终为一个字节)。因此,无论何时创建变量,您实际上都会创建两件事:

  • 在内存中为VALUE保留的位置(在本例中为32位,因为它是一个整数)
  • 指针(8位[1字节])
  • 现在处于位置B,该功能期望A POINTER到存储位置。这意味着它将自己在本地仅创建一个指针副本(1个字节),而不将实际的保留位置(作为新指针WILLL POINT)复制到与原始指针相同的位置。这意味着在操作该功能期间,您具有:

两个指针到内存中的一个int为int的值保留一个位置这些指针POINT都指向相同的VALUE

这意味着对值的任何修改都会同时影响两者。

因此,在同一示例中,位置C不会像我们在函数SAME POINTER下将值修改为$ myVariable一样打印出6。

对于复杂类型(对象),大多数编程环境中的默认操作是传递引用(指针)。

例如,如果您有一个课程:

class Person {
   public string $name;
}

并创建它的一个实例并设置一个值:

$john = new Person();
$john->name = "John Malkovic";

然后将其传递给函数:

function printName(Person $instanceOfPerson) 
{
   printOnScreen($instanceOfPerson);
}

就内存而言,它将再次在内存(1字节)中仅创建一个指向相同值的新POINTER。所以有这样的代码:

function printName(Person $instanceOfPerson) 
{
   printOnScreen($instanceOfPerson);
}

$john = new Person(); // position A
printName($john); // position B
...rest of the code // position C

在位置A期间,您有:1个Person(这表示指向内存中某个位置的1个指针[1个字节],该位置具有用于存储类Person的对象的大小)

在位置B期间,您有:2个指针[2个字节],但仍在内存中保留一个位置以存储类人值的对象[实例]

在位置C期间,您从位置A又有情况

我希望这可以为您澄清主题-通常有更多内容需要讨论,而我上面提到的只是一般性的解释。

© www.soinside.com 2019 - 2024. All rights reserved.