繁体   English   中英

为什么这个函数返回字符串的正确长度? (增加一个字符指针)

[英]Why does this function return the correct length of a string? (Incrementing a char pointer)

这是一个计算字符串中字符数的函数:

int str_len(const char* s) {
    int i = 0;
    while(*(s++)) {
        i++;
    }
    return i;
}

为什么这会返回正确的长度?

假设我用一个简单的字符串"a"调用这个函数。 然后s在 while 循环中递增,因此si的值都为 0。

的值s++是原始值s ,增量之前,增量发生在下一个顺序点之前一个不确定的时间。

因此*s++*(s++)是等价的:它们都取消引用s的原始值。 另一个等价的表达式是*(0, s++)并且,不适合胆小的人,这是这样的: 0[s++]

但是请注意,您的函数应为i及其返回类型使用size_t类型:

size_t str_len(const char *s) {
    size_t i = 0;
    while (*s++) {
        i++;
    }
    /* s points after the null terminator */
    return i;
}

这是一个可能更高效的版本,每个循环有一个增量:

size_t str_len(const char *s) {
    const char *s0 = s;
    while (*s++) {
        /* nothing */
    }
    return s - 1 - s0;
}

对于那些对第二段中奇怪的表达感到疑惑的人:

  • 0, s++是逗号运算符的一个实例,它评估其左侧部分,然后评估构成其值的右侧部分。 因此(0, s++)等价于(s++)

  • 0[s++]等价于(s++)[0]*(0 + s++)*(s++ + 0) ,它们简化为*(s++) 转置[]表达式中的指针和索引表达式不是很常见也不是特别有用,但符合 C 标准。

假设我用一个简单的字符串“a”来调用这个函数。 然后 s 在 while 循环中递增,因此 s 的值为 0,i 也为 0。

在这个例子中, s指向'a'"a" 然后它递增, i也递增。 现在s指向空终止符,而i1 因此,在循环的下一次运行中, *(s++)'\\0' (即0 ),因此循环结束,并返回i的当前值(即1 )。

通常,循环对字符串中的每个字符运行一次,然后在空终止符处停止,这就是它计算字符的方式。

这完全有道理:

int str_len(const char* s) {
    int i = 0;
    while(*(s++)) { //<-- increments the pointer to char till the end of the string
                    //till it finds '\0', that is, if s = "a" then s is 'a'
                    // followed by '\0' so it increments one time
        i++; //counts the number of times the pointer moves forward
    }
    return i;
}

“但是s在括号中。这就是为什么我认为它会先递增”

这正是指针递增而不是字符递增的原因,假设您有(*s)++ ,在这种情况下,字符将递增而不是指针递增。 取消引用意味着您现在正在使用指针引用的值,而不是指针本身。

由于两个运算符具有相同的优先级但从右到左关联,您甚至可以简单地使用不带括号的*s++来增加指针。

后递增运算符将操作数的值增加 1,但表达式的值是递增操作之前操作数的原始值。

假设传递给str_len()的参数是"a" str_len() ,指针s指向字符串"a"第一个字符。 while循环中:

while(*(s++)) {
.....
.....

尽管s将递增,但表达式s的值将是指向它在递增之前指向的字符'a'指针,即指向第一个字符'a'指针。 当指针s被取消引用时,它将给出字符'a' 在下一次迭代中, s指针将指向下一个字符,即空字符\\0 s被取消引用时,它将给出0并且循环将退出。 请注意, s现在将指向字符串"a"的空字符之后的一个元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM