Почему char «расширяется» до int?
Я знаю, что упускаю что-то очень простое, но не могу этого понять.
Если я сделаю char Letter = 'A';
, то letter = Letter << 8
, буква = 0, как и следовало ожидать, поскольку мы перекладываем биты «с полки»; влево.
Но если мы сделаем это:
char letter = 'A';
void setup()
{
Serial.begin(9600);
int twoBytes = letter << 8;
Serial.println(twoBytes, BIN);
}
void loop() {}
Результат: 100000100000000, но почему? <<
имеет приоритет над =
, поэтому сначала необходимо сдвинуть букву
влево на 8, а затем присвоить это значение (которое должно быть 0 ) до twoBytes
.
@HavocRC, 👍0
Обсуждение1 ответ
Лучший ответ:
Это забавное, неинтуитивное правило языка C++, называемое «интегральным
повышение". Проще говоря, это говорит о том, что никакие вычисления никогда не выполняются.
для типа меньше, чем int
: все, что меньше, неявно повышается
в int
, как только он появится в арифметическом или логическом выражении.
См. Неявные преобразования на сайте cppreference.com (предупреждения: это волосатый).
Спасибо, приму на веру! Было бы хорошей практикой сказать int twoBytes = Letter; twoBytes << 8;
вместо этого для ясности, или это вообще имеет значение?, @HavocRC
Я бы сказал, что для опытного программиста C или C++ это может не иметь большого значения. Для тех, кто не знаком с этими правилами, полезно все, что может сделать код более понятным. Вы также можете написать int twoBytes = int(letter) << 8;
или оставить letter << 8
и добавить комментарий., @Edgar Bonet
В таком случае, когда вам нужны только самые правые 8 бит, я бы лично «и» это сделал так: int twoBytes = (letter << 8) & 0xFF;
Поскольку вам нужен младший байт, сделайте это явным., @Nick Gammon
Я не уверен, как то, что вы говорите, связано с тем, что говорят они, но int twoBytes = (letter << 8) & 0xFF;
— это либо сложный способ помещения нуля в twoBytes
, либо потенциально неопределенное поведение. , в зависимости от значения и системы., @timemage
ОП был удивлен тем, что результат не был нулевым, поэтому я указал, что если вы делаете сдвиг (влево или вправо) и не уверены, сколько бит сохраняется в результате, тогда anding это сделает это ясно. Я не понимаю, как результаты могут быть неопределенными., @Nick Gammon
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Библиотека DHT.h не импортируется
- ошибка: ожидаемое первичное выражение перед токеном ','
Нет ли подразумеваемого, что это сработает (по некоторому определению слова «работа»)? Если вы ожидали ноль, почему бы просто не написать:
int twoBytes = 0;
— тот факт, что вы этого не сделали, подразумевает, что вы ожидаете, что буква будет рассматриваться как 16-битная., @Nick GammonЯ просто хочу отметить, что, хотя вы разместили это здесь, это полностью вопрос C++. Компилятор Arduino — это компилятор GNU C++. Ничего «Arduino» в том, как он обрабатывает код, который вы пишете, за исключением некоторой предварительной обработки, которую выполняет IDE. См. [здесь](https://arduinoprosto.ru/q/13178/classes-and-objects-how-many-and-what-file-types-do-i-actually-need-to-use-the /13182#13182) для получения более подробной информации об этом., @Nick Gammon
@NickGammon .....потому что мне нужно, чтобы «буква» находилась в старшем байте «twoBytes», и я помещаю еще один символ в младший байт «twoBytes». Несмотря на то, что код, который я написал, работал, будучи любознательным человеком, я понял, что это не имеет смысла, отсюда и вопрос., @HavocRC