当我在递增指针后使用 strlen() 时会发生什么?

What happens when I use strlen() after incrementing a pointer?

我已经对 strlen() 做了一些研究并有一个问题。

假设我有一个 50 元素数组和一个指向第一个元素的指针,意思是:

char A[50],*x;
gets(A);
x=&A[0];

据我了解,strlen(x) 应该会给出字符串的长度。

我的问题是,当我递增 x 时到底发生了什么?

首先,很抱歉跑题了,但是请不要使用过时的 gets() 函数。请改用fgets

在回答您的问题时,如果 x 是指向有效非空字符串的指针,则 strlen(x+1) 将始终等于 strlen(x) - 1

假设我们有这个字符串,x 指向它:

     +---+---+---+---+---+---+
  a: | H | e | l | l | o | [=10=]|
     +---+---+---+---+---+---+
       ^
       |
   +---|---+
x: |   *   |
   +-------+

x指向字符串的第一个字符。现在,strlen 所做的只是从 pointed-to 字符开始并计算字符数,直到找到终止的 '[=21=]'.

所以如果我们增加 x,现在它指向 'e'(也就是说,它指向字符串 "ello"),像这样:

     +---+---+---+---+---+---+
  a: | H | e | l | l | o | [=11=]|
     +---+---+---+---+---+---+
           ^
           |
          /
         /
        /
       |
   +---|---+
x: |   *   |
   +-------+

所以 strlen 的长度会少一个。


脚注:我想起了一个我不止一次遇到的有趣错误。当您使用 malloc 为字符串分配 space 时,您始终必须记住包含 space 作为终止 '[=21=]'。只是不要这样做:

char *p = malloc(strlen(str + 1));

我的co-worker就干过一次(不,真的,那是co-worker,不是我!),很难追查,因为太容易看有错误的代码,看不到它不是

char *p = malloc(strlen(str) + 1);

本应如此。

它给你一个更小的。 x += i 大致相当于伪代码 x = substr(x, i)。 (请注意,如果 i 的长度超过 x 的长度,就会发生不好的事情。)

它将比以前少 return。在 C 中,字符串只是指向第一个字符的内存地址的指针,所以如果你的字符串是

"ABCDEF"

如果您增加指针,而不是指向 'A' 的指针,它将指向 'B',因此新字符串是

"BCDEF"

strlen("BCDEF") 是 5 而 strlen("ABCDEF") 是 6。

您的代码:

char A[50],*x;
gets(A);
x=&A[0];

strlen(x) was supposed to give me the length of the string

what happens as I increment x? Does strlen(x) now give me the same value as before or a smaller one and if so, why does it happen?

好吧,答案比人们想象的要复杂。答案是:视情况而定!

通过声明 A[50],编译器将在堆栈上分配 50 个字节 ,这些字节未初始化为任何值。

假设 A 的内容恰好是

A[50] = { '5', '1', '2', '3', 0 /*.............*/ };

然后考虑两种情况:

a) 用户输入:<enter>

b) 用户输入:'7'<enter>

数组的内容A会有所不同

a) { 0, '1', '2', '3', 0 /*.............*/ };

b) { '7', 0, '2', '3', 0 /*.............*/ };

strlen 的结果可能会让您大吃一惊:

这是测试程序和结果:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char  A[50] = { '5', '1', '2', '3', 0 };
    char *x;

    gets(A);
    x=&A[0];

    for (int i=0; i < 5; i++)
        printf("%d: %02X\n", i, A[i]);

    printf("strlen(x)  = %zu\n", strlen(x));  
    printf("strlen(x+1)= %zu\n", strlen(x+1)); 

    return 0;
}

测试:

<enter>                                                                                                                                         
0: 00                                                                                                                                        
1: 31                                                                                                                                        
2: 32                                                                                                                                        
3: 33                                                                                                                                        
4: 00                                                                                                                                        
strlen(x)  = 0                                                                                                                               
strlen(x+1)= 3  

7<enter>                                                                                                                                            
0: 37                                                                                                                                        
1: 00                                                                                                                                        
2: 32                                                                                                                                        
3: 33                                                                                                                                        
4: 00                                                                                                                                        
strlen(x)  = 1                                                                                                                               
strlen(x+1)= 0 

如您所知,strlen 计算从起始位置到遇到第一个 '[=27=]' 的字符数。如果起始字节等于 '[=27=]'strlen(x) = 0.

对于场景 a) strlen(x)strlen(x+1) 将是 03
对于场景 b) strlen(x)strlen(x+1) 将是 10.

请不要使用 gets (Why is the gets function so dangerous that it should not be used?) 并且还要注意我以十六进制格式打印 ASCII 个字符,例如 '2' = 0x32.