- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
C 标准库中的strchr
函数在字符串中查找char
,但其签名采用int
作为搜索字符.在我发现的这两个实现中,实现将此 int
转换为 char
:
char *strchr(const char *s, int c) {
while (*s != (char)c)
if (!*s++)
return 0;
return (char *)s;
}
char *strchr(const char *s, int c) {
while (*s && *s != (char)c)
s++;
if (*s == c)
return (char *)s;
return NULL;
}
有人知道为什么吗?为什么不直接将 char
作为参数?
最佳答案
这纯粹是历史原因。请注意,在过去的 C 语言 (K&R C) 中,没有函数原型(prototype) 这样的东西。 strchr
那个时候的函数将被声明为
char *strchr();
并以 K&R 风格定义为
char *strchr(s, c)
char *s;
char c;
{
/* whatever */
}
然而,在 C 语言中(在 K&R C 和现代语言中)如果函数声明时没有原型(prototype)(如上所示),则在每个函数调用中传递的参数都服从所谓的默认值争论促销。在默认参数提升下,任何小于 int
的整数类型(或 unsigned int
)总是转换为 int
(或 unsigned int
)。 IE。当参数未声明时,无论何时传递 char
值作为参数,此值隐式转换为int
, 实际上 body 上通过了 int
. short
也是如此. (顺便说一句,float
在默认情况下会转换为 double
参数提升)。如果在函数内部参数实际上声明为 char
(如上面的 K&R 样式定义),它被隐式转换回 char
键入并用作 char
在函数里面。这就是它在 K&R 时代的工作方式,实际上直到今天,当函数没有原型(prototype)或使用可变参数时,这也是它在现代 C 中的工作方式。
现在,提示现代 C,它具有函数原型(prototype) 并使用现代风格的函数定义语法。为了保留和复制 strchr
的“传统”功能,如上所述,我们别无选择,只能声明strchr
的参数。作为int
并将其显式转换为 char
在函数里面。这正是您在引用的代码中观察到的。这正是 strchr
的功能在标准中有描述。
此外,如果您有一个已编译的遗留库,其中 strchr
如上所示以 K&R 样式定义,您决定为该库提供现代原型(prototype),即 strchr
的正确声明。会是
char *strchr(const char *s, int c);
因为int
是上述遗留实现期望实际接收到的 c
.用 char
声明它参数不正确。
因此,您永远不会看到期望类型为 char
的参数的“传统”标准库函数, short
或 float
.所有这些函数都将使用 int
类型的参数声明或 double
相反。
char 指针和 void *
的标准保证背后有一个非常相同的基本原理。指针共享相同的表示和对齐要求。依靠这个保证你可以申报malloc
作为void *
-返回函数,然后将此声明与标准库的预编译遗留版本一起使用,其中 malloc
实际返回char *
.
引用:C99 基本原理,5.10 版
7.1.4 Use of library functions
/--/
All library prototypes are specified in terms of the “widened” types: an argument formerly declared as char is now written as int. This ensures that most library functions can be called with or without a prototype in scope, thus maintaining backwards compatibility with pre-C89 code
关于c - 为什么 strchr 需要一个 int 来查找 char?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2394011/
我正在研究 CS50 习题集。在此函数中,我迭代一行以确保它符合某些规则:“方法 SP 请求-目标 SP HTTP-版本 CRLF”,其中 SP 是空格,CRLF 是回车/换行符。 我通过字符串的最后
我对 C 语言还很陌生,因为我只是将其作为入门类(class),并且我遇到了家庭作业问题。该程序的目标是将字符串类型的数组名称和动态选择的字符从循环传递给函数。该函数必须检查字符串中是否有所选字符,如
我正在查看 strchr() 的示例:http://www.cplusplus.com/reference/cstring/strchr/ 为什么这样可以正确找到索引?直觉上它看起来应该给出负索引:
我不明白为什么下面的 C 代码不起作用: int obtainStringLength(char* str, char c1, char c2) { char* firstOcurrence
我在以下代码中收到错误assignment makes pointer from integer without a cast,这是什么意思? char * splitter; if(splitter
这个问题在这里已经有了答案: Why does strchr take an int for the char to be found? (4 个答案) 关闭 5 年前。 尝试创建一个简单的函数来查
我尝试编写自己的 strchr() 方法实现。 现在看起来像这样: char *mystrchr(const char *s, int c) { while (*s != (char) c)
我的学期快结束了,我正在写一个函数来查找字符串中某个字符的编号,给定老师分配的函数原型(prototype)。我知道我一定是在做一些愚蠢的事情,但是这段代码要么被锁定,要么在我的函数中无限循环。 这是
我的任务是编写我自己的 strchr 版本,但它似乎不起作用。任何建议将不胜感激。这是: char *strchr (const char *s, int c) //we are looking fo
#include #include int main () { const char str[] = "http://www.tutorialspoint.com"; const ch
这行代码给我带来了段错误: g_object_set(G_OBJECT(data.udpsrc), "port", 5000, "caps", caps, NULL); 哪里 data.udpsrc
我正在使用一个用 C 编写的程序,该程序涉及比较带连字符的姓氏。例如,它可能会将 Mary Jay-Blige 与 Mary Kay-Blige 进行比较。查找连字符并将变量设置为其位置的代码是: A
我正在尝试重载 >> 运算符以读取单个(使用 enum Symbol {e,a,b,c,d}; 创建)符号: istream & operator >> (istream & is, Symbol &
我正在为 C++ 练习编写 ROT13。但是这里的这段代码返回错误并且无法编译,我不明白为什么!我在以下几行中发布了一段代码 string encode(string &x) { char a
所以我正在尝试检查一个字符串,看看它是否: 有 8 个或更多字符 至少有一个大写字母 至少有一个小写字母 至少有以下字符之一 .,?!;:_!@# 这是我的代码: #include #include
这个问题在这里已经有了答案: How does strchr implementation work (5 个答案) 关闭 7 年前。 char a[20]="this is"; cout<
我想处理字符(运算符)来操作一些数字。但关键是角色来自堆栈。当我声明 Char 类型堆栈并使用 top() 方法获取字符(运算符)时,它在 strchr 函数中不起作用。我不知道为什么。我真的很想知道
我正在深入研究 C 中的指针和字符串,但我仍然不习惯一些概念。我尝试实现 strchr() 函数的一个版本——与 string.h 中的相同——出于学习目的,但一些基本的东西仍然不正确。 这是我的代码
我有以下内容: LPSTR email // Has data in it already LPSTR index=strchr(email,'@'); 现在我想插入一个新字符串: LPSTR use
我正在为一个类(class)编写一个 C 程序,该类(class)要求我获取请求行并将其分解为后续部分。这是出于学习目的,所以我可以期待一个相当标准的请求行。 考虑到这个问题,我打算使用某种 for(
我是一名优秀的程序员,十分优秀!