关于如何在 C 中使用 strchr 的困惑
Confusion on how to use strchr in C
char *strchr( const char *s, int c );
我知道 strchr 定位字符 c
在字符串 s
中的第一次出现。如果找到 c
,则 s
中指向 c
的指针被 returned。否则,NULL
指针被 returned。
那么为什么下面的代码将 num 输出到 strlen(string) 而不是其设计目的?
num=0;
while((strchr(string,letter))!=NULL)
{
num++;
string++;
}
但是这段代码给出了正确的输出
num=0;
while((string=strchr(string,letter))!=NULL)
{
num++;
string++;
}
我不明白为什么将 returned 的指针分配给另一个合格的指针甚至会有所不同。我只是在测试 return 值是否为 NULL 指针。
string
是一个指针。
在第一个示例中,您只需将它向右移动一个位置,而不管在哪里(或如果!)找到 "letter"。
在第二个例子中,每次你找到一个"letter",你:
a) 更新 "string" 指向字母,然后
b) 再次更新 "string" 以指向刚刚过去的字母。
让我试着换一种说法,
returns a pointer to the located character, or a null pointer if the character does not occur in the string.
在您的代码段的第一部分,return 值未被捕获,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
的 return 值被捕获回 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 +<--------------------+
+-------+
第一个代码片段:
So why does below code outputs num to strlen(string) rather than what its designed to do?
输出可能不会总是 strlen(string)
,而是取决于输入字符串 string
和传递给 strchr()
的字符 letter
。例如如果输入是
string = "hello"
letter = 'l'
那么你将得到的输出是4
,它不等于字符串的长度"hello"
。如果输入是
string = "hello"
letter = 'o'
那么你将得到的输出是5
,等于字符串的长度"hello"
。如果输入是
string = "hello"
letter = 'x'
那么你将得到的输出是0
。
输出实际上取决于字符 letter
在输入字符串中最后出现的位置。
原因是只有一条语句在修改string
指针的位置,那条语句是
string++;
它是这样工作的-
如果 string
中存在字符,则 strchr()
将 return 一个非空值,直到输入 string
指针指向最后一次出现时或之前的字符字符串中的字符 letter
。一旦 string
指针指向字符串中最后一次出现的 letter
字符之后的一个字符,strchr()
将 return NULL
并退出循环并 num
将等于 letter
字符在字符串中最后一次出现的位置。因此,您将获得从 0
到 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
第二个代码片段:
But this code gives correct output
是的,原因是 strchr()
returned 指针被分配给了 string
指针。同样拿上面的例子,假设输入是
string = "hello"
letter = 'l'
strchr(string, letter)
将 return 指向第一次出现的字符 l
的指针,并将其分配给指针 string
。所以,现在字符串指针指向第一次出现的 l
。也就是说,现在 string
是
string = "llo"
在循环体中你正在做
string++;
这将使字符串指针指向由 strchr()
编辑的 return 字符的下一个字符。现在 string
是
string = "lo"
letter = `l`
和 strchr(string, letter)
将 return 指向 string
当前指向的字符的指针,因为它与字符 letter
匹配。由于循环体中的string++
,现在字符串将指向下一个字符
string = "o"
letter = `l`
和 strchr(string, letter)
将 return NULL
并且循环将退出。 num
递增的次数与在 string
中找到的字符 letter
递增的次数相同。因此第二个片段给出了正确的输出。
char *strchr( const char *s, int c );
我知道 strchr 定位字符 c
在字符串 s
中的第一次出现。如果找到 c
,则 s
中指向 c
的指针被 returned。否则,NULL
指针被 returned。
那么为什么下面的代码将 num 输出到 strlen(string) 而不是其设计目的?
num=0;
while((strchr(string,letter))!=NULL)
{
num++;
string++;
}
但是这段代码给出了正确的输出
num=0;
while((string=strchr(string,letter))!=NULL)
{
num++;
string++;
}
我不明白为什么将 returned 的指针分配给另一个合格的指针甚至会有所不同。我只是在测试 return 值是否为 NULL 指针。
string
是一个指针。在第一个示例中,您只需将它向右移动一个位置,而不管在哪里(或如果!)找到 "letter"。
在第二个例子中,每次你找到一个"letter",你:
a) 更新 "string" 指向字母,然后
b) 再次更新 "string" 以指向刚刚过去的字母。
让我试着换一种说法,
returns a pointer to the located character, or a null pointer if the character does not occur in the string.
在您的代码段的第一部分,return 值未被捕获,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
的 return 值被捕获回 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 +<--------------------+
+-------+
第一个代码片段:
So why does below code outputs num to strlen(string) rather than what its designed to do?
输出可能不会总是 strlen(string)
,而是取决于输入字符串 string
和传递给 strchr()
的字符 letter
。例如如果输入是
string = "hello"
letter = 'l'
那么你将得到的输出是4
,它不等于字符串的长度"hello"
。如果输入是
string = "hello"
letter = 'o'
那么你将得到的输出是5
,等于字符串的长度"hello"
。如果输入是
string = "hello"
letter = 'x'
那么你将得到的输出是0
。
输出实际上取决于字符 letter
在输入字符串中最后出现的位置。
原因是只有一条语句在修改string
指针的位置,那条语句是
string++;
它是这样工作的-
如果 string
中存在字符,则 strchr()
将 return 一个非空值,直到输入 string
指针指向最后一次出现时或之前的字符字符串中的字符 letter
。一旦 string
指针指向字符串中最后一次出现的 letter
字符之后的一个字符,strchr()
将 return NULL
并退出循环并 num
将等于 letter
字符在字符串中最后一次出现的位置。因此,您将获得从 0
到 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
第二个代码片段:
But this code gives correct output
是的,原因是 strchr()
returned 指针被分配给了 string
指针。同样拿上面的例子,假设输入是
string = "hello"
letter = 'l'
strchr(string, letter)
将 return 指向第一次出现的字符 l
的指针,并将其分配给指针 string
。所以,现在字符串指针指向第一次出现的 l
。也就是说,现在 string
是
string = "llo"
在循环体中你正在做
string++;
这将使字符串指针指向由 strchr()
编辑的 return 字符的下一个字符。现在 string
是
string = "lo"
letter = `l`
和 strchr(string, letter)
将 return 指向 string
当前指向的字符的指针,因为它与字符 letter
匹配。由于循环体中的string++
,现在字符串将指向下一个字符
string = "o"
letter = `l`
和 strchr(string, letter)
将 return NULL
并且循环将退出。 num
递增的次数与在 string
中找到的字符 letter
递增的次数相同。因此第二个片段给出了正确的输出。