原文出自:http://blog.youkuaiyun.com/zhoudaxia/article/details/4641727
8、特定区域的字符串比较和转换strcoll,strxfrm,wcscoll,wcsxfrm:strcoll使用当前的区域设置来比较字符串,strxfrm使用当前的区域设置来转换字符串。当前区域设置由LL_COLLATE宏指定。它们均调用带有区域设置参数的内部版本strcoll_l和strxfrm_l来完成实际的工作。
- /* strcoll.c:strcoll函数的实现 */
- #include <string.h>
- #ifndef STRING_TYPE
- # define STRING_TYPE char
- # define STRCOLL strcoll
- # define STRCOLL_L __strcoll_l
- # define USE_HIDDEN_DEF
- #endif
- #include "../locale/localeinfo.h"
- int
- STRCOLL (s1, s2)
- const STRING_TYPE *s1;
- const STRING_TYPE *s2;
- {
- return STRCOLL_L (s1, s2, _NL_CURRENT_LOCALE);
- }
- #ifdef USE_HIDDEN_DEF
- libc_hidden_def (STRCOLL)
- #endif
- /* strxfrm.c:strxfrm函数的实现 */
- #include <string.h>
- #include <locale/localeinfo.h>
- #ifndef STRING_TYPE
- # define STRING_TYPE char
- # define STRXFRM strxfrm
- # define STRXFRM_L __strxfrm_l
- #endif
- size_t
- STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n)
- {
- return STRXFRM_L (dest, src, n, _NL_CURRENT_LOCALE);
- }
9、错误消息报告strerror:获取错误码errnum的字符串描述,在下一次调用strerror之前这个字符串存储空间不能修改,对这个空间进行写操作会导致未定义的行为。若获取没有成功,则使用errno全局变量(或全局宏)中的错误码来获取错误消息。
- /* strerror.c:strerror函数的实现 */
- #include <libintl.h> /* 有很多内部接口 */
- #include <stdio.h>
- #include <string.h>
- #include <errno.h> /* errno中保存了程序的错误码 */
- /* 返回错误码errnum的字符串描述,在下一次调用strerror之前这个字符串存储
- 空间不能修改,对这个空间进行写操作会导致未定义的行为 */
- libc_freeres_ptr (static char *buf); /* 存放字符串描述的全局空间 */
- char *
- strerror (errnum)
- int errnum;
- {
- char *ret = __strerror_r (errnum, NULL, 0); /* 根据错误码获取错误消息 */
- int saved_errno;
- if (__builtin_expect (ret != NULL, 1)) /* 若错误消息获取成功,则返回它 */
- return ret;
- /* 否则获取errno中保存的程序错误码,用缓冲区buf来存储它的字符串描述 */
- saved_errno = errno;
- if (buf == NULL)
- buf = malloc (1024); /* buf是一个全局缓冲区 */
- __set_errno (saved_errno); /* 设置错误码 */
- if (buf == NULL)
- return _("Unknown error");
- return __strerror_r (errnum, buf, 1024); /* 获取错误码对应的错误消息并返回 */
- }
10、内存块复制memcpy,memmove,wmemcpy,wmemmove:memcpy从SRC中复制N个字节的内容到DEST中,memmove从SRC中复制N个字节的内容到DEST中,保证对重叠字符串(即SRC与DEST共用存储空间)有正确的行为。这两个函数的实现使用了memcopy.h和pagecopy.h中定义的内部接口,有按字节方式复制BYTE_COPY_FWD,按字方式复制WORD_COPY_FWD(一个字为unsigned long型)、按页方式复制PAGE_COPY_FWD_MAYBE,这些接口都是以宏的形式提供的。
- /* memcopy.h -- 在内存复制函数中使用的一些定义 */
- /* 内存函数的复制策略是:
- 1、复制字节,直到目标指针被对齐。
- 2、在展开的循环中复制字。如果源指针和目标指针不是用
- 同一种方式对齐,则使用字内存操作,但在写之前要对两个读取的字进行移位和合并
- 3、复制剩下的几个字节
- 在至少有10个寄存器用来给GCC使用的处理器上,这是非常快速的,并且能在一条指令中使用
- reg+const来访问内存 */
- #include <sys/cdefs.h>
- #include <endian.h>
- /* 在本文件中定义的宏有:
- BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy)
- BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy)
- WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy)
- WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy)
- MERGE(old_word, sh_1, new_word, sh_2)
- */
- /* 用于对齐的内存操作类型,正常时它应该是能一次装载和存储的最大类型 */
- #define op_t unsigned long int
- #define OPSIZ (sizeof(op_t))
- /* 用于未对齐的操作类型 */
- typedef unsigned char byte;
- /* 用于在寄存器中存储字节的优化类型 */
- #define reg_char char
- /* 对两个字的合并操作 */
- #if __BYTE_ORDER == __LITTLE_ENDIAN /* 小端字节序:w0在低端,w1在高端 */
- #define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
- #endif
- #if __BYTE_ORDER == __BIG_ENDIAN /* 大端字节序:w0在高端,w1在低端 */
- #define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
- #endif
- /* 向前复制:从SRC_BP中精确地复制NBTYES个字节到DST_BP中,无需对指针的对齐作任何假设 */
- #define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) /
- do /
- { /
- size_t __nbytes = (nbytes); /
- while (__nbytes > 0) /
- { /
- byte __x = ((byte *) src_bp)[0]; /
- src_bp += 1; /
- __nbytes -= 1; /
- ((byte *) dst_bp)[0] = __x; /
- dst_bp += 1; /
- } /
- } while (0)
- /* 向后复制:从SRC_END_PTR中精确地复制NBTYTES_TO_COPY个字节到DST_END_PTR中,
- 复制从指针前面的字节右端开始,并且向着更小的地址方向前进。无需对指针的对齐作任何假设 */
- #define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) /
- do /
- { /
- size_t __nbytes = (nbytes); /
- while (__nbytes > 0) /
- { /
- byte __x; /
- src_ep -= 1; /
- __x = ((byte *) src_ep)[0]; /
- dst_ep -= 1; /
- __nbytes -= 1; /
- ((byte *) dst_ep)[0] = __x; /
- } /
- } while (0)
- /* 向前复制:从SRC_BP中复制最多NBYTES个字节到DST_BP中,假设DST_BP对齐到OPSIZ的倍数。
- 如果不是所有的字节都能顺利的复制,剩下的字节数保存到NBYTES_LEFT中,否则存入0 */
- extern void _wordcopy_fwd_aligned (long int, long int, size_t) __THROW;
- extern void _wordcopy_fwd_dest_aligned (long int, long int, size_t) __THROW;
- #define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) /
- do /
- { /
- if (src_bp % OPSIZ == 0) /
- _wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); /
- else /
- _wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ); /
- src_bp += (nbytes) & -OPSIZ; /
- dst_bp += (nbytes) & -OPSIZ; /
- (nbytes_left) = (nbytes) % OPSIZ; /
- } while (0)
- /* 向后复制:从SRC_END_PTR中复制最多NBYTES_TO_COPY个字节到DST_END_PTR中,复制
- 从指针前面的字(为op_t类型)的右端开始,并且向着更小的地址方向前进。可以利用DST_END_PTR
- 已经对齐到OPSIZ的倍数。如果不是所有的字节都能顺利的复制,剩下的字节数保存到
- NBYTES_REMAINING中,否则存入0 */
- extern void _wordcopy_bwd_aligned (long int, long int, size_t) __THROW;
- extern void _wordcopy_bwd_dest_aligned (long int, long int, size_t) __THROW;
- #define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) /
- do /
- { /
- if (src_ep % OPSIZ == 0) /
- _wordcopy_bwd_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); /
- else /
- _wordcopy_bwd_dest_aligned (dst_ep, src_ep, (nbytes) / OPSIZ); /
- src_ep -= (nbytes) & -OPSIZ; /
- dst_ep -= (nbytes) & -OPSIZ; /
- (nbytes_left) = (nbytes) % OPSIZ; /
- } while (0)
- /* 进入展开循环的门槛值 */
- #define OP_T_THRES 16
- /* pagecopy.h -- 按页方式来复制的宏;用在memcpy和memmove中 */
- /* 本文件中定义的宏:
- PAGE_COPY_FWD_MAYBE (dstp, srcp, nbytes_left, nbytes)
- 由WORD_COPY_FWD以及其他的函数来调用,指针至少要是字对齐的。这将会检查虚页复制是否能
- 执行、是否应该执行、以及如果能执行的话则执行它
- 依赖于系统的pagecopy.h文件应该定义以下宏,然后包含本文件:
- PAGE_COPY_THRESHOLD
- -- 值得使用按页复制策略的最小字节数
- PAGE_SIZE
- -- 页的大小
- PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes)
- -- 执行虚页复制操作的宏。指针要对齐到PAGE_SIZE个字节的边界上
- */
- #if PAGE_COPY_THRESHOLD
- #include <assert.h>
- #define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes) /
- do /
- { /
- if ((nbytes) >= PAGE_COPY_THRESHOLD && /
- PAGE_OFFSET ((dstp) - (srcp)) == 0) /
- { /
- /* 要复制的字节数超过内核用于复制虚拟页的VM操作的门槛值,且源地址 /
- 和目标地址有同样的对齐方式 */ /
- size_t nbytes_before = PAGE_OFFSET (-(dstp)); /
- if (nbytes_before != 0) /
- { /
- /* 首先复制第一页前面的各个字 */ /
- WORD_COPY_FWD (dstp, srcp, nbytes_left, nbytes_before); /
- assert (nbytes_left == 0); /
- nbytes -= nbytes_before; /
- } /
- PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes); /
- } /
- } while (0)
- /* 页大小总是2的幂,这样我们就可以避免模除法运算 */
- #define PAGE_OFFSET(n) ((n) & (PAGE_SIZE - 1))
- #else
- #define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)
- #endif
- /* memcpy.c:memcpy函数的实现 */
- #include <string.h>
- #include <memcopy.h> /* 包含了字节复制函数BYTE_COPY_FWD和字复制函数WORD_COPY_FWD */
- #include <pagecopy.h> /* 包含内存页复制函数PAGE_COPY_FWD_MAYBE */
- #undef memcpy
- /* 从src中复制len个字节的内容到dst中 */
- void *
- memcpy (dstpp, srcpp, len)
- void *dstpp;
- const void *srcpp;
- size_t len;
- {
- unsigned long int dstp = (long int) dstpp;
- unsigned long int srcp = (long int) srcpp;
- /* 从开始复制到末尾 */
- /* 如果len足够长,使用字复制方式(一个字为long类型,一般占4个字节) */
- if (len >= OP_T_THRES)
- {
- /* 复制开头的几个字节,以使dstp对齐到字的边界 */
- len -= (-dstp) % OPSIZ;
- BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); /* 字节复制方式 */
- /* 通过虚拟地址操作,从srcp中复制尽可能多的页到dstp中 */
- PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); /* 页复制方式 */
- /* 利用对齐的dstp,采用字复制方式从srcp复制到dstp。剩余的字节数放在第三个实参中,
- 例如放在len中。这个数字可能在不同的机器有不同的值 */
- WORD_COPY_FWD (dstp, srcp, len, len);
- /* 复制剩下的尾部几个字节 */
- }
- /* 还有剩下的几个字节,使用字节内存操作 */
- BYTE_COPY_FWD (dstp, srcp, len);
- return dstpp;
- }
- libc_hidden_builtin_def (memcpy)
- /* memmove.c:memmove函数的实现 */
- #include <string.h>
- #include <memcopy.h> /* 包含了字节复制函数BYTE_COPY_FWD和字复制函数WORD_COPY_FWD */
- #include <pagecopy.h> /* 包含内存页复制函数PAGE_COPY_FWD_MAYBE */
- /* 所有这些都是为了在定义了一些东西后bcopy.c能包含本文件 */
- #ifndef a1
- #define a1 dest /* 第一个实参是dest */
- #define a1const
- #define a2 src /* 第二个实参是src */
- #define a2const const
- #undef memmove
- #endif
- #if !defined(RETURN) || !defined(rettype)
- #define RETURN(s) return (s) /* 返回dest */
- #define rettype void *
- #endif
- /* 从SRC中复制LEN个字节的内容到DEST中,保证对重叠字符串(即SRC与DEST共用存储空间)有正确的行为 */
- rettype
- memmove (a1, a2, len)
- a1const void *a1;
- a2const void *a2;
- size_t len;
- {
- unsigned long int dstp = (long int) dest;
- unsigned long int srcp = (long int) src;
- /* 这个测试使得向前复制代码一旦可能就能被使用,减少工作集 */
- if (dstp - srcp >= len) /* *Unsigned* compare! */
- {
- /* 从开始复制到末尾 */
- /* 如果len足够长,使用字复制方式(一个字为long类型,一般占4个字节) */
- if (len >= OP_T_THRES)
- {
- /* 复制开头的几个字节,以使dstp对齐到字的边界 */
- len -= (-dstp) % OPSIZ;
- BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); /* 字节复制方式 */
- /* 通过虚拟地址操作,从srcp中复制尽可能多的页到dstp中 */
- PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); /* 页复制方式 */
- /* 利用对齐的dstp,采用字复制方式从srcp复制到dstp。剩余的字节数放在第三个实参中,
- 例如放在len中。这个数字可能在不同的机器有不同的值 */
- WORD_COPY_FWD (dstp, srcp, len, len);
- /* 复制剩下的尾部几个字节 */
- }
- /* 还有剩下的几个字节,使用字节内存操作 */
- BYTE_COPY_FWD (dstp, srcp, len);
- }
- else
- {
- /* 从开始复制到末尾 */
- srcp += len;
- dstp += len;
- /* 如果len足够长,使用字复制方式(一个字为long类型,一般占4个字节) */
- if (len >= OP_T_THRES)
- {
- /* 复制开头的几个字节,以使dstp对齐到字的边界 */
- len -= dstp % OPSIZ;
- BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
- /* 利用对齐的dstp,采用字复制方式从srcp复制到dstp。剩余的字节数放在第三个实参中,
- 例如放在len中。这个数字可能在不同的机器有不同的值 */
- WORD_COPY_BWD (dstp, srcp, len, len);
- /* 复制剩下的尾部几个字节 */
- }
- /* 还有剩下的几个字节,使用字节内存操作 */
- BYTE_COPY_BWD (dstp, srcp, len);
- }
- RETURN (dest);
- }
- #ifndef memmove
- libc_hidden_builtin_def (memmove)
- #endif
解释:
(1)memcopy.h中,宏op_t为字的类型,定义为unsigned long,OPSIZ为字的大小(32位平台中为4字节)。byte为字节的类型,定义为unsigned char。MERGE函数用于合并两个字,根据不同的机器字节序,一个字在高端,一个字在低端。字节复制和字复制都有两种方式,一种是向前复制,一种是向后复制。字复制时需要指针对齐到字的边界(即指针变量中的值为OPSIZ的倍数),复制操作使用了编译器内置的_wordcopy_fwd_aligned等函数。字节复制的接口中的代码是很直接的,用一个while循环一个字节一个字节地进行拷贝即可。宏OP_T_THRES定义了能进行字复制的最低门槛值。
(2)pagecopy.h中,要复制的字节数必须达到一定的门槛值PAGE_COPY_THRESHOLD(这个值在内核中定义),才会执行按页复制。PAGE_SIZE为页的大小,在内核中定义,PAGE_OFFSET(n)用于计算页的偏移。复制时先用WORD_COPY_FWD复制前面几个字节,这样就能让源地址和目标地址按页对齐,然后就可执行页复制。
(3)有了这些宏,memcpy和memmove函数的实现就比较简单了,直接用这些接口来进行复制操作,只不过要注意进行字复制或页复制时要复制开头的几个字节,以对齐到字或页的边界。最后尾部可能还剩下几个字节,用字节复制复制它们即可。
11、内存块中的字符搜索memchr,wmemchr:在内存块S的前N个字节中搜索C的第一次出现。算法实现与strlen及strchr类似。
- /* memchr.c:memchr函数的实现 */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #undef __ptr_t
- /* 标准C++或标准C中通用指针为void*类型 */
- #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
- # define __ptr_t void *
- #else /* 传统C中通用指针为char*类型 */
- # define __ptr_t char *
- #endif
- #if defined _LIBC
- # include <string.h>
- # include <memcopy.h>
- #else
- # define reg_char char
- #endif
- #if HAVE_STDLIB_H || defined _LIBC
- # include <stdlib.h>
- #endif
- #if HAVE_LIMITS_H || defined _LIBC
- # include <limits.h>
- #endif
- #define LONG_MAX_32_BITS 2147483647
- #ifndef LONG_MAX
- #define LONG_MAX LONG_MAX_32_BITS
- #endif
- #include <sys/types.h>
- #if HAVE_BP_SYM_H || defined _LIBC
- #include <bp-sym.h>
- #else
- # define BP_SYM(sym) sym
- #endif
- #undef memchr
- #undef __memchr
- /* 在S的前N个字节中搜索C的第一次出现 */
- __ptr_t
- __memchr (s, c_in, n)
- const __ptr_t s;
- int c_in;
- size_t n;
- {
- const unsigned char *char_ptr;
- const unsigned long int *longword_ptr;
- unsigned long int longword, magic_bits, charmask;
- unsigned reg_char c;
- c = (unsigned char) c_in;
- /* 通过一次读取一个字符来处理开头的几个字符,直到char_ptr中的值对齐到一个long型字的边界,
- 即直到char_ptr中的值是long的字节数(通常为4)的倍数 */
- for (char_ptr = (const unsigned char *) s;
- n > 0 && ((unsigned long int) char_ptr
- & (sizeof (longword) - 1)) != 0;
- --n, ++char_ptr)
- if (*char_ptr == c) /* 若到达字符c处,则直接返回其指针 */
- return (__ptr_t) char_ptr;
- /* 所有这些说明性的注释使用4字节的long型字,但本算法同样也可以应用于8字节的long型字 */
- longword_ptr = (unsigned long int *) char_ptr;
- /* magic_bits的第8,16,24,31位为0,称这些位为“洞”。注意每个字节的左边有一个洞,
- 在最后的位置上也有一个洞。
- bits: 01111110 11111110 11111110 11111111
- 比特1确保进位能传播到后面的比特0上,比特0则提供洞,以便让进位陷进去 */
- if (sizeof (longword) != 4 && sizeof (longword) != 8)
- abort ();
- #if LONG_MAX <= LONG_MAX_32_BITS
- magic_bits = 0x7efefeff;
- #else
- magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
- #endif
- /* 设置一个长整型字,其每个字节都是字符c */
- charmask = c | (c << 8);
- charmask |= charmask << 16;
- #if LONG_MAX > LONG_MAX_32_BITS
- charmask |= charmask << 32;
- #endif
- /* 这里我们不使用传统的对每个字符都进行测试的循环,而是一次测试一个long型字。技巧性的部分
- 是测试当前long型字的各个字节是否为0 */
- while (n >= sizeof (longword))
- {
- /* longword中有一个字节为C,恰好等价于longword ^ charmask中有一个字节为0 */
- longword = *longword_ptr++ ^ charmask;
- /* 让longword加上魔数magic_bits */
- if ((((longword + magic_bits)
- /* 设置那些通过加法而未改变的位 */
- ^ ~longword)
- /* 只需看这些洞。如果任何的洞位都没有改变,最有可能的是有一个字节值为C或者到达终止符处(没找到C) */
- & ~magic_bits) != 0)
- {
- /* 长整型字的哪个字节为C或0?如果都不是,则是一个非预期情况,继续搜索 */
- const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
- if (cp[0] == c)
- return (__ptr_t) cp;
- if (cp[1] == c)
- return (__ptr_t) &cp[1];
- if (cp[2] == c)
- return (__ptr_t) &cp[2];
- if (cp[3] == c)
- return (__ptr_t) &cp[3];
- #if LONG_MAX > 2147483647 /* 如果long类型是8个字节,则还有4个字节需要判断 */
- if (cp[4] == c)
- return (__ptr_t) &cp[4];
- if (cp[5] == c)
- return (__ptr_t) &cp[5];
- if (cp[6] == c)
- return (__ptr_t) &cp[6];
- if (cp[7] == c)
- return (__ptr_t) &cp[7];
- #endif
- }
- n -= sizeof (longword);
- }
- /* 循环完如果还剩下几个字节,则继承搜索这剩下的几个字节 */
- char_ptr = (const unsigned char *) longword_ptr;
- while (n-- > 0)
- {
- if (*char_ptr == c)
- return (__ptr_t) char_ptr;
- else
- ++char_ptr;
- }
- return 0;
- }
- #ifdef weak_alias
- weak_alias (__memchr, BP_SYM (memchr))
- #endif
- libc_hidden_builtin_def (memchr)
12、内存块比较memcmp,wmemcmp:对两个内存块的前N个字节进行比较。比较也是使用字(unsigned long型)的比较方式,以加快搜索速度。采用的策略是先比较开头的几个字节,以使块指针对齐到字的边界,再用memcmp_common_alignment(两个内存块都对齐的情况)或memcmp_not_common_alignment(一个内存块对齐,而另一个没有对齐)按字进行快速的比较,最后对剩下的几个字节进行比较。代码就不再解剖了,涉及到大量的字操作,以及用MERGE进行字合并(这需要考虑到机器的字节序)。
13、内存块设置memset,wmemset:将内存块的前LEN个字节设置为字符C。也是采用字的方式来进行快速地写入。先设置了一个字cccc,其每个字节都是字符C。为了加快写入速度,每循环一次就写入8个cccc,最后对剩下的几个字节写入C。
- /* memset.c:memset函数的实现 */
- #include <string.h>
- #include <memcopy.h>
- #undef memset
- /* 将内存块DST的前LEN个字节设置为字符C */
- void *
- memset (dstpp, c, len)
- void *dstpp;
- int c;
- size_t len;
- {
- long int dstp = (long int) dstpp;
- if (len >= 8)
- {
- size_t xlen;
- op_t cccc;
- /* 设置一个长整型字,其每个字节都是字符c */
- cccc = (unsigned char) c;
- cccc |= cccc << 8;
- cccc |= cccc << 16;
- if (OPSIZ > 4)
- /* 移位操作分两步,以避免当long为32位时出现警告 */
- cccc |= (cccc << 16) << 16;
- /* 把dstp对齐到字的边界,开头的几个字节要设置为C,在这个对齐循环中无需
- 测试LEN是否等于0 */
- while (dstp % OPSIZ != 0)
- {
- ((byte *) dstp)[0] = c;
- dstp += 1;
- len -= 1;
- }
- /* 每次迭代中写8个op_t型的字,直到剩下不到8个字为止 */
- xlen = len / (OPSIZ * 8); /* 计算迭代次数 */
- while (xlen > 0)
- {
- ((op_t *) dstp)[0] = cccc;
- ((op_t *) dstp)[1] = cccc;
- ((op_t *) dstp)[2] = cccc;
- ((op_t *) dstp)[3] = cccc;
- ((op_t *) dstp)[4] = cccc;
- ((op_t *) dstp)[5] = cccc;
- ((op_t *) dstp)[6] = cccc;
- ((op_t *) dstp)[7] = cccc;
- dstp += 8 * OPSIZ;
- xlen -= 1;
- }
- len %= OPSIZ * 8; /* 计算剩下的字节数 */
- /* 每次迭代写1个字,直到剩下不到OPSIZ个字节为止 */
- xlen = len / OPSIZ; /* 计算迭代次数 */
- while (xlen > 0)
- {
- ((op_t *) dstp)[0] = cccc;
- dstp += OPSIZ;
- xlen -= 1;
- }
- len %= OPSIZ;
- }
- /* 写入最后剩下的几个字节 */
- while (len > 0)
- {
- ((byte *) dstp)[0] = c;
- dstp += 1;
- len -= 1;
- }
- return dstpp;
- }
- libc_hidden_builtin_def (memset)
本文详细介绍了字符串操作中的核心函数,包括strcoll与strxfrm的区域设置敏感比较与转换,strerror的错误消息获取,memcpy与memmove的高效内存块复制策略,memchr的字符搜索,memcmp的内存块比较,以及memset的内存块设置。通过分析这些函数的内部实现原理,帮助读者深入理解字符串操作的底层机制。
370

被折叠的 条评论
为什么被折叠?



