搜索
首页后端开发php教程你会加法吗?我真是纠结了!求助,求解释

$a = 1;$c = $a + ($a++);var_dump($c);//3   $a = 1;$c = (++$a)+$a;var_dump($c);//4   $a = 1;$c = (++$a)+($a++);var_dump($c);//4   $a = 1;$b = &$a;$c = (++$a)+($a++);var_dump($c);//5

求解释。


回复讨论(解决方案)


1)表达式从左到右执行,所以$a这时还是1,1+2=3

2)同样是从左到右执行,++$a为2,这时$a已经自加过,所以2+2=4

3)++$a是先自加,这时$a值为2,后面的$a++是后自加,所以2+2=4

4)因为是改变引用的值,所以是2+3=5

$a = 1;
$c = $a + ($a++);
var_dump($c, $a);//3, 2
$a++ 等价于 $a = $a + 1
所以
$c = $a + ($a++);
等价于
$c = 2 + (1);
根据加法交换律
$c = $a + ($a++);
等价于
$c = ($a++) + $a; //写成这样就不难理解了吧?
等价于
$c = (1) + 2;

其他类同

1)表达式从左到右执行,所以$a这时还是1,1+2=3

2)同样是从左到右执行,++$a为2,这时$a已经自加过,所以2+2=4

3)++$a是先自加,这时$a值为2,后面的$a++是后自加,所以2+2=4

4)因为是改变引用的值,所以是2+3=5

求解释第三和第一的区别  既然是后自加 为甚么第一个不是2?

对于
$a = 1;
$c = (++$a)+($a++);
var_dump($c, $a);//4, 3

是这么理解的
(++$a) 先加 1,后取值
取出 $a 的值(2)参与运算
($a++) 先取值,后加 1
取出 $a 的值(2)参与运算
$c = (2) + (2)
虽然此时 $a 已经是 3 了
但参与计算的都是标量,没有变量
注意与 1 式的区别

xu大我还是不太理解和1式的区别  如果按照3式的分析,得到结果是2,当然这肯定是不对的  1式和3式的核心区别在哪里呢?....

$c =  $a + ($a++);
是以变量参与运算的

xu大我还是不太理解和1式的区别  如果按照3式的分析,得到结果是2,当然这肯定是不对的  1式和3式的核心区别在哪里呢?....

++$a   
表示$a先加1,再返回$a值  
相当于
$a=$a+1;
返回 $a ;  

$a++   表示先返回$a的值再给$a加1

返回 $a;
$a=$a+1;


eg:
$a=1;

echo $a++;  //先返回$a,然后给$a做加1运算   相当于  echo $a; $a=$a+1;      输出是1

echo ++$a;  //  先给$a做加1运算,再返回$a    相当于   $a=$a+1;  echo $a;  输出是2

xu大我还是不太理解和1式的区别  如果按照3式的分析,得到结果是2,当然这肯定是不对的  1式和3式的核心区别在哪里呢?.... 你也晕乎了是吧,哈哈哈

对于
$a = 1;
$c = (++$a)+($a++);
var_dump($c, $a);//4, 3

是这么理解的
(++$a) 先加 1,后取值
取出 $a 的值(2)参与运算
($a++) 先取值,后加 1
取出 $a 的值(2)参与运算
$c = (2) + (2)
虽然此时 $a 已经是 3 了
但参与计算的都是标量,没有变量
注意与 1 式的区别
综合斑竹两次的回答,第一个哈第三的解释,那就是说有括号的时候先运算括号内的,然后都转化为标量了再做计算是吧。
我还有疑惑,最后一个结果是5的是如何理解呢?

1)表达式从左到右执行,所以$a这时还是1,1+2=3

2)同样是从左到右执行,++$a为2,这时$a已经自加过,所以2+2=4

3)++$a是先自加,这时$a值为2,后面的$a++是后自加,所以2+2=4

4)因为是改变引用的值,所以是2+3=5
第一个好像就解释错了。

又无括号多没有关系,你这都是加法运算,由加法的结合律可知,无论是否有括号,括号加在哪里,都不会影响最终的结果

$a = 1;$c = (++$a)+($a++);var_dump($c);//4$a = 1;$c = ++$a + $a++;var_dump($c);//4$a = 1;$c = $a++ + ++$a;var_dump($c);//4

又无括号多没有关系,你这都是加法运算,由加法的结合律可知,无论是否有括号,括号加在哪里,都不会影响最终的结果

