博客列表 >PHP字符串与数组常用操作总结

PHP字符串与数组常用操作总结

吾逍遥
吾逍遥原创
2020年12月01日 11:17:081951浏览

一、PHP字符串常用操作

通过老师的授课,发现JS的字符串与数组的操作与PHP的非常类似,可以相互借鉴学习,一方面是可以快速理解函数用法,另一个是相互印证相互提高了。

1、大括号{}

大括号常用的用法主要是函数块和双引号中变量引用,今天老师又讲了字符串中{}用法,类似于JS中将字符串当成数组来处理,顺其自然就随手测试了[],发现二者均可以对字符串进行访问,修改和删除。那么二者之间有区别吗?而且代码中总是对大括号{}进行了黄色波浪线提示,老师说建议使用{}是合适的吗?在网中发现,{}是PHP7.4以前的语法了,以后推荐使用[]。所以可以放弃{}这种访问字符串的方法了,这样和JS访问字符串可以统一了。

2、字符串打印输出函数

先看最基本的 printf(format,arg1,arg2...) 将输出的字符串按特定的格式输出,学过C、C++的这个函数就是熟悉得不能再熟悉了,格式符号都是%开头,如%s是格式化为字符串,%d是格式化为整数,%c是格式化为ASCII值对应的字符。arg1对应第一个格式符号,arg2对应第二个,以此类推。下面是常见的格式化字符表:

占位符 描述
%b 二进制数
%c ASCII 值对应的字符
%d 包含正负号的十进制数(负数、0、正数)
%e 使用小写的科学计数法(例如 1.2e+2)
%E 使用大写的科学计数法(例如 1.2E+2)
%u 不包含正负号的十进制数(大于等于 0)
%f 浮点数(本地设置)
%F 浮点数(非本地设置)
%g 较短的 %e 和 %f
%G 较短的 %E 和 %f
%o 八进制数
%s 字符串
%x 十六进制数(小写字母)
%X 十六进制数(大写字母)

与printf类似的就是vprintf,二者唯一区别就是参数传递方式,前者是列表式传参,多个参数以逗号隔开,后者则以数组形式传递参数。

  1. printf('Hello %s','World');
  2. echo '<hr>';
  3. vprintf('Hello %s,my age is %d',['World',28]);

与它们类似的还有sprintf和vsprintf,二都都是将格式化结果保存到字符串中返回。

  1. $sql = sprintf('SELECT * FROM `%s` LIMIT %d','users',11);
  2. echo $sql;
  3. $sql = vsprintf('SELECT * FROM `%s` LIMIT %d',['users',11]);
  4. file_put_contents('temp1.txt',$sql);

3、字符串和数组转换【重点】

字符串和数组相互转换是开发中经常用到的,它主要包括数组转字符串implode或join,反之是explode。implode和join的implode(separator,array)第一个参数是分隔符,默认是空,第二个参数就是数组了。而explodeexplode(separator,string,limit)第一个参数也是分隔符,第二个参数是字符串,第三个参数比较有意思,若大于分隔符分隔成的数组个数时无效,若是小于分隔符分隔成的数组个数时,则是将后面所有合并。

  1. // 数组转字符串
  2. echo implode(',',['html','css','vuejs','uniapp']);
  3. echo '<hr>';
  4. echo join(',',['html','css','vuejs','uniapp']);
  5. echo '<hr>';
  6. // 字符串转数组,explode第三个参数是指定数组的成员个数,若个数大于字符串个数时,则无效,若小于时,则大于的合并成一个成员
  7. print_r(explode(',','localhost,root,root,utf8,3306',4));
  8. echo '<hr>';
  9. print_r(explode(',','localhost,root,root,utf8,3306',5));
  10. echo '<hr>';

JS中字符串转数组是split,在PHP中也有str_split,它的语法是str_split(string,length),第一个参数是字符串,第二个参数是指定数组成员的长度,默认为1。中文在uft-8中是占3个字符。

  1. print_r(str_split('php中文网',3));

4、大小写转换和移除字符串两侧的空白字符

大写是strtoupper,小写是strlower,移除字符串两侧的空白字符或其他预定义字符是trim。它的语法是trim(string,charlist),其中charlist若不指定则移除以下所有字符。

  • “\0” - NULL
  • “\t” - 制表符
  • “\n” - 换行
  • “\x0B” - 垂直制表符
  • “\r” - 回车
  • “ “ - 空格

