C - return ((char *)&s[i]);本声明中的含义是什么?



我对这些漫游很陌生,如果这是一个愚蠢的问题,我很抱歉。但他们能告诉我这是怎么回事吗?

char    *ft_strchr(char *s, int c)
{
int i;
i = 0;
if (!s)
return (0);
if (c == '')
return ((char *)&s[ft_strlen(s)]);  // THIS LINE
while (s[i] != '')
{
if (s[i] == (char) c)
return ((char *)&s[i]); // THIS LINE
i++;
}
return (0);
}

我知道这是对该变量的强制转换,但我还没有拆开这个&在中间。然后测试这个函数,如果我把它拿出来…它崩溃。

谁来帮帮我??函数工作正常,它找到字符串中第一次出现的c,并返回带有其位置的指针。我只是想更好地理解这个应用程序。

这里&是指向操作符的指针。

例如&s[0],您将获得指向数组s的第一个元素的指针(与普通s相同)。要获得指向索引i的字符的指针,它是&s[i]


为了解释更多,你必须记住C中的字符串实际上是字符数组,以空结束符''结束。

这样的字符串通常由指向字符串第一个字符的指针表示。

例如:

char hello[] = "Hello world";  // An array of 12 characters, including terminator

当你使用hello时,它衰减为指向第一个元素的指针,即&hello[0]。打印时:

printf("%s", hello);  // Same as printf("%s", &hello[0])

它将打印整个字符串:Hello world.

但是你可以在数组中的任何地方使用指向的指针作为第一个"字符,只得到它的一小部分。例如,&hello[6]是指向数组中'w'字符的指针,基本上是上述数组中第二个单词的开始。在打印:

时使用
printf("%s", &hello[6]);

它将打印world


另一个注意事项是,在您展示的代码中,不需要(char *)强制转换。

请注意货物崇拜编程,这是一件相当糟糕的事情。

关于为什么代码以这种方式编写/函数如何工作:

至少从标准Cstrchr中要求将空终止符视为字符串的一部分。因此,如果函数的用户要求函数搜索空终止符,则必须将其作为特殊情况处理。

基本上你有4种可能的不同结果:

  • (正常使用)if (s[i] == (char) c) return ((char *)&s[i]);
    找到字符,返回指向找到的字符位置的指针。从intchar的强制转换是按照标准Cstrchr的要求进行的——它的行为也是这样。(从而允许传递像EOF这样的东西。)

  • (正常使用)return (0); }
    未找到字符,返回NULL

  • (特殊情况)if (!s) return (0);
    用户传递给函数一个空指针,返回null。这不是标准Cstrchr所要求的。因为调用者可能完全知道他们传递给函数的是一个有效的指针,像这样的错误检查只是徒劳地增加了额外的膨胀/分支。推荐的做法是将它们放在调用方端。幼稚编写的库函数经常被这样的空指针检查弄得乱七八糟。

  • (特殊情况)if (c == '') return ((char *)&s[ft_strlen(s)]);
    用户出于某种原因决定搜索空终止符。它总是在数组的索引strlen(s)处找到,因此使用strlen进行索引,然后返回指向空终止符所在位置的指针。

    还需要注意的是,调用者传递显式的零('')和调用者传递int(转换为char后变为零)之间的微妙区别。在后一种情况下,该函数将返回NULL(未找到)。这就是为什么在if (c == '')没有强制转换到char的原因。


关于编码风格的一些注意事项:

  • char*转换到char*是无意义的。
  • return (0);的括号没有意义。
  • For循环对可读性很好:for(size_t i=0; s[i] != ''; i++).

所以这个函数似乎可以重写为:

char* ft_strchr (char *s, int c)
{
if(c == '')
return &s[strlen(s)];
for(size_t i=0; s[i] != ''; i++)
{
if(s[i] == (char)c)
{
return &s[i];
}
} 
return NULL;
}

最新更新