указатели на символы, массивы символов и строки в контексте вызова функции

В чем разница между строкой, которая не компилируется, и строкой, которая компилируется?
Строка, которая не компилируется, выдает это предупреждение: устаревшее преобразование из строковой константы в ‘char *’

Кроме того, я знаю, что приведение (char *) к строке, передаваемой в функцию, решит проблему, но я хотел бы понять, почему это даже необходимо, когда 2-я строка компилируется очень хорошо.

class Student {

public:

Student( char name[] ) {

}

}

int main() {

Student stud( "Kacy" ); //does not compile
char name[20] = "Kacy";   //compiles just fine

}

2

Решение

char[] подпись в параметре точно такая же, как char*, В C ++ недопустимо преобразовывать строковую константу char const* (строка "Kacy") к char* потому что строки неизменны.

Ваш второй пример компилируется, потому что name это фактический массив. Там нет изменений в char*,

В качестве решения измените ваш параметр, чтобы он содержал массив константных строк:

Student(char const name[]);

что опять же как

String(char const *name);

хотя вам лучше использовать std::string:

#include <string>

class String
{
public:
String(std::string name);
};
1

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

Строковые литералы C ++ имеют тип «массив из n const char», который распадается на const char * в вашем случае использования. Неявное преобразование в char * (то есть, отбрасывая const) вы пытаетесь устарела, поэтому есть предупреждение. Измените тип в сигнатуре конструктора или сделайте явное приведение к типу.

Из стандарта C ++:

Обычный строковый литерал имеет тип «массив N const char «и статический срок хранения

1

Строка

"Kacy"

не является массивом символов, когда компилятор создает код. Вместо этого он сохранит строку «Kacy» где-то в памяти и выдаст указатель на это место. Так что вы получаете это const char * указывая на строку «Kacy \ 0».

Если вы измените ваш конструктор на:

 Student(const char *nmae)

Вы можете использовать его как:

 Student stud("Kacy");

и как это:

 char name[20] = "Kacy";
Student stud2(name);

Обратите внимание, что компилятор сгенерирует код для заполнения массива name с персонажами в "Kacy", который отличается от просто usinv "Kacy" в качестве аргумента Student конструктор.

0