Почему аргумент main() argv типа char * [], а не const char * []?
Когда я написал следующий код и выполнил его, компилятор сказал
устаревшее преобразование из строковой константы в char*
int main()
{
char *p;
p=new char[5];
p="how are you";
cout<< p;
return 0;
}
Это означает, что я должен был написать const char *
.
Но когда мы передаем аргументы в main
, используя char* argv[]
, мы не пишем const char* argv[]
.
Почему?
Ответы
Ответ 1
Потому что... argv[]
не const. И это, конечно, не (статический) строковый литерал, поскольку он создается во время выполнения.
Вы объявляете указатель char *
, а затем присваиваете ему строковый литерал, который по определению является константой; фактические данные находятся в постоянной памяти.
int main(int argc, char **argv) {
// Yes, I know I'm not checking anything - just a demo
argv[1][0] = 'f';
std::cout << argv[1] << std::endl;
}
Input:
g++ -o test test.cc
./test hoo
Вывод:
Foo
Это не комментарий о том, почему вы хотите изменить argv
, но это, безусловно, возможно.
Ответ 2
Исторические причины. Изменение подписи main() могло бы сломать слишком много существующего кода. И вполне возможно, что некоторые реализации позволяют вам изменить параметры на главный из вашего кода. Однако код такой:
char * p = "helllo";
* p = 'x';
всегда является незаконным, потому что вам не разрешено связываться со строковыми литералами, так что указатель должен быть const char.
Ответ 3
Вы назначаете строчную константу (const char*
) указателю на непостоянную строку (char *p
). Это позволит вам изменить строчную константу, например. выполнив p[0] = 'n'
.
В любом случае, почему бы вам не использовать std::string
? (вы, кажется, используете С++).
Ответ 4
почему требуется, чтобы char * был постоянным при назначении ему строки
Поскольку такие литералы (например, "hi"
, "hello what going on"
и т.д.) хранятся в сегменте только для чтения вашего exe. Таким образом, указатели, указывающие на них, должны указывать на постоянные символы (например, не могут их изменить).
Ответ 5
Если вы посмотрите на функции выполнения, такие как execve
, вы увидите, что они фактически не принимают const char*
в качестве параметров, но действительно требуют char*
, поэтому вы не можете использовать строковую константу для вызова main
.