$a = 1;$c = (++$a)+($a++);var_dump($c);//4$a = 1;$c = ++$a + $a++;var_dump($c);//4$a = 1;$c = $a++ + ++$a;var_dump($c);//4
那请问最后一个引用后变成5的那个怎么解释。

对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5

对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5 不明白。还是有点晕。

反正执行过程中 $a++不影响$a的值,而是执行完毕才改变,类似for $i=...循环,$i在退出循环后值还要+1
++$a则是在执行过程中就改变了$a的值,执行后则不变

$b=&$a 导致了$a++做了“执行后”这个动作,所以$a++也递增了

我习惯就是这样理解的,也不知是否合适

$c =  $a + ($a++);
是以变量参与运算的


xu大我还是不太理解和1式的区别  如果按照3式的分析,得到结果是2,当然这肯定是不对的  1式和3式的核心区别在哪里呢?....

$a=1;
$c= $a+($a++);
红色的$a是以变量参与运算,但是为什么是2呢? 难道$a+($a++)先运行($a++)部分吗?  
测试过去掉$a++的括号结果还是一样,那么跟括号没有关系。那么表达式不是从左往右计算吗?

$c =  $a + ($a++);
是以变量参与运算的


xu大我还是不太理解和1式的区别  如果按照3式的分析,得到结果是2,当然这肯定是不对的  1式和3式的核心区别在哪里呢?....

估计得这么理解

function returnFirst(&$a)
{
    $return=$a;
    $a=$a+1;
    return $return;
}

function plusFirst(&$a)
{
     $a=$a+1;
     $return=$a;
     return $return;
}


$a=1;
$c=$a+returnFirst($a)  ; //$c=$a+(a++) 
var_dump($c,$a); //3,2


对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5




那如果是
$c=($a++)+($a++) 要理解成 $c=($b=$a+1)+($b=$a+1)吗?  
$c=($a++)+($a++) 返回的结果是3


对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5




那如果是
$c=($a++)+($a++) 要理解成 $c=($b=$a+1)+($b=$a+1)吗?  
$c=($a++)+($a++) 返回的结果是3 更晕了,听了你的一席话,我又觉得斑竹的解释有问题了。。。

对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5

nnd这个问题太折磨人了

当$b=&$a,好像只有在(++$a)在运算表达式的最左边才会出意外的状况。
即:
(++$a)+表达式2+表达式3......
注:表达式为($a++)或者(++$a)

并且从第三个表达式开始都有的结果都有规律可寻,也就是说只会影响到(++$a)+表达式2的结果。

假设前n个表达式的和为Sn,运算完后$a=5;
则Sn+($a++)=Sn+5;
  Sn+(++$a)=Sn+6

也就是符合把($a++) 当作 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }  把(++$a)当作 function plusFirst(&$a){ $a=$a+1; return $a;}正确推算出来


是不是php设计在这个问题上的设计缺陷哦。要是的话就很high哦,平生第一碰到这个级别的问题啊。


对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5

nnd这个问题太折磨人了

当$b=&$a,好像只有在(++$a)在运算表达式的最左边才会出意外的状况。
即:
(++$a)+表达式2+表达式3......
注:表达式为($a++)或者(++$a)

并且从第三个表达式开始都有的结果都有规律可寻,也就是说只会影响到(++$a)+表达式2的结果。

假设前n个表达式的和为Sn,运算完后$a=5;
则Sn+($a++)=Sn+5;
  Sn+(++$a)=Sn+6

也就是符合把($a++) 当作 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }  把(++$a)当作 function plusFirst(&$a){ $a=$a+1; return $a;}正确推算出来


是不是php设计在这个问题上的设计缺陷哦。要是的话就很high哦,平生第一碰到这个级别的问题啊。 你也搞晕了?


对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5

nnd这个问题太折磨人了

当$b=&$a,好像只有在(++$a)在运算表达式的最左边才会出意外的状况。
即:
(++$a)+表达式2+表达式3......
注:表达式为($a++)或者(++$a)

并且从第三个表达式开始都有的结果都有规律可寻,也就是说只会影响到(++$a)+表达式2的结果。

假设前n个表达式的和为Sn,运算完后$a=5;
则Sn+($a++)=Sn+5;
  Sn+(++$a)=Sn+6

