инициализация char и char указателей - PullRequest
4 голосов
/ 06 апреля 2010

В чем разница между ними:

Это работает:

char* pEmpty = new char;
*pEmpty = 'x';

Однако, если я попытаюсь сделать:

char* pEmpty = NULL;
*pEmpty = 'x'; // <---- doesn't work!

и

char* pEmpty = "x"; // putting in double quotes works! why??

РЕДАКТИРОВАТЬ: Спасибо за все комментарии: Я исправил это. это должно было быть pEmpty = 'x', Итак, эта строка даже не компилируется: char pEmpty = 'x'; когда эта строка работает: char * pEmpty = "x"; // двойные кавычки.

Ответы [ 5 ]

10 голосов
/ 06 апреля 2010

Ваша вторая строка не работает, потому что вы пытаетесь присвоить 'x' для pEmpty вместо *pEmpty.

Редактировать : Спасибо Чаку за исправление. ТАКЖЕ не работает, потому что вам нужно выделить немного памяти для хранения значения 'x'. См. Пример ниже.

Третья строка работает, потому что вы используете инициализатор, а не обычный оператор присваивания.

В общем, вы должны понимать, как работают указатели и разыменования.

char *p = new char();  // Now I have a variable named p that contains 
                       // the memory address of a single piece of character
                       // data.

*p = 'x'; // Here I assign the letter 'x' to the dereferenced value of p; 
          // that is, I look up the location of the memory address contained
          // in p and put 'x' there.

p = 'x'; // This is illegal because p contains a memory address, 
         // not a character.

char q = 'x';  // Now I have a char variable named q containing the 
               // character 'x'.

p = &q;  // Now I assign the address of q (obtained with the reference
         // operator &) to p.  This is legal because p contains a memory
         // address.
2 голосов
/ 06 апреля 2010

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

Когда вы делаете char* pEmpty = new char, вы даете pEmpty значение, возвращаемое new char, которое является адресом порции памяти, достаточно большой, чтобы содержать значение char. Затем вы используете *pEmpty для доступа к этой памяти и присваиваете ей значение символа 'x'.

Во втором примере вы пишете pEmpty = 'x' - но помните, что pEmpty является указателем , что означает, что он должен содержать адрес . 'x' адрес? Нет, это буквальный символ! Так что эта строка на самом деле не имеет смысла.

В третьем примере вы присваиваете pEmpty строковый литерал "x". Это адрес? Да, это. Литерал вычисляется по адресу этой постоянной строки.

Помните, что указатели - это совсем не то, на что они указывают. Их можно использовать для доступа к значению этого типа, но они совершенно другого типа.

1 голос
/ 06 апреля 2010

Разница в том, что строковые литералы хранятся в памяти, к которой программа может обращаться во время выполнения, тогда как символьные литералы являются просто значениями. C ++ спроектирован так, что символьные литералы, такие как тот, что у вас есть в примере, могут быть встроены как часть машинного кода и вообще никогда не храниться в памяти.

Чтобы сделать то, что вы пытаетесь сделать, вы должны определить статическую переменную типа char, которая инициализируется как 'x', а затем установить pEmpty для ссылки на эту переменную.

0 голосов
/ 06 апреля 2010

pEmpty = 'x'; присваивает pEmpty (а не память, на которую указывает) значение 'x'.

*pEmpty = 'x'; //this is probably what you want
0 голосов
/ 06 апреля 2010

Второй пример не работает по нескольким причинам. Во-первых, вы указали указатель, ну, в общем, нигде конкретно. Во-вторых, вы на самом деле не разыменовывали его, поэтому вы указываете указателю указать адрес литерала символа. Поскольку у него нет адреса, компилятор будет жаловаться.

EDIT:

Для ясности, звездочка (*) - это оператор, который разыменовывает указатели.

...