首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建strchr()的简化版本

创建strchr()的简化版本
EN

Stack Overflow用户
提问于 2017-02-03 07:28:31
回答 2查看 2.5K关注 0票数 9

为了创建一个简单的函数来查找字符串中的单个字符“类似strchr() like”,我执行了以下操作:

代码语言:javascript
复制
char* findchar(char* str, char c)
{
    char* position = NULL;
    int i = 0;
    for(i = 0; str[i]!='\0';i++)
    {
        if(str[i] == c)
        {
            position = &str[i];
            break;
        }
    }
    return position;
}

到目前为止它起作用了。但是,当我查看strchr()的原型时:

代码语言:javascript
复制
char *strchr(const char *str, int c);

第二个参数是int?我很想知道..。为什么不吃个焦炭?这是否意味着我们可以使用int来存储字符,就像使用字符一样?

这就引出了第二个问题,我试图改变我的函数,接受一个int作为第二个参数.但我不确定这样做是否正确和安全:

代码语言:javascript
复制
char* findchar(char* str, int c)
{
    char* position = NULL;
    int i = 0;
    for(i = 0; str[i]!='\0';i++)
    {
        if(str[i] == c) //Specifically, is this line correct? Can we test an int against a char? 
        {
            position = &str[i];
            break;
        }
    }
    return position;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-03 08:13:14

考虑fgetc()的返回值,在unsigned charEOF范围内的值,一些负值。这是传递给strchr()的值类型。

@Roland Illig很好地解释了导致在strchr()中保留使用int ch的历史。

OP的代码失败/有以下问题。

1) char* str被视为每§7.23.1.1 3中的unsigned char *str

对于本款中的所有函数,每个字符应被解释为其类型为无符号字符。

2) i应该是size_t类型,以处理字符数组的整个范围。

3)为了strchr()的目的,将空字符视为搜索的一部分。

终止空字符被认为是字符串的一部分。

4)最好使用const,因为str没有改变。

代码语言:javascript
复制
char* findchar(const char* str, int c)     {
    const char* position = NULL;
    size_t i = 0;
    for(i = 0; ;i++) {
        if((unsigned char) str[i] == c) {
            position = &str[i];
            break;
        }
        if (str[i]=='\0') break;
    }
    return (char *) position;
}

进一步的细节

strchr函数在s指向的字符串中定位c (转换为char)的first事件。C11dr§7.23.5.2 2

所以int c就像对待char一样。这可能意味着

代码语言:javascript
复制
        if((unsigned char) str[i] == (char) c) {

然而,我认为这意味着:

代码语言:javascript
复制
        if((unsigned char) str[i] == (unsigned char)(char) c) {

或者简单的

代码语言:javascript
复制
        if((unsigned char) str[i] == (unsigned char)c) {
票数 5
EN

Stack Overflow用户

发布于 2017-02-03 08:14:05

在ANSI C89之前,函数被声明时没有原型。strchr的声明当时看起来是这样的:

代码语言:javascript
复制
char *strchr();

就这样。根本不声明任何参数。相反,有一些简单的规则:

  • 所有指针都作为参数以原样传递。
  • 小于int范围的所有整数值都转换为int
  • 所有浮点值都转换为double

所以当你给strchr打电话时,真正发生的是:

代码语言:javascript
复制
strchr(str, (int)chr);

当ANSI C89被引入时,它必须保持向后兼容性。因此,它将strchr的原型定义为:

代码语言:javascript
复制
char *strchr(const char *str, int chr);

这保留了上述示例调用的确切行为,包括对int的转换。这一点很重要,因为实现可能定义传递char参数与传递int参数不同,这在8位平台上是有意义的。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42018949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档