也就是符合把($a++) 当作 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }  把(++$a)当作 function plusFirst(&$a){ $a=$a+1; return $a;}正确推算出来


是不是php设计在这个问题上的设计缺陷哦。要是的话就很high哦,平生第一碰到这个级别的问题啊。

也就是符合把($a++) 当作 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }  把(++$a)当作 function plusFirst(&$a){ $a=$a+1; return $a;}正确推算出来
这句话,说了等于没说。。你返回了半天,还是运算过后的$a的值,



对于
$a = 1;
$b = &$a;
var_dump($c);//5
由于应用的存在,情况要复杂点

由于有一个对 $b 的赋值过程,这相当于
$a = 1;
$c = (++$a)+($b = $a+1);
var_dump($c);//5

nnd这个问题太折磨人了

当$b=&$a,好像只有在(++$a)在运算表达式的最左边才会出意外的状况。
即:
(++$a)+表达式2+表达式3......
注:表达式为($a++)或者(++$a)

并且从第三个表达式开始都有的结果都有规律可寻,也就是说只会影响到(++$a)+表达式2的结果。

假设前n个表达式的和为Sn,运算完后$a=5;
则Sn+($a++)=Sn+5;
  Sn+(++$a)=Sn+6

也就是符合把($a++) 当作 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }  把(++$a)当作 function plusFirst(&$a){ $a=$a+1; return $a;}正确推算出来


是不是php设计在这个问题上的设计缺陷哦。要是的话就很high哦,平生第一碰到这个级别的问题啊。

也就是符合把($a++) 当作 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }  把(++$a)当作 function plusFirst(&$a){ $a=$a+1; return $a;}正确推算出来
这句话,说了等于没说。。你返回了半天,还是运算过后的$a的值,

我的意思是
$a = 1;
$c = $a + ($a++);
var_dump($c);//3
    
$a = 1;
$c = (++$a)+$a;
var_dump($c);//4
    
$a = 1;
$c = (++$a)+($a++);
var_dump($c);//4

第二种和第三种情况很好理解,就是单纯从左到右,并且符合对"先加后返回"或者"先返回后加"的理解
第一种情况呢,如果是从左边到右边运算的话,好像不符合对"先返回后加"的理解。但是如果是按照从右边到左边的运算顺序的话,就解释的通了。
我估计当运算式出现变量以及自加运算时,php会有个优先顺序,先运算自加的过程。
就好比
($a++)相当于 function returnFirst(&$a){ $return=$a; $a=$a+1; return $return ; }
(++$a)相当于  function plusFirst(&$a){ $a=$a+1; return $a;}

所以要是把($a++)替代成returnFirst(&$a),把(++$a)替代成plusFirst(&$a)
以上的三种情况都能解释得通。

但是,你列举了第四种情况,有变量引用
$a = 1;
$b = &$a;
$c = (++$a)+($a++);
var_dump($c);//5

注:
($a++)或者(++$a)   我称之为子表达式
若干个($a++)或者(++$a)相加  我称之为表达式

在有变量引用的时候,你用若干个($a++)和(++$a)相加时
只有当(++$a)在运算表达式的最左边才会出意外的状况(指的是出现与用函数替代不一致的结果),并且意外
只影响到(++$a)+“子表达式2”的结果。
也就是说,如果你已经知道(++$a)+“子表达式2”的结果,你还是可以用函数替代“子表达式2”之后的“子表达式”来推算结果。


综上所述,我认为($a++)可以用 returnFirst($a)来理解,(++$a)可以用 plusFirst($a)来理解。
第四种意外情况,可能是自加和引用同时出现时没有考虑到的php设计缺陷。当然这只是我猜测

C/C++和php的前加加后加加结果还不一样,php是通过zend内核来操作变量在内存中的分配,相比来说c/c++的还更好理解。

C/C++和php的前加加后加加结果还不一样,php是通过zend内核来操作变量在内存中的分配,相比来说c/c++的还更好理解。 请帮忙我们捋一捋吧。。。好理解的话。

看了楼上的各种解释,心里不免有很多疑问,总觉得每一种解释都很牵强。我觉得应该把它看作是php的一个bug,而不是一个特性。
用vld工具可以看到php的运算过程
第一步 ++$a 得出的表达式值我们用 $1表示。
第二步 $a++ 得出的表达式值我们用 $2表示。
第三步 计算 $1 + $2。
这个过程应该是没有异议的。

