为了账号安全,请及时绑定邮箱和手机立即绑定

如下所示,请问主要是那几个判断是什么意思,然后如何识别,及实现字对齐的呢?

如下所示,请问主要是那几个判断是什么意思,然后如何识别,及实现字对齐的呢?

慕工程0101907 2022-04-21 16:11:20
#define lsize sizeof(word)#define lmask (lsize - 1)void *memcpy(void *dest, const void *src, size_t count){char *d = (char *)dest;const char *s = (const char *)src;int len;if(count == 0 || dest == src)return dest;if(((long)d | (long)s) & lmask) {// src and/or dest do not align on word boundaryif((((long)d ^ (long)s) & lmask) || (count < lsize))len = count; // copy the rest of the buffer with the byte moverelselen = lsize - ((long)d & lmask); // move the ptrs up to a word boundarycount -= len;for(; len > 0; len--)*d++ = *s++;}for(len = count / lsize; len > 0; len--) {*(word *)d = *(word *)s;d += lsize;s += lsize;}for(len = count & lmask; len > 0; len--)*d++ = *s++;return dest;}
查看完整描述

1 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

d,s是两个字符型指针,分别指向目标传位置和源传位置
在判断 if(((long)d | (long)s) & lmask) 中,举个具体的例子
假设是32位计算机,字长 word= 32/8 为4,即占4个byte,则lmask = 000……00011
则d与s若是对齐的,应只有第三位及更高位不同(从低位算起)则(long)d | (long)s的最低两位一定是00,例如 d = **……**10100 s = **……**00100,则(long)d | (long)s = **……**10100,此时((long)d | (long)s) & lmask = 0,即对齐的话不做if中的语句,直接从整字开始copy内存内容

否则,((long)d | (long)s) & lmask 非0,进入if语句:
if((((long)d ^ (long)s) & lmask) || (count < lsize)) 中,记住lmask = 000……00011,所以(long)d ^ (long)s指d,s最低两位若完全相同,如都为10,10或者01,01,或者11,11,(不可能同时为00,00),则((long)d ^ (long)s) & lmask)为假,此时若count>=lsize,即判断为假,则len = lsize - ((long)d & lmask);
其中((long)d & lmask)指d中后两位1的个数,为0个,1个,2个或者3个,而lsize - ((long)d & lmask)既是从d开始放,到下一个整字开始前还有几个空位,只能相应的为3个,2个,1个或者0个。随后的语句是指把先前面的0~3个零头字节复制掉,
count -= len;
for(; len > 0; len--)
*d++ = *s++;

否则,若d与s开始时就完全错开,如(10,11)或者(count < lsize),判断为真,指的是若d与s开始时就完全错开,则逐字节复制即可,此时不可整字复制,或者虽然d和s是非整字对齐,如同为01,01,但是copy内容小于lsize(比如是4),不会存在大小为4byte的整字需要复制,则从d开始从头到尾复制即可,即for(len = count / lsize; len > 0; len--)循环中的内容。

for(len = count & lmask; len > 0; len--)
*d++ = *s++;
因为lmask = 000……00011,则len = count & lmask即字符串的最后0~3个字符,所以最后的for是把整字之外剩余的零头也copy过去

讲的比较混乱,按这个思路仔细想象就行了。
Good luck!



查看完整回答
反对 回复 2022-04-24
  • 1 回答
  • 0 关注
  • 195 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号