| 赞 | 2  | 
 
| VIP | 143 | 
 
| 好人卡 | 1 | 
 
| 积分 | 1 | 
 
| 经验 | 216792 | 
 
| 最后登录 | 2019-10-10 | 
 
| 在线时间 | 24 小时 | 
 
 
 
 
 
Lv1.梦旅人 
	- 梦石
 - 0 
 
        - 星屑
 - 61 
 
        - 在线时间
 - 24 小时
 
        - 注册时间
 - 2008-8-5
 
        - 帖子
 - 1924
 
 
 
 | 
	
嗯,但指针是连续内存... 
shift 确实只是增加指针:- 00480 /*
 
 - 00481  *  call-seq:
 
 - 00482  *     array.shift   ->   obj or nil
 
 - 00483  *  
 
 - 00484  *  Returns the first element of <i>self</i> and removes it (shifting all
 
 - 00485  *  other elements down by one). Returns <code>nil</code> if the array
 
 - 00486  *  is empty.
 
 - 00487  *     
 
 - 00488  *     args = [ "-m", "-q", "filename" ]
 
 - 00489  *     args.shift   #=> "-m"
 
 - 00490  *     args         #=> ["-q", "filename"]
 
 - 00491  */
 
 - 00492 
 
 - 00493 VALUE
 
 - 00494 rb_ary_shift(ary)
 
 - 00495     VALUE ary;
 
 - 00496 {
 
 - 00497     VALUE top;
 
 - 00498 
 
 - 00499     rb_ary_modify_check(ary);
 
 - 00500     if (RARRAY(ary)->len == 0) return Qnil;
 
 - 00501     top = RARRAY(ary)->ptr[0];
 
 - 00502     ary_make_shared(ary);
 
 - 00503     RARRAY(ary)->ptr++;         /* shift ptr */
 
 - 00504     RARRAY(ary)->len--;
 
 - 00505 
 
 - 00506     return top;
 
 - 00507 }
 
  复制代码 不过就像我说的,unshift 和 pop 则会在缓冲区容量不够的时候重新分配内存:- 00509 VALUE
 
 - 00510 rb_ary_unshift(ary, item)
 
 - 00511     VALUE ary, item;
 
 - 00512 {
 
 - 00513     rb_ary_modify(ary);
 
 - 00514     if (RARRAY(ary)->len == RARRAY(ary)->aux.capa) {
 
 - 00515         long capa_inc = RARRAY(ary)->aux.capa / 2;
 
 - 00516         if (capa_inc < ARY_DEFAULT_SIZE) {
 
 - 00517             capa_inc = ARY_DEFAULT_SIZE;
 
 - 00518         }
 
 - 00519         RARRAY(ary)->aux.capa += capa_inc;
 
 - 00520         REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
 
 - 00521     }
 
 - 00522 
 
 - 00523     /* sliding items */
 
 - 00524     MEMMOVE(RARRAY(ary)->ptr + 1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
 
 - 00525 
 
 - 00526     RARRAY(ary)->len++;
 
 - 00527     RARRAY(ary)->ptr[0] = item;
 
 - 00528 
 
 - 00529     return ary;
 
 - 00530 }
 
  复制代码 这里的 REALLOC_N 就是包装了 xrealloc 的一个宏;下面还有一个的 MEMMOVE 用来把数组整体右移一位,之后空出来的第一位被设为 unshift 的参数。一般类似这种插入删除的运算,都需要 O(n),只不过由于按块转移内存,所以效率损失微乎其微 
pop 的:- 00444 VALUE
 
 - 00445 rb_ary_pop(ary)
 
 - 00446     VALUE ary;
 
 - 00447 {
 
 - 00448     rb_ary_modify_check(ary);
 
 - 00449     if (RARRAY(ary)->len == 0) return Qnil;
 
 - 00450     if (!FL_TEST(ary, ELTS_SHARED) &&
 
 - 00451             RARRAY(ary)->len * 2 < RARRAY(ary)->aux.capa &&
 
 - 00452             RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
 
 - 00453         RARRAY(ary)->aux.capa = RARRAY(ary)->len * 2;
 
 - 00454         REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
 
 - 00455     }
 
 - 00456     return RARRAY(ary)->ptr[--RARRAY(ary)->len];
 
 - 00457 }
 
  复制代码 也需要在适当时候重新分配内存,只不过这次是缩减容量 
 
to_s 那个是写过无数次的二叉树 ASCII 化 + -90度旋转... |   
 
 
 
 |