5

我试图理解string.h函数。这是我自己的 strncpy() 实现

char * my_strncpy(char *dst, const char* src, int n)
{
    char *orig = dst;
    const char *hold = src;
    int count = 0, remain = 0;
    while(*(hold++))
            count++;
    if ( n > count )
    {
            remain = n - count;
            n = count;
    }
    while(n--)
            *dst++ = *src++;
    while(remain--)
            *dst++ = '\0';
    return orig;
}

但是在这里查看 glibc 实现时,我想知道为什么它太大而复杂。

我使用“ time ”命令测试了执行时间。这两个功能运行几乎相同。
有人可以分享有关 glibc strncpy()的知识以及我在 my_strncpy() 中缺少的内容。

4

1 回答 1

1

从现代 C 编程的角度来看,“Glibc”代码写得非常糟糕。它看起来像是针对具有 32 位对齐的特定平台的一系列过早优化。如果编译器很垃圾,那么您必须以首选对齐的单位对字节进行分组,并一次复制一个这样的单位。这就是代码看起来如此怪异的主要原因。

我猜代码很可能是很久以前写的,当时编译器在优化代码方面做得更差,而 CPU 对这些东西的硬件支持较少。它们在前缀和后缀增量之间来回切换的不一致、看似随机的方式也表明代码是为糟糕的编译器编写的。

除了过早的优化之外,代码完全是意大利面条,没有合理的解释。完全没有注释也表明代码是由糟糕的程序员编写的。

综上所述,他们以这种方式编写代码可能有也可能没有各种历史原因,但代码中有很多糟糕的编程实践,不能被视为过早的优化。

只需将该代码视为垃圾即可。


另请注意,该strncpy功能主要已过时,应避免使用。strncpy仅用于 Unix 中的古老字符串格式。它从未打算成为strcpy. 相反,该函数是危险的,并且已知会由于意外丢失空终止而导致大量错误。

的标准规范strncpy也迫使它做很多无意义的事情,比如在你已经提前知道长度时检查空终止。另外,有人可能想知道在第一个字符之后\0用 more填充剩余的字符有什么好处\0。所有这些毫无意义的要求使函数不必要地变慢。

因此,没有理由strncpy在现代 C 代码中的任何地方使用。复制已知长度的字符串的正确方法是:

memcpy(str1, str2, str2len + 1);
于 2014-06-18T07:34:57.563 回答