1
char *strchr( const char *s, int c );

我知道 strchr 定位 string 中第一次出现的c字符s。如果c找到,则返回指向cin的指针。s否则,NULL返回一个指针。

那么为什么下面的代码输出 num 到 strlen(string) 而不是它的设计目的呢?

num=0;
   while((strchr(string,letter))!=NULL)
   {
      num++;
      string++;
   }

但是这段代码给出了正确的输出

num=0;
   while((string=strchr(string,letter))!=NULL)
   {
      num++;
      string++;
   }

我不明白为什么将返回的指针分配给另一个合格的指针甚至会有所作为。我只是测试返回值是否为 NULL 指针。

4

3 回答 3

3
  1. string是一个指针。

  2. 在第一个示例中,您只需将其向右移动一个位置,无论在何处(或是否!)找到“字母”。

  3. 在第二个例子中,每次你找到一个“字母”,你:

    a) 更新 "string" 以指向该字母,然后

    b)再次更新“字符串”以指向刚刚过去的字母。

于 2020-01-25T05:05:36.610 回答
2

让我试着用不同的方式表达,

strchr

返回指向所定位字符的指针,如果该字符未出现在字符串中,则返回空指针。

在您的代码段返回值的第一部分没有被捕获,string它之前指向的位置的下一个位置作为参数传递。简而言之,该片段正在计算直到最后一次出现的字符总数letter

const char* string = "hello"
char letter = 'l'
num=0;
while((strchr(string,letter))!=NULL)
{
    num++;
    string++;
}

像这样,

            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
              ^
              |
+-------+     |
+string +-----+
+-------+
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                  ^
                  |
+-------+         |
+string +---------+
+-------+

            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                      ^
                      |
+-------+             |
+string +-------------+
+-------+



            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                              ^
                              |
+-------+                     |
+string +---------------------+
+-------+

在第二个片段中,返回值strchr被捕获回string并在下一次迭代中将下一个地址作为参数传递,

const char* string = "hello"
char letter = 'l'
num=0;
while((string = strchr(string,letter))!=NULL)
{
    num++;
    string++;
}

像这样的东西,

+-------+     
+string +-----+
+-------+     |
              |
/*input pointer to strchr*/
              |
              v
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                      |
                      |
               /*return pointer from strchr*/
                      |
+-------+             |
+string +<------------+
+-------+     


+-------+                 
+string +-----------------+
+-------+                 |
                          |
            /*input pointer to strchr*/
                          |
                          v
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+
                          |
                          |
              /*return pointer from strchr*/
+-------+                 |
+string +<----------------+
+-------+     

+-------+                     
+string +---------------------+
+-------+                     |
                              |
                /*input pointer to strchr*/
                              |
                              v
            +---+---+---+---+---+----+
            |'h'|'e'|'l'|'l'|'o'|'/0,|
            +---+---+---+---+---+----+

                   /*NULL return from strchr*/
+-------+                     |
+string +<--------------------+
+-------+
于 2020-01-25T06:41:54.840 回答
0

第一个代码片段:

那么为什么下面的代码输出 num 到 strlen(string) 而不是它的设计目的呢?

输出可能并不strlen(string)总是,将取决于输入字符串stringletter传递给的字符strchr()。例如,如果输入是

string = "hello"
letter = 'l'

那么你将得到的输出4不等于 string 的长度"hello"。如果输入是

string = "hello"
letter = 'o'

那么你将得到的输出5等于 string 的长度"hello"。如果输入是

string = "hello"
letter = 'x'

那么你将得到的输出是0.
输出实际上取决于letter输入字符串中字符最后一次出现的位置。

原因是只有一个语句正在修改string指针的位置,并且该语句是

      string++;

它以这种方式工作 -
如果字符存在于 中stringstrchr()则将返回一个非空值,直到输入string指针指向字符串中最后一次出现字符时或之前的字符letter。一旦string指针指向字符串中最后一次出现的字符之后的一个letter字符,strchr()就会返回NULL并退出循环,并且num将等于字符串中最后一次出现的letter字符的位置。0因此,您将获得从to范围内的输出,但strlen(string)并非strlen(string)总是如此。

string = "hello", letter = 'e', num = 0
strchr(string, letter) will return not null as 'e' present in input string
num++; string++;

string = "ello", letter = 'e', num = 1
strchr(string, letter) will return not null as 'e' present in input string
num++; string++;

string = "llo", letter = 'e', num = 2
strchr(string, letter) will return null as it does not find 'e' in input string and loop exits

Output will be 2

第二个代码片段:

但是这段代码给出了正确的输出

是的,原因是strchr()返回的指针被分配给string指针。以与上面相同的示例为例,假设输入为

string = "hello"
letter = 'l'

strchr(string, letter)将指针返回到第一次出现的字符l,并将其分配给指针string。所以,现在字符串指针指向第一次出现的l. 这意味着,现在string

string = "llo"

在循环体中你正在做

string++;

这将使字符串指针指向由 . 返回的字符的下一个字符strchr()。现在string

string = "lo"
letter = `l`

并将strchr(string, letter)返回string指向当前指向的字符的指针,因为它与字符匹配letter。由于string++在循环体中,现在字符串将指向下一个字符

string = "o"
letter = `l`

并将strchr(string, letter)返回NULL并且循环将退出。num增加的次数与在 中letter找到的字符一样多string。因此,第二个片段给出了正确的输出。

于 2020-01-25T06:47:14.083 回答