关键是 ++$a 的结果是什么?$a++的结果又是什么?
对于++$a, php用递增后的$a来表示表达式的结果, 也就是$1与$a在php的底层是指向同一个zval的。
而$a++呢, php先把$a复制出一份作为$2, 然后把$a加1, 也就是从此之后 $2与$a 不会再有半毛钱关系。

问题的关键就在 第二步的$a++改变了$a的值,而且由于$a是引用类型,此操作将不会在$a的副本上进行,这就会同步修改第一步的表达式值$1(因为$a和$1本来就是同一个东西)。

有兴趣的同学可以看下php的源码,在zend_vm_def.h中搜索PRE_INC即可找到 前置++ 的底层实现。 PRE_DEC也就是 前置-- 运算也有同样的问题。
明白了这些你就很容易构造出更多不符合预期结果的表达式

大家可以试一试
$a = 2;
$b = &$a;

echo ++$a + $a++;
echo ++$a + $a*=2;

echo --$a + $a--;
echo --$a - $a--;

echo ++$a + $a--;

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
简单地说明PHP会话的概念。简单地说明PHP会话的概念。Apr 26, 2025 am 12:09 AM

phpsessionstrackuserdataacrossmultiplepagerequestsusingauniqueIdStoredInacookie.here'showtomanageThemeffectionaly:1)startAsessionWithSessionwwithSession_start()和stordoredAtain $ _session.2)

您如何循环中存储在PHP会话中的所有值?您如何循环中存储在PHP会话中的所有值?Apr 26, 2025 am 12:06 AM

在PHP中,遍历会话数据可以通过以下步骤实现:1.使用session_start()启动会话。2.通过foreach循环遍历$_SESSION数组中的所有键值对。3.处理复杂数据结构时,使用is_array()或is_object()函数,并用print_r()输出详细信息。4.优化遍历时,可采用分页处理,避免一次性处理大量数据。这将帮助你在实际项目中更有效地管理和使用PHP会话数据。

说明如何使用会话进行用户身份验证。说明如何使用会话进行用户身份验证。Apr 26, 2025 am 12:04 AM

会话通过服务器端的状态管理机制实现用户认证。1)会话创建并生成唯一ID,2)ID通过cookies传递,3)服务器存储并通过ID访问会话数据,4)实现用户认证和状态管理,提升应用安全性和用户体验。

举一个如何在PHP会话中存储用户名的示例。举一个如何在PHP会话中存储用户名的示例。Apr 26, 2025 am 12:03 AM

Tostoreauser'snameinaPHPsession,startthesessionwithsession_start(),thenassignthenameto$_SESSION['username'].1)Usesession_start()toinitializethesession.2)Assigntheuser'snameto$_SESSION['username'].Thisallowsyoutoaccessthenameacrossmultiplepages,enhanc

哪些常见问题会导致PHP会话失败?哪些常见问题会导致PHP会话失败?Apr 25, 2025 am 12:16 AM

PHPSession失效的原因包括配置错误、Cookie问题和Session过期。1.配置错误:检查并设置正确的session.save_path。2.Cookie问题:确保Cookie设置正确。3.Session过期:调整session.gc_maxlifetime值以延长会话时间。

您如何在PHP中调试与会话相关的问题?您如何在PHP中调试与会话相关的问题?Apr 25, 2025 am 12:12 AM

在PHP中调试会话问题的方法包括:1.检查会话是否正确启动;2.验证会话ID的传递;3.检查会话数据的存储和读取;4.查看服务器配置。通过输出会话ID和数据、查看会话文件内容等方法,可以有效诊断和解决会话相关的问题。

如果session_start()被多次调用会发生什么?如果session_start()被多次调用会发生什么?Apr 25, 2025 am 12:06 AM

多次调用session_start()会导致警告信息和可能的数据覆盖。1)PHP会发出警告,提示session已启动。2)可能导致session数据意外覆盖。3)使用session_status()检查session状态,避免重复调用。

您如何在PHP中配置会话寿命?您如何在PHP中配置会话寿命?Apr 25, 2025 am 12:05 AM

在PHP中配置会话生命周期可以通过设置session.gc_maxlifetime和session.cookie_lifetime来实现。1)session.gc_maxlifetime控制服务器端会话数据的存活时间,2)session.cookie_lifetime控制客户端cookie的生命周期,设置为0时cookie在浏览器关闭时过期。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器