资讯专栏INFORMATION COLUMN

php 的自增运算符

pumpkin9 / 2999人阅读

摘要:的一些小众的用法,很多老司机,使用时也会出问题。值值,自增后为整型数字运算正常范围的整数最大值的整数整数直接变成浮点数浮点数的计算若在精度范围内,则自增加,若不在精度范围内,则忽略。字符运算继承自的字符自增运算符。

php 的一些小众的用法,很多php老司机,使用时也会出问题。
今天就聊一聊php的自增运算符。

bool 值

对于bool值无效。

   # php -r "$a=false; $a++; var_dump($a);";
   bool(false)
null 值

null 值,自增后为整型1.

  # php -r "$a=null; $a++; var_dump($a);";
  int(1)
数字运算

正常范围的整数:

#  php -r "$a=1; $a++; var_dump($a);";
int(2)

最大值的整数,整数直接变成浮点数:

  # php -r "$a=9223372036854775807; $a++; var_dump($a);"
  float(9.2233720368548E+18)
  # php -r "$a=9223372036854775806; $a++; var_dump($a);"
  int(9223372036854775807)

浮点数的计算:

若在精度范围内,则自增加1,若不在精度范围内,则忽略。

字符运算 继承自perl的字符自增运算符。

以字符结尾

  # php -r "$a="a"; $a++; var_dump($a);";
  string(1) "b"
  # php -r "$a="z"; $a++; var_dump($a);";
  string(2) "aa"
  # php -r "$a="A"; $a++; var_dump($a);";
  string(1) "B"
  # php -r "$a="Z"; $a++; var_dump($a);";
  string(2) "AA"
  # php -r "$a="zzz"; $a++; var_dump($a);";
  string(4) "aaaa"

数字结尾

# php -r "$a="Z1"; $a++; var_dump($a);";
string(2) "Z2"
# php -r "$a="Z9"; $a++; var_dump($a);";
string(3) "AA0"

php 源码中,字符串自增运算符的算法说明:
#define LOWER_CASE 1
#define UPPER_CASE 2
#define NUMERIC 3

static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */
{
  int carry=0;  // 标识是否需要进位
  size_t pos=Z_STRLEN_P(str)-1; // 从字符串末端开始遍历
  char *s;
  zend_string *t;
  int last=0; /* Shut up the compiler warning */
  int ch;

  if (Z_STRLEN_P(str) == 0) {
      zval_ptr_dtor_str(str);
      ZVAL_INTERNED_STR(str, ZSTR_CHAR("1"));
      return;
  }

  if (!Z_REFCOUNTED_P(str)) {
      Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
      Z_TYPE_INFO_P(str) = IS_STRING_EX;
  } else if (Z_REFCOUNT_P(str) > 1) {
      Z_DELREF_P(str);
      Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
  } else {
      zend_string_forget_hash_val(Z_STR_P(str));
  }
  s = Z_STRVAL_P(str);

  do {
      ch = s[pos];
      if (ch >= "a" && ch <= "z") {
          if (ch == "z") { // 当末端是z 时,需要进位,修改为a
              s[pos] = "a";
              carry=1;
          } else {
              s[pos]++;
              carry=0;
          }
          last=LOWER_CASE;
      } else if (ch >= "A" && ch <= "Z") {
          if (ch == "Z") { // 同理,当末端是Z时,需要进位,修改为A
              s[pos] = "A";
              carry=1;
          } else {
              s[pos]++;
              carry=0;
          }
          last=UPPER_CASE;
      } else if (ch >= "0" && ch <= "9") {
          if (ch == "9") { // 当末端时9时,需要进位
              s[pos] = "0";
              carry=1;
          } else {
              s[pos]++;
              carry=0;
          }
          last = NUMERIC;
      } else {           
          carry=0;
          break;
      }
      if (carry == 0) {   // 若已经在当前位处理完成,则结束,否则一直处理到第一位
          break;
      }
  } while (pos-- > 0);

  if (carry) {  // 需要进位, 则需要多分配一个byte
      t = zend_string_alloc(Z_STRLEN_P(str)+1, 0);
      memcpy(ZSTR_VAL(t) + 1, Z_STRVAL_P(str), Z_STRLEN_P(str));
      ZSTR_VAL(t)[Z_STRLEN_P(str) + 1] = "";
      switch (last) {   //考虑上一位last 标识的是那种类型,赋值不同数据
          case NUMERIC:
              ZSTR_VAL(t)[0] = "1";
              break;
          case UPPER_CASE:
              ZSTR_VAL(t)[0] = "A";
              break;
          case LOWER_CASE:
              ZSTR_VAL(t)[0] = "a";
              break;
      }
      zend_string_free(Z_STR_P(str));
      ZVAL_NEW_STR(str, t);
  }
}
php 自增运算符 Doc

