0

我正在尝试完全理解指针,因此我正在练习 Kenneth 的 A. Reek 书籍“C 上的指针”。我在处理第 6 章问题 1 时遇到了一个问题,上面写着:“编写一个函数,该函数将在字符串中搜索给定字符集中的任何一个。你的函数应该匹配这个原型

 char *find_char(char const *source, char const *chars);

这是我的问题:在这个 while 循环中,

while(*found_char_location != '\0'){

    if(*found_char_location == *source_pt_cpy)
    {
        return found_char_location;
        //return *source_pt_cpy;
    }//end if

如果我尝试返回指针*source_pt_cpy ,程序会给我一个分段错误错误,但如果我返回指针*found_char_location ,它会正常工作,这非常令人困惑,因为它们不具有相同的值吗?为什么一个会崩溃,而另一个不会?这是我的完整源代码。我在这里先向您的帮助表示感谢。

char *find_char(char const *source, char const *chars)
{

  if(is_null(source, chars))
  {

    return NULL;
  }//end if

  char *found_char_location;
  char *source_pt_cpy;

  found_char_location = chars;

  source_pt_cpy = source;

  while(*found_char_location != '\0'){

    if(*found_char_location == *source_pt_cpy)
    {
      return found_char_location;
      //return *source_pt_cpy;
    }//end if

    source_pt_cpy++;

    if(*source_pt_cpy == '\0')
    {
      chars++;
      source++;
      found_char_location = chars;
      source_pt_cpy = source;
    }//end if

  }//end while

  return NULL;
}//end function
4

4 回答 4

0

他们指向的东西是相同的值,但它们不在同一个位置(或者您不需要检查它们的值是否相同)。

另外,使用 *; 时要小心。*source_pt_cpy 不是指针,它是指针指向的内容,如果这是您返回的内容,那么使用该值作为指针很可能会导致段错误。

于 2013-09-05T01:46:37.150 回答
0

分段错误可能是由函数的调用者引起的,find_char但发生在函数的调用者中。请注意,在一种情况下(有效的情况),您正在返回一个指针,而调用者可能需要一个指针,因为这是正确的:

return found_char_location;

在失败的情况下,您不会返回指针,而实际上只是指针指向的字符:

return *source_pt_cpy;

因此,如果调用者将此视为指针,则可能会导致分段错误。

于 2013-09-05T01:53:22.267 回答
0

通常*chars字符串会比*source字符串短。

您应该循环遍历字符以获取中的固定位置

如果没有找到匹配,则使用source++前进到源中的下一个位置

返回到字符的开头

使用类似的东西:

chars = beginChars ;

你没有做什么。

如果您不确定发生了什么,请添加:

printf(" %c %c\n",*source,*chars);

在你循环的中间,在所有的增量和减量之后。

于 2016-04-03T21:59:40.173 回答
0

在 C 中,指针是变量的地址,仅此而已。如果要比较字符串(在 C 中翻译为以空字符结尾的字符串),最好使用strcmp()orstrncmp()函数。

像这样的声明

  char *found_char_location;
  char *source_pt_cpy;

  found_char_location = chars;

  source_pt_cpy = source;
  ...
  ...
    if(*found_char_location == *source_pt_cpy)

将比较存储在found_char_locationsource_pt_cpy指针指向的位置中的单个值,在这种情况下是一个字符,我认为这不是你想要的!

这是我维护的自制字符串库中的代码片段(如果您想玩指针,请查看它!)

/*******************************************************************
*  Return values
*      - NULL in case any of the arguments is NULL
*      - Modified string is returned 
*
*  Example Usage
*      char str[] = "'free' as in 'free speech', not as in 'free beer'";
*      printf("%s\n",zstring_replace_str(str,"free","KLMN"));
*
*  Example Output
*      'KLMN' as in 'KLMN speech', not as in 'KLMN beer'";
******************************************************************/
char *zstring_replace_str(char *str, const char *x, const char *y){
    /* to preserve the address of original pointers, tmp_ are used 
     * dummy_ptr enables us to preserve the address of tmp_str when
     * a matching string pattern is found
     * */
    char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y;
    int len_str=0, len_y=0, len_x=0;

    /* NULL pointer check */
    if ((*str && *x && *y)==0)
        return 0;

    /* calculating length of strings */
    for(; *tmp_y; ++len_y, ++tmp_y)
        ;

    for(; *tmp_str; ++len_str, ++tmp_str)
        ;

    for(; *tmp_x; ++len_x, ++tmp_x)
        ;

    /* Bounds check */
    if (len_y >= len_str)
        return str;

    /* reset tmp pointers */
    tmp_y = y;
    tmp_x = x;

    for (tmp_str = str ; *tmp_str; ++tmp_str)
        if(*tmp_str == *tmp_x) {
            /* save tmp_str */
            for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
                if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){
                    /* Reached at the end of x, we got something to replace 
                     * then!
                     * Copy y only if there is enough room for it
                     */
                    for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str)
                        *tmp_str = *tmp_y;
            }
        /* reset tmp_x */
        tmp_x = x;
        }

    return str;
}

它并不能完全按照您的意愿行事,但会让您了解如何完成任务。

在上面的代码中,for循环

for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)

做你想做的事。它从源字符串的开头(for循环的初始化)开始,然后在其逻辑检查部分比较指针tmp_x 和 dummy_ptr指向的当前字符。最后,循环递增两个指针以遍历整个字符串。

这是另一个在字符串中搜索字符而不是字符串的示例。此代码也来自zString 库

/* First if check can be omitted to improve the performance */
int zstring_search_chr(char *token,char s){
    if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}
于 2016-04-03T22:26:02.603 回答