char, указатель, приведение и строковые вопросы - PullRequest
3 голосов
/ 20 августа 2010
/*1*/ const char *const letter = 'A';

/*2*/ const char *const letter = "Stack Overflow";

Почему 1 недействителен, а 2 действителен?

буква - это указатель, которому необходимо присвоить адрес. Являются ли указанные строки адресами? Я предполагаю, что именно поэтому # 2 является действительным и что строки в одинарных кавычках не считаются адресами?

Кроме того, в чем разница между этими двумя типами кастинга?

static_cast<> и ().

И, наконец, если переменная является переменной типа char, почему cout << & var << выходит искаженным? Почему я должен разыграть это как недействительное *? </p>

Спасибо за ваше терпение по поводу вопросов для начинающих.

Ответы [ 6 ]

8 голосов
/ 20 августа 2010

Поскольку 'A' не является указателем, это char, 65 или 41 16 , если базовый набор символов ASCII.

"Stack", с другой стороны, является строкой, в основном массивом символов {'S', 't', 'a', 'c', 'k', '\0'}, который ухудшается до указателя на свой первый символ.

Ваша "разница между static_cast и ()" была получена здесь , намного лучше, чем я мог.

Причина, по которой вы получаете мусор с char var = 'x'; cout << &var ..., заключается в том, что &var - это char *, что означает, что его обрабатывают как строку - вв этом случае cout выводит символы до конечного нулевого символа \0, которого нет или находится за пределами символа.Следующий код показывает это:

#include <iostream>
int main() {
    //int q1 = 0;
    char xx = 'x';
    //int q2 = 0;
    std::cout << &xx << std::endl;
    return 0;
}

вывод:

x~Í"

Когда вы раскомментируете строки q, это работает, потому что это ставит нули вокруг символа, выводя xсам по себе).Имейте в виду, что это не кошерный C, он работает только из-за того, как организован мой стек.Не используйте это настоящий код.

0 голосов
/ 20 августа 2010

Один из способов, которым я обычно следую, - это использовать оператор typeid для понимания типов, с которыми я имею дело.

То есть type_info :: name возвращает строку, определяемую реализацией, обычно во многих случаях самоочевидно понять, с чем мы имеем дело Вывод ниже показан при компиляции с gcc

#include <iostream>
#include <typeinfo>
using namespace std;

int main(){
   cout << typeid('A').name() << endl;                      // prints 'c' meaning char
   cout << typeid("Stack Overflow").name() << endl;         // prints 'A15_c' meaning
                                                            // array of 15 characters
}
0 голосов
/ 20 августа 2010

Вы можете видеть char как целочисленный тип (как int, но более короткий), поэтому, когда вы пишете char l = 'A';, вы просто подписываете числовое значение ASCII A в переменной l.

Когда вы пишете char* letters = "foo", результат будет похож на следующий

char letters[4];
letters[0] = 'f';
...
letters[3] = '\0';
0 голосов
/ 20 августа 2010

В этом случае «A» - это просто значение (вероятно, «65»). Всякий раз, когда C видит что-то в одинарных кавычках, он предполагает, что имеет дело с одним символом. Таким образом, вы, по сути, говорите, что указатель «буква» будет указывать на то, что находится по адресу памяти 65. , вероятно, не то, что вы собираетесь, поэтому компилятор помечает это как ошибку.

С другой стороны, когда вы назначаете строку («A»), компилятор делает некое волшебство за кулисами, чтобы заставить его работать. Он берет эту строку и помещает ее куда-нибудь в ваш исполняемый файл, а затем каждый раз, когда вы используете эту конкретную строку, заменяет адрес памяти строки, о которой он знает, на литерал, который вы поместили в программу.

Кроме того, static_cast (value) предпочтительнее, чем (type), потому что static_cast <> () имеет тенденцию быть немного более ограничительным в том, что он будет делать (так что больше ошибок будет обнаружено во время компиляции). Это также более многословно (например, есть const_cast (значение), которое преобразует значение из const (неизменяемого) во что-то, что может быть изменено вашим кодом.

НТН

0 голосов
/ 20 августа 2010

Для вашего второго вопроса будет полезна ссылка .

0 голосов
/ 20 августа 2010

Первый тип - это просто char тип со значением A .. Кроме того, здесь нет строк в одинарных кавычках, а только символ в одинарных кавычках.

В то время как второй array of characters и, таким образом, он работает ..

char letter [] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char letter [] = "Hello"; 

Оба указывают одно и то же средство инициализации для letter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...