我尝试编写自己的 strchr() 方法实现。
现在看起来像这样:
char *mystrchr(const char *s, int c) {
while (*s != (char) c) {
if (!*s++) {
return NULL;
}
}
return (char *)s;
}
最后一行原本是
return s;
但这不起作用,因为 s 是常量。我发现需要这个类型转换 (char *),但老实说我不知道我在那里做什么 :( 有人可以解释一下吗?
最佳答案
我相信这实际上是 C 标准对 strchr()
的定义中的一个缺陷。功能。 (我会很高兴被证明是错误的。)(回复评论,它是否真的是一个缺陷是有争议的;恕我直言,它仍然是糟糕的设计。它可以安全地使用,但它太容易了不安全地使用它。)
这是 C 标准所说的:
char *strchr(const char *s, int c);
The strchr function locates the first occurrence of c (converted to a char) in the string pointed to by s. The terminating null character is considered to be part of the string.
这意味着这个程序:
#include <stdio.h>
#include <string.h>
int main(void) {
const char *s = "hello";
char *p = strchr(s, 'l');
*p = 'L';
return 0;
}
尽管它小心地将指向字符串文字的指针定义为指向 const
的指针 char
, 具有未定义的行为,因为它修改了字符串文字。至少 gcc 不会对此发出警告,程序会因段错误而终止。
问题是 strchr()
需要 const char*
参数,这意味着它 promise 不会修改 s
的数据指向 -- 但它返回一个普通的 char*
, 这允许调用者修改相同的数据。
这是另一个例子; 它没有未定义的行为,但是它悄悄地修改了一个const
没有任何强制转换的合格对象(经过进一步思考,我相信它具有未定义的行为):
#include <stdio.h>
#include <string.h>
int main(void) {
const char s[] = "hello";
char *p = strchr(s, 'l');
*p = 'L';
printf("s = \"%s\"\n", s);
return 0;
}
这意味着,我认为(回答您的问题)strchr()
的 C 实现必须将其结果转换为 const char*
至 char*
,或做一些等效的事情。
这就是为什么 C++ 在对 C 标准库所做的少数更改之一中替换了 strchr()
。具有两个同名的重载函数:
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
C当然做不到。
替代方案是替换 strchr
通过两个函数,一个取 const char*
并返回 const char*
, 另一个服用 char*
并返回 char*
.与 C++ 不同,这两个函数必须具有不同的名称,可能是 strchr
。和 strcchr
.
(历史上,const
是在定义了 strchr()
之后添加到 C 中的。这可能是保留 strchr()
而不破坏现有代码的唯一方法。)
strchr()
不是唯一有此问题的 C 标准库函数。受影响的功能列表(我认为这个列表是完整的,但我不保证)是:
void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
char *strpbrk(const char *s1, const char *s2);
char *strrchr(const char *s, int c);
char *strstr(const char *s1, const char *s2);
(全部在 <string.h>
中声明)和:
void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
(在 <stdlib.h>
中声明)。所有这些函数都带有指向 const
的指针。指向数组初始元素的数据,并返回非 const
指向该数组元素的指针。
关于c - strchr 实现如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14367727/