【问题标题】:Why copy function arguments into local variables?为什么要将函数参数复制到局部变量中?
【发布时间】:2013-01-09 06:42:56
【问题描述】:

strlcpy.c 将参数复制到局部变量中的原因是什么:

size_t
strlcpy(char *dst, const char *src, size_t siz)
{
    char *d = dst;
    const char *s = src;
    size_t n = siz;

    /* Copy as many bytes as will fit */
    if (n != 0) {
        while (--n != 0) {
            if ((*d++ = *s++) == '\0')
                break;
        }
    }

    /* Not enough room in dst, add NUL and traverse rest of src */
    if (n == 0) {
        if (siz != 0)
            *d = '\0';      /* NUL-terminate dst */
        while (*s++)
            ;
    }

    return(s - src - 1);    /* count does not include NUL */
}

更新

我添加了正文。

【问题讨论】:

    标签: c string.h


    【解决方案1】:

    一个很常见的原因是变量在函数中被修改,然后与参数一起在表达式中使用。

    例如,该函数可能会修改变量n,然后再进行例如return siz - n;.

    【讨论】:

    • @SperanskyDanil 因为该指针也可能被修改。想想while (...) { *d++ = *s++; }
    【解决方案2】:

    其实在剩下的代码中siz和src都是需要计算一些东西的:

    /* Not enough room in dst, add NUL and traverse rest of src */
    if (n == 0) {
        if (siz != 0)
            *d = '\0';      /* NUL-terminate dst */
        while (*s++)
            ;
    }
    
    return(s - src - 1);    /* count does not include NUL */
    

    但我不明白为什么 dst 被复制到本地。也许只是为了对称。

    【讨论】:

      【解决方案3】:

      至少对于src 参数,它用于计算返回的长度。该函数的最后一行显示:

      return(s - src - 1);
      

      dst 参数而言,它实际上并不是必需的,但可能为了保持一致性。这可能无关紧要,因为一个体面的优化编译器可能不会受到这个看似额外的变量的影响。

      【讨论】:

      • “不必要的”扫描不是不必要的。 strl* 函数经过精心设计。 You can read the paper。相关部分是:“与 snprintf() 具有相同语义的返回值是更好的选择,因为它在截断检测和恢复方面为程序员提供了最大的灵活性。”
      • @Art,这很好,一开始我没有意识到它被指定返回 source 的长度而不是复制的字符数。消除了我的错误假设。
      【解决方案4】:

      对于dstd,我想,只是为了模拟。对于其他变量,它们在“代码”中使用它们的初始值和更新值。

      【讨论】:

        【解决方案5】:
        size_t
        strlcpy(char *dst, const char *src, size_t siz)
        {                     ^-------------------------->constant so must not be modified. that's why a temp variable is needed for modification.     
            char *d = dst;     <-- useless may be.
            const char *s = src;
            size_t n = siz;      
        
            /* Copy as many bytes as will fit */
            if (n != 0) {        
                while (--n != 0) {
                    if ((*d++ = *s++) == '\0')
                        break;
                }
            }
        
            /* Not enough room in dst, add NUL and traverse rest of src */
            if (n == 0) {                    <-- new n arg.
                if (siz != 0)              <---  original siz arg
                    *d = '\0';      /* NUL-terminate dst */
                while (*s++)
                    ;
            }
        
            return(s - src - 1);    /* count does not include NUL */  <-- using the original and modified values of s and src together.
        }
        

        【讨论】:

        • 嘿,请说说没用的?
        猜你喜欢
        • 2021-06-20
        • 1970-01-01
        • 2017-07-06
        • 2020-06-01
        • 1970-01-01
        • 2023-03-24
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多