要注意的是: 转义字符只有在双引号""或定界符<<<EOF中双引号才有效,若是单引号则当成两个字符,不是转义字符,使用trim就无法移除,这点在移除处理时要注意,我在下面代码测试时就遇到这样问题。

  1. // trim是移除两侧空白字符,要注意若是转义字符时要用双引号,若是单引号则算成两个字符,不是转义字符,移除无效
  2. $str1="\n\n\nHello World !\n\n\n";
  3. $str2='\n\n\nHello World !\n\n\n';
  4. echo strlen(trim($str1)).','.strlen(trim($str2));

ltrim和rtrim是从左侧或右侧移除空白字符或其他预定义字符,使用注意事项同trim。

5、查找、取子串、比较和替换

查找子串:一般分大小写,若想不分大小写,可加上i

  1. strpos是查找子串第一次出现位置(分大小写),strpos(string,find,start),第一个是字符串,第二个是子串,第三个参数start表示起始位置,默认是从0开始。stripos也是查找第一次出现位置(不分大小写)
  2. strrpos是查找子串最后一次出现位置(分大小写),strripos也是查找最后一次出现位置(不分大小写)
  3. strstr也是查找子串第一次出现位置(分大小写),它的语法是strstr(string,search,before_search)。它和strpos不同地方有两个:一个是search为数字时,则返回匹配此数字对应的 ASCII 值的字符;另一个是before_search默认是false,如果设置为 “true”,它将返回 search 参数第一次出现之前的字符串部分。相当于查找和取子串两个功能了。它的不分大小写版本是stristr
  1. echo strpos('AbCDef123asdf','as');
  2. echo strstr('AbCDef123asdf','as',true);

取子串:substr(string,start,length),start为0时表示从字符串第一个字符开始,为正数时从在字符串的指定位置开始,若为负数则是在从字符串结尾开始的指定位置开始,最后一个字符是-1,以此类推。length为正数是返回指定长度的字符串,若没有则默认返回到结尾处。

  1. echo substr('abcdef',0),'<br>';
  2. echo substr('abcdef',2),'<br>';
  3. echo substr('abcdef',2,2),'<br>';
  4. echo substr('abcdef',-1),'<br>';
  5. echo substr('abcdeft',-2,2),'<br>';
  6. echo substr('abcdeft',-3,2),'<br>';

字符串比较: strcmp和strcasecmp,前者是分大小写,后者不分大小写。strcmp(string1,string2)。相等时返回0,大于0时string1大于string2,小于0时string1小于string2。

  • 类似还有strncmp和strncasecmp是比较前n个字符。
  • strnatcmp和strnatcasecmp:使用自然排序比较字符大小。strcmp是常规计算机字符串排序算法,它在比较10和2时,结果是10小于2,因为10中第一个1小于2,而自然排序时,它们将自然数来排序,结果是10大于2。

比较规则: 从左向右比较,相等则依次向后,若不等结束比较,返回结果。

替换:str_replace(find,replace,string,count) find是查找的值,replace是替换的值,string是被搜索的字符串,count是对替换数进行计数的变量。find和replace可以是字符串,也可以是数组,它是大小写敏感,它 返回带有替换值的字符串或数组,不分大小写的版本是str_ireplace()。它的替换规则如下:

  • 如果搜索的字符串是数组,那么它将返回数组。
  • 如果搜索的字符串是数组,那么它将对数组中的每个元素进行查找和替换。
  • 如果同时需要对数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余元素将用空字符串进行替换
  • 如果查找的是数组,而替换的是字符串,那么替代字符串将对所有查找到的值起作用。
  1. echo str_replace('转账','**','微信转账,支付宝转账',$count),'<br>';
  2. $search = ['交友','广告','直播','带货'];
  3. echo str_replace($search,['***','===','&&&','+++'],'广告代理,直播教学,免费带货,异性交友'),'<br>';

6、求字符串长度strlen和mb_strlen

求字符串的字符长度是strlen,若是有中文时,则在utf-8中中文占3个字符。若是中英文混排时想计算长度可以使用mb_strlen,它接受第二个参数,就是编码,建议是utf-8或uft8。不建议使用gb2312编码,它显示得很异常。

  1. echo mb_strlen('中国人123','utf-8'),'<br>';
  2. echo mb_strlen('中国人','gb2312'),'<br>';
  3. echo strlen('中国人123'),'<br>';

需要注意: 需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在php.ini中加载了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函数的问题。

二、PHP数组相关的操作

1、游标访问数组

  • key() -返回数组中的当前元素的键名
  • current() - 返回数组中的当前元素的值
  • next() - 将内部指针指向数组中的下一个元素,并输出
  • prev() - 将内部指针指向数组中的上一个元素,并输出
  • reset() - 将内部指针指向数组中的第一个元素,并输出
  • end() - 函数将数组内部指针指向最后一个元素

本来还想介绍each(),测试时提醒each在PHP7的以后版本推荐使用foreach代替了。
游标访问数组不限索引数组还是关联数组

  1. // 循环输出数组
  2. $people = array("Bill", "Steve", "Mark", "David");
  3. reset($people);
  4. while(current($people)){
  5. echo 'key='.key($people).',value='.current($people).'<br>';
  6. next($people);
  7. }

2、数组和变量转换

关联数组与变量转换:

  • extract():将关联数组拆分成变量,接受参数是数组变量
  • compact():将一组变量组成关联数组,接受参数是键名字符串,就是将变量名作为键名,它的值为键值,组成关联数组
  • array():将一组变量组成关联数组,组成关联数组时,要使用=>同时指明键名和键值的变量。
    注意事项: 要区分compact和array组成关联数组时接受参数的区别,前者是将变量名作为键名,键值是键名的变量;而后者则是要同时指定键名和键值,灵活度更高,当然书写更长。
  1. $config = ['type'=>'mysql','host'=>'localhost','dbname'=>'phpedu','charset'=>'utf=8'];
  2. extract($config);
  3. echo $type, ",{$host}", ",{$dbname}", ",{$charset}",'<br>';
  4. // compact的参数是变量名加引号,不是变量喔,而array组成关联数组则要指出键名
  5. print_r(compact('type','host','dbname','charset'));
  6. $arr=array('type'=>$type,'host'=>$host,'dbname'=>$dbname,'charset'=>$charset);

索引数组与变量转换:

  • list():将索引数组赋值给一些变量。若不想接受某个变量,以空占位,每个接受变量用逗号隔开。
  • array():将一组变量或值组成索引数组,常见的创建数组也是这个函数。它也可以创建关联数组。
    注意事项: array()接受参数有三种形式: 一组变量时变量值组成索引数组;一组常量时常量组成索引数组;键名=>变量或常量时组成关联数组
  1. // 索引数组
  2. // 要注意array和compact的参数区别
  3. $arr=array($type,$host,$dbname,$charset);
  4. print_r($arr);
  5. echo '<hr>';
  6. list($a,$b)=$arr;
  7. echo $a, ",{$b}",'<br>';

3、array_splice实现增改删

array_splice和JS的数组函数splice使用方法是一样的,是比较强大的函数,可实现数组的增改删除。它的语法是:array_splice(array,start,length,array2)

  • array,必需。规定数组
  • start,必需。数值,规定删除元素的开始位置。0为第一个元素,为正数,则从数组中该值指定的偏移量开始移除,为负数,则从数组末端倒数该值指定的偏移量开始移除。
  • length,可选,数值,规定被移除的元素个数,也是被返回数组的长度。为正数,则移除该数量的元素,为负数则移除从 start 到数组末端倒数 length 为止中间所有的元素,为0表示不删除,不设置则移除从 start 参数设置的位置开始直到数组末端的所有元素。
  • array2,可选,规定带有要插入原始数组中元素的数组。如果只有一个元素,则可以设置为字符串,不需要设置为数组。
  • 返回值,由被提取元素组成的数组。
  • 该函数直接操作array数组。

应用1:分割字符串: 只要有前两个参数让可以了,如array_splice($arr,3),它返回就是从索引3开始的成员,原$arr为索引0到2的成员。

应用2:增加: 要设置length为0,表示从start增加array。如array_splice($arr,3,0,['id','name']);