来源:https://blog.lpflpf.cn/passag...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31801.html

相关文章

  • php与唯一ID生成的相关事宜

    摘要:原文地址唯一的生成并不是一件小事想说爱它也并不是像简单来一个这样一件容易的事为什么要唯一数据库的自增在分库的时候会是一场灾难假设分两个库因为每个库都会开始从开始自增届时系统中将会出现两个为的用户自增会暴露用户量或者其他业务量自增会让有心者 [原文地址:https://blog.ti-node.com/blog...] 唯一ID的生成并不是一件小事 , 想说爱它 , 也并不是像简单来一个...

    pepperwang 评论0 收藏0
  • PHP 中「自增、自减」运算引发的奇怪问题

    摘要:在的官方手册中写道支持风格的前后递增与递减运算符。第一个注意事递增递减运算符不影响布尔值。递增递减布尔值递增递减在处理字符变量的算数运算时,沿袭了的习惯,而非的。还有一个注意事项递增递减其他字符变量则无效,原字符串没有变化。 在 PHP 的官方手册中写道: PHP 支持 C 风格的前/后递增与递减运算符。 第一个注意事:递增/递减运算符不影响布尔值。递减 NULL 值也没有...

    madthumb 评论0 收藏0
  • HashMap,HashSet,Hashtable,Vector,ArrayList 的关系

    摘要:继承的类,泛型为时,注意和其他的类型不同。因为是线程安全简单来说,是个一维数组。同样,指定和,如果中间发生变化则会抛出异常。最后,可以,然后,使用基类可以实现和的快速赋值。线程安全也是线程安全的,和一样,连函数都丧心病狂地同步了。 这么几个比较常用的但是比较容易混淆的概念同出于 java.util 包。本文仅作几个类的浅度解析。 (本文基于JDK1.7,源码来自openjdk1.7。)...

    microcosm1994 评论0 收藏0
  • volatile 关键字的深入分析及AtomicInteger的使用

    摘要:我们使用命令查看字节码会发现在虚拟机中这个自增运算使用了条指令。其实这么说也不是最严谨的,因为即使经过编译后的字节码只使用了一条指令进行运算也不代表这条指令就是原子操作。 volatile的语义:1、保证被volatile修饰的变量对所有其他的线程的可见性。2、使用volatile修饰的变量禁止指令重排优化。看代码: public class InheritThreadClass ex...

    raoyi 评论0 收藏0
  • ES规范解读之自增操作符

    摘要:对于这种疑问,我们只能求助给出官方解释后自增操作符从上的算法描述,我们能够清晰的得知,后自增操作符是先自增赋值,然后返回自增前的值,这样的一个顺序。 ES规范解读之自增操作符 原文:https://github.com/kuitos/kuitos.github.io/issues/24几个月前,不知道什么缘由跟同事讨论了起js里自增操作符(i++)的问题,现将前因后果整理出来,传于世人...

    junnplus 评论0 收藏0

发表评论

0条评论

pumpkin9

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<