2009-06-05 6 views
1
int main() 

{ 
    char *second= new char("hello"); 
    char *first="hi"; 
    char third[]="new"; 
} 

Я новичок в C++ и не понимаю, как работает char, почему первый дает ошибку компилятора и каковы различия в этих трех способах объявления, о силе и преимуществах объявив его определенным образом.динамически выделенный char

Благодаря

Хм, а кто-то упоминает о том, что вторая форма предназначена только для чтения, поэтому я мог изменить его. предположим, что у меня есть код ниже

int main() 

{ 
    char *second= new char("hello"); 
    char *first="hi"; 
    char third[]="new"; 
    first="world"; 
} 

Код, как указано выше, все равно будет выполнен, почему это так? , то какая форма лучше, если я хочу прочитать ввод, но не знаю размер строки?

ответ

12

Знайте, что

"abc" 

выделяет статическую память где-то, который длится всю жизнь программы. Вы не можете записать это хранилище, поэтому C++ дает ему тип char const[N] (массив из N постоянных символов). Теперь, следующий делает точку указателя на это хранилище

char *first = "hi"; 

Так что роняет const, что способ инициализации указателя является устаревшим. То, что он вообще работает, - это просто поддерживать обратную совместимость с C, где строковый литерал не имеет типа const (но он все еще доступен для чтения). Предпочитают следующие вместо

char const *first = "hi"; 

В Контрастом, последний, как вы показали, копирует строку содержимого литерала в массив, который будет доступен для записи, и быть такого размера, строковый литерал просто вписывается в него.

char third[] = "new"; 

Если вы сделаете это в функции, то, как и все переменные, этот массив будет очищен, когда вы покинете область действия. Теперь, первый способ, которым вы показали, отличается. Он создает символ динамически. Вы могли бы инициализировать его, как этот

char *c = new char('A'); 

И так как это происходит динамически, вы должны сообщить компилятору явно, когда он должен освободить память

delete c; 

Но вы не можете инициализировать символ с строкового литерала , То, что вы, вероятно, имели в виду, создает динамическое хранилище, инициализированное строковым литералом. Это невозможно, используя new. Единственная форма инициализации динамического массива - обнулить его, но вы не можете напрямую инициализировать содержимое строкового литерала или другого массива. Для этой формы использования new редко приходится делать это напрямую. Если вы хотите, вы можете сделать это путем создания динамического массива нужного размера, а затем скопировать байты из строки литералов в этот буфер

char *c = new char[sizeof "hello"]; // sizeof "hello" will give 6 
std::strcpy(c, "hello"); 

delete[] c; // delete[] is for deleting dynamic arrays 

Помните, что это довольно низкий уровень, и я рекомендую вам использование строк

std::string s = "hello"; // s.size() gives you its size 

Он полностью управляет памятью для вас. Также доступно конкатенация, индексирование и что-то подобное.

+1

+1. Единственное, что я хотел бы добавить, это немного о char vs. char *. Читая вопрос о OP, кажется, что он путается в строках char/string */c. – kbyrd

+0

Спасибо. добавлен некоторые другие вещи –

+0

хорошо просмотр мужчина. Вам не кажется, что проблемы с новичками слишком сильно зависят от std :: string. Это делает C++ слишком похожим на Java, и когда вам приходится работать с char *, вы потеряны. – toto

1

Давайте попробуем объяснить в коде:

// your code 
char *first="hi"; 
// this is the memory location of the string, assigned by the compiler 
// sizeof(first) == sizeof(char*) == 4 (usually, lets not get into this right now) 
char *first = 0x12345; 


// your code 
char third[]="new"; 
// means, the following: 
char third[4]; 
third[0] = 0x6E; // ascii code of 'n' 
third[1] = 0x65; // ascii code of 'e' 
third[2] = 0x77; // ascii code of 'w' 
third[3] = 0x00; // strings in C end with NULL 
// note that sizeof(third) is still sizeof(char*), but this 
// time you statically allocated sizeof(char)*4 for the whole array 

Больше чтение для вас:

Смежные вопросы