Почему strrchr () возвращает `char *` вместо `const char *`?

Функция char* strrchr(const char *str, int ch) возвращает указатель (char*) в str (const char *) где последнее вхождение ch расположен.

Таким образом, мы можем написать следующий код без приведения:

#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *ptr = strrchr (CONSTSTR, '/');
*ptr++ = 'B';
*ptr++ = 'A';
*ptr++ = 'D';
}

В чем преимущество возвращения char* вместо const char* ?

РЕДАКТИРОВАТЬ:
Как Шафик Ягмур указал, что есть очень хорошие ответы на Как работает реализация strchr?

Поскольку мой код на C ++, я буду использовать <cstring> вместо <string.h>, Спасибо за ваши ответы 😉

Тем не менее Ответ Майка Сеймура лучше всего подходит вопрос. Я даже добавил более подробный ответ ниже четко сказать, как strrchr() является функцией C (перегрузка не разрешена), объявление соответствует Const а также неконстантная строки. Так как strrchr() можно вызвать с неконстантная строка, возвращаемая строка также должна быть неконстантная.

6

Решение

В Си функция должна быть такой, или заставлять пользователя использовать хитрые приведения во многих ситуациях:

  • Если это занялоconst указатель, вы не можете найти const строка;
  • Если он вернул const указатель, вы не можете использовать его для измененияconst строка.

В C ++ вы должны включить <cstring> а не устаревший C-only заголовок. Это даст вам две const-правильные перегрузки, которые не могут быть выполнены в C:

const char* strchr(const char* s, int c);
char* strchr(      char* s, int c);
6

Другие решения

Вы смотрите на устаревшую функцию из стандартной библиотеки C (<string.h>). Библиотека C ++ (<cstring>) вводит подходящее const и неconst перегрузки, поэтому вы должны использовать это везде, где это возможно.

13

const char *str средства strrchr гарантирует не изменять str,

возврате const char * средства strrchr запрещает вам изменять возвращаемое значение.

3

strrchr() от <string.h> является функцией C. Поскольку C не разрешает перегрузку функций, strrchr() был разработан, чтобы соответствовать как Const а также неконстантная строки.

char* strrchr( const char *str, int ch );

strrchr() может быть вызван с неконстантная строка, и поэтому возвращаемая строка также должна быть неконстантная как объяснено в следующих примерах.

Const контекст без ошибки компиляции:

#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"}

неконстантная контекст без ошибки компиляции:

#include <string.h>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"}

Неправильное использование также без ошибки компиляции:

#include <string.h>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
char *nonconst = strrchr (CONSTSTR, '/');
*nonconst++ = 'B';
*nonconst++ = 'A';  // drawback of the unique declaration:
*nonconst++ = 'D';  // no compilation error
}

В C ++ есть две перегруженные функции:

const char* strrchr( const char* str, int ch );  //1st
char* strrchr(       char* str, int ch );  //2nd

Const контекст использует 1-й:

#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";
const char *basename = std::strrchr (CONSTSTR, '/');
// basename points to "foobar.txt"}

неконстантная контекст использует 2-й:

#include <cstring>
int main()
{
char nonconst[] = "foo/bar/foobar.txt";
char *basename = std::strrchr (nonconst, '/');
basename[0] = 'G';
basename[3] = 'D';
// basename points to "GooDar.txt"}

Неправильное использование должно привести к ошибке компиляции:

#include <cstring>
int main()
{
const char CONSTSTR[] = "foo/bar/foobar.txt";

char *nonconst = std::strrchr (CONSTSTR, '/');
// Visual C++ v10 (2010)
// error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'

*nonconst++ = 'B';
*nonconst++ = 'A';
*nonconst++ = 'D';
}

Но этот последний пример не приводит к ошибке компиляции, используя g++ -Wall file.cpp, Протестировано с использованием версий GCC 4.1.2 (RedHat) а также 4.7.2 (MinGW).

2

Почему вы запрещаете коду изменять возвращаемую переменную? Имейте в виду, что const char * не является char * const, вам будет разрешено изменить символ в любом случае, но вы не сможете контролировать само возвращаемое значение, что не имеет особого смысла, так как вы можете изменить его и отредактировать базовую строку в другой позиции для твоя цель.

0
По вопросам рекламы [email protected]