php for循环: for ($i = 'A'; $i <= 'Z'; $i++), 对于 'Z'++ 后是 'AA' 的疑问

新手上路,请多包涵
<?php
$string = '';
$j = 'Z';
for ($i = 'A'; $i <= $j; $i++) {
    $string .= $i;
}
echo strlen($string);

上面代码, $j='Y' 时输出 25; $j='Z' 时输出 1326

我有2个疑问:

  1. 为什么 Y++ 之后是 AA,这是依据的什么规则?
  2. 如果 $i 和 $j 是按 ASCII 码进行对比,为什么 $i=YZ 时就跳出循环了,而 Z 和 ZA 的 ord() 值都是 90 呢 ?

请大神帮忙解惑,谢谢 ~

阅读 2.4k
1 个回答

1. 'Z'+1 后为什么是 'AA'?

这个在PHP手册中有一段话说明

https://www.php.net/manual/en...
PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in Perl 'Z'+1 turns into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ). Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported.

简单的说,就是PHP里面的字符串加法模仿了Perl 里面的处理方式,'Z'+1就是'AA'

2. PHP的字符串比较不是纯粹的ASCII比较

对应PHP源码,会比较好理解一些

ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
{
    int retval;

    if (s1 == s2) {
        return 0;
    }
    retval = memcmp(s1, s2, MIN(len1, len2));  //比较s1和s2的前几个字节, 返回0表示相等
    if (!retval) {                                                    
        return (int)(len1 - len2);             //如果前几个字节相等则比较长度,长的大
    } else {
        return retval;
    }
}

拿 'ZZ' > 'Z' 来说, 取出两个字符串的头一个字符进行比较,发现是相等的,然后对比字符串长度,发现 'ZZ' 更长,所以 'ZZ' 大

参考:
注意PHP对字符串的递增运算
PHP字符串比较
PHP源码位置
memcmp reference

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题