Почему char «расширяется» до int?

c++ bit bitshift

Я знаю, что упускаю что-то очень простое, но не могу этого понять.

Если я сделаю 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.

, 👍0

Обсуждение

Нет ли подразумеваемого, что это сработает (по некоторому определению слова «работа»)? Если вы ожидали ноль, почему бы просто не написать: 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


1 ответ


Лучший ответ:

4

Это забавное, неинтуитивное правило языка 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