Я передал указатель ptr
функции, прототип которой принимает его как const
.
foo( const char *str );
Что, по моему пониманию, означает, что он не сможет изменить содержимое ptr
прошло.Как и в случае foo( const int i )
.Если foo()
пытается изменить значение i
, компилятор выдает ошибку.Но здесь я вижу, что он может легко изменить содержимое ptr
.Пожалуйста, взгляните на следующий код
foo( const char *str )
{
strcpy( str, "ABC" ) ;
printf( "%s(): %s\n" , __func__ , str ) ;
}
main()
{
char ptr[ ] = "Its just to fill the space" ;
printf( "%s(): %s\n" , __func__ , ptr ) ;
foo( const ptr ) ;
printf( "%s(): %s\n" , __func__ , ptr ) ;
return;
}
При компиляции я получаю только предупреждение, без ошибок:
warning: passing argument 1 of ‘strcpy’ discards qualifiers from pointer target type
и когда я его запускаю,Я получаю вывод вместо Segmentation Fault
main (): он просто заполняет пространствоfoo (): ABCmain (): ABC
Теперь мои вопросы 1- Что на самом деле означает const char *str
в прототипе?Означает ли это, что функция не может изменить содержимое str
?Если это так, то почему вышеприведенная программа меняет значение? 2- Как я могу убедиться, что содержимое указателя, который я передал, не будет изменено?
Из "содержимого указателя" в приведенном выше вопросе я имею в виду "содержимое"памяти, на которую указывает указатель ", а не" адрес, содержащийся в указателе ".
Редактировать
В большинстве ответов говорится, что это из-за strcpy
иC неявным преобразованием типов.Но теперь я попробовал это
foo( const char *str )
{
str = "Tim" ;
// strcpy( str, "ABC" ) ;
printf( "%s(): %s\n" , __func__ , str ) ;
}
На этот раз вывод без предупреждения от компилятора
main (): он просто заполняет пространствоfoo (): Тимmain (): просто заполнить пространство
Таким образом, очевидно, что память, на которую указывает str
, изменяется на область памяти, содержащую "Tim"
, в то время как она находится в foo()
.Хотя я не использовал strcpy()
на этот раз.Разве const
не должно это остановить?или мое понимание неверно?
Мне кажется, что даже с const
я могу изменить ссылку на память и содержание ссылки на память тоже.Тогда какой смысл?
Можете ли вы привести пример, когда complier выдаст ошибку, что я пытаюсь изменить указатель const?
Спасибо всем вам за ваше время и усилия.