应用3:修改: 要设置length=array2.length,这样删除的刚好被插入的替换了,相当修改效果。如array_splice($arr,3,2,['id','name']);

应用4:删除:array_splice($arr,3,2);

  1. // $arr=array('type'=>$type,'host'=>$host,'dbname'=>$dbname,'charset'=>$charset);
  2. print_r(array_splice($arr,2,1,'woxiaoyao'));
  3. echo '<hr>';
  4. print_r($arr);

对索引数组和关联数组测试: array_splice对索引数组增删改都没问题,若是关联数组分隔和删除操作没有任何问题,增加和修改则将对应键名替换为索引键名,不建议对关联数组增改。

4、栈与队列

  • 栈:是一种特殊的线性表,是添加与删除受限的一种数据结构 LIFO,只能在固定的一端进行数据的添加与删除。
    • 尾部压入和弹出:array_push和array_pop
    • 头部压入和弹出:array_unshift和array_shift。
    • 若是压入多个时,要注意压入顺序。array_push是从左向右依次压入,而array_unshift则是从右向左从头部压入。如果难理解,可以将压入所有数据看成成一个从左向右的数组(左为头部,右为尾部),push压入时头部接上栈的尾部,它的尾部成为新栈的尾部,而unshift压入时尾部接上栈的头部,它的头部成为新栈的头部。

push

  1. $arr=[];
  2. array_push($arr,10);
  3. array_push($arr,20,30,40,50,60);
  4. array_pop($arr);
  5. array_unshift($arr,9);
  6. array_unshift($arr,1,2,3,4,5,6,7);
  7. array_shift($arr);
  8. print_r($arr);
  • 队列:FIFO queue数据结构之一,特殊的线性表,受到操作的限制,它其实就是上面组合,这里就不演示了。
    • 尾部队列:array_push和array_shift
    • 头部队列:array_unshift和array_pop

5、搜索键值或键名

  • array_key_exists(key,array) 检查某个数组中是否存在指定的键名,如果键名存在则返回 true,如果键名不存在则返回 false。
  • in_array(search,array,type) 检测键值在不在指定的数组中,存在返回true,不存在返回false。type默认为false,为true时要求值和类型都一致
  • array_search(value,array,strict) 检测键值在不在指定的数组中,存在的话返回元素值对应的键名,不存在返回false。strict默认为false,为true时要求值和类型都一致
  1. var_dump(array_key_exists(60,$arr));
  2. var_dump(in_array(60,$arr));
  3. var_dump(array_search(50,$arr));
  • array_keys()返回数组,数组成员是原数组的键名
  • array_values()返回数组中所有的值(不保留键名),键值从0到1 递增
  • 搜索实现:就是从返回的键名数组或键值数组中查找符合条件,可以使用foreach遍历数组。

6、数组合并和提取

数组合并:

  • array_combine(keys,values) 两个参数均是数组,第一个是键名,第二个是键值。键名数组和键值数组的元素个数必须相同!否则返回false。
  • array_merge(array1,array2,array3...) 把一个或多个数组合并为一个数组。
    • 参数都是索引数组时,依次拼接,将所有键值作为新的数组成员,不会出现覆盖。
    • 参数是关联数组时,同键名时,后面的键值会覆盖前面的值。
    • 若只有一个参数时,且键名是整数,则该函数将返回带有整数键名的新数组,其键名以 0 开始进行重新索引。有点类似array_values效果。
  • array_merge_recursive(array1,array2,array3...) 和array_merge使用一致,唯一区别就是关联数组时,同键名不会覆盖,而是将多个相同键名的值递归组成一个数组。
  1. $fname=array("Bill","Steve","Mark");
  2. $age=array("60","56","31");
  3. print_r(array_combine($fname,$age));
  4. echo '<br>';
  5. $a1=array("a"=>"red","b"=>"green");
  6. $a2=array("c"=>"blue","b"=>"yellow");
  7. print_r(array_merge($a1,$a2));
  8. echo '<br>';
  9. print_r(array_merge_recursive($a1,$a2));
  10. echo '<br>';

merge

二维数组某列的提取: 这个在数据查询中经常要用到,每条记录是个数组,多个记录组成二维数组,此时若想快速获取记录中某列的值组成数组,使用函数就是array_column(array,column_key,index_key);

  • array 必需。规定要使用的多维数组(记录集),常见是二维数组
  • column_key 必需。需要返回值的列。可以是索引数组的列的索引,或者是关联数组的列的键名。也可以是 NULL,此时将返回整个数组(配合 index_key 参数来重置数组键的时候,非常有用)
  • index_key 可选。用作返回数组的索引/键的列。
  • 返回值 返回数组,此数组的值为输入数组中某个单一列的值。
  1. $a = array(
  2. array( 'id' => 5698, 'first_name' => 'Bill', 'last_name' => 'Gates', ),
  3. array( 'id' => 4767, 'first_name' => 'Steve', 'last_name' => 'Jobs', ),
  4. array( 'id' => 3809, 'first_name' => 'Mark', 'last_name' => 'Zuckerberg', )
  5. );
  6. $last_names = array_column($a, 'last_name', 'id');
  7. print_r($last_names);
  8. echo '<br>';

7、数组的遍历(迭代)操作

这点和JS数组非常类似了,JS中有map、filter和reduce,PHP也有对应的array_map、array_filter和array_reduce。

  • array_reduce(array,myfunction,initial) 用回调函数迭代地将数组简化为单一的值,其中myfunction完整语法是function($prev,$cur,$index,$arr){}$prev是每步结果返回值,若是不存在initial,则第一次是它等于数组第一个成员,$cur从第二个开始遍历;而存在initial时,则第一次$prev为初始值,$cur从第一个开始遍历数组,这点要切记。它的应用包括求和、求最大值、计算重复、去重等,更详细要参考我写的关于JS的reduce总结https://www.php.cn/blog/detail/24999.html
  • 类似遍历array_map和array_filter可参考JS的map或filter,也可参考手册学习了
  1. // 求和演示,同JS一样写匿名函数
  2. $a=array(10,15,20);
  3. echo array_reduce($a,function($prev,$next){return $prev+$next;},5);
  4. // 箭头闭包只能是有一个表达式,使用关键字fn,而且PHP7.4以后再支持
  5. // echo array_reduce($a,fn($prev,$next)=>$prev+$next,5);
  • array_walk(array,myfunction,userdata...) 对数组中的每个元素应用用户自定义函数。在函数中,数组的键名和键值是参数,当用户自定义函数中的第一个参数指定为引用:&$value,就可以改变数组元素的值。
    • array_walk()函数对数组中的每个元素应用回调函数。如果成功则返回 TRUE,否则返回 FALSE
    • 典型情况下 myfunction 接受两个参数。array 参数的值作为第一个,键名作为第二个。如果提供了可选参数 userdata ,将被作为第三个参数传递给回调函数。
    • 如果 myfunction 函数需要的参数比给出的多,则每次 array_walk() 调用 myfunction 时都会产生一个 E_WARNING 级的错误。这些警告可以通过在 array_walk() 调用前加上 PHP 的错误操作符 @ 来抑制,或者用 error_reporting()。
  1. // 遍历
  2. function myfunction1($value,$key,$p)
  3. {
  4. echo "$key $p $value<br>";
  5. }
  6. $a=array("a"=>"red","b"=>"green","c"=>"blue");
  7. array_walk($a,"myfunction1","has the value");
  8. // 通过&$value修改数组的值。
  9. function myfunction2(&$value,$key)
  10. {
  11. $value="yellow";
  12. }
  13. $a=array("a"=>"red","b"=>"green","c"=>"blue");
  14. array_walk($a,$myfunction2);
  15. print_r($a);

注意事项: 回调函数作为参数时,若 直接使用匿名函数作为函数时,则形式是function($arg1,$arg2,…){};若是 先定义回调函数 ,此时传参一定要注意,可以是 函数名加引号 ,也可是 $拼接函数名,若直接是函数名则将报错,它在JS中可以是合法变量名,但在PHP中$才是变量前缀。

8、排序

  • sort(array,sortingtype)索引数组进行升序排序 ,本函数为数组中的单元赋予新的键名。原有的键名将被删除。如果成功则返回 TRUE,否则返回 FALSE。可使用rsort()进行降序排序。sortingtype规定了如何比较数组的元素/项目,可能的值
    • 0 = SORT_REGULAR - 默认。把每一项按常规顺序排列(Standard ASCII,不改变类型)
    • 1 = SORT_NUMERIC - 把每一项作为数字来处理。
    • 2 = SORT_STRING - 把每一项作为字符串来处理。
    • 3 = SORT_LOCALE_STRING - 把每一项作为字符串来处理,基于当前区域设置(可通过 setlocale() 进行更改)。
    • 4 = SORT_NATURAL - 把每一项作为字符串来处理,使用类似 natsort() 的自然排序。
    • 5 = SORT_FLAG_CASE - 可以结合(按位或)SORT_STRING 或 SORT_NATURAL 对字符串进行排序,不区分大小写。
    • 其它相关的排序: 按键名(ksort和krsort)、对关联数组按照键值(asort和arsort)、用“自然排序”算法对数组排序(natsort和natcasesort)等
  1. $arr = array('1', '10', '2', '32', '22');
  2. sort($arr);
  3. // 按字符串排序
  4. sort($arr, SORT_STRING);
  5. print_r($arr);
  • usort(array,myfunction) 通过用户自定义的比较函数对数组进行排序。myfunction定义可调用比较函数的字符串。如果第一个参数小于等于或大于第二个参数,那么比较函数必须返回一个小于等于或大于0的整数。本函数为 array 中的元素赋予新的键名。这会删除原有的键名。类似有 使用用户自定义的比较函数对数组中的键名进行排序((uksort)和使用用户自定义的比较函数对数组中的键值进行排序(uasort)
    注意自定义函数作为参数传递时要么加引号,或加$前缀。
  1. function my_sort($a, $b)
  2. {
  3. if ($a == $b) return 0;
  4. return ($a < $b) ? -1 : 1;
  5. }
  6. $a = array(4, 2, 8, 6);
  7. usort($a, "my_sort");
  8. print_r($a);
  • array_multisort(array1[,sortingorder,sortingtype][,array2,array3,....]) 对多个数组或多维数组进行排序。
    • sortingorder 可选。规定排列顺序。SORT_ASC - 默认,升序排列;SORT_DESC降序。
    • sortingtype 可选。规定排序类型。和sort函数中sortingtype取值和意义相同。
    • 返回值:如果成功则返回 TRUE,如果失败则返回 FALSE。
    • 字符串键名将被保留,但是数字键名将被重新索引,从 0 开始,并以 1 递增。
    • 可以在每个数组后设置排序顺序和排序类型参数。如果没有设置,每个数组参数会使用默认值。
    • 函数先对第一个数组进行排序,接着是其他数组,如果两个或多个值相同,它将对下一个数组进行排序。
  1. $a1=array("Dog","Dog","Cat");
  2. $a2=array("Pluto","Fido","Missy");
  3. array_multisort($a1,$a2);
  4. print_r($a1);
  5. print_r($a2);
  6. array_multisort($a1,SORT_ASC,$a2,SORT_DESC);
  7. print_r($a1);
  8. print_r($a2);
  9. $a1=array(1,30,15,7,25);
  10. $a2=array(4,30,20,41,66);
  11. $num=array_merge($a1,$a2);
  12. array_multisort($num,SORT_DESC,SORT_NUMERIC);
  13. print_r($num);

9、其它常见的操作函数

  • count(array,mode) 返回数组中元素的数目,mode默认为0,不对多维数组中的所有元素进行计数,递归地计数数组中元素的数目(计算多维数组中的所有元素)
  • array_unique(array,sortingtype) 移除数组中重复的值,sortingtype可参考sort。
  • array_sum() 返回数组中所有成员的和
  • array_product() 返回数组中所有成员相乘的结果

三、学习后的感受

PHP的字符串和数组操作和JS非常类似,但在变量处理上要比JS严格,更接近于C或C++。如 自定义函数(或称为回调函数),可以是 直接作参数传递 ,不可用箭头函数,目前PHP7.4支持箭头函数感觉很鸡肋(要关键字fn,还只能是一个表达式),在PHP中暂且忘掉它吧。另一种传递函数参数方式就是 函数名加引号或$拼接函数名,这点要注意,否则将报错。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
灭绝师太2020-12-04 14:07:091楼
期待你关于oop的作业总结~