Arlleex 131 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба Приветствую! Допустим, есть функция static u32 HexToInt1(u8 Symb) { if(Symb <= '9') return Symb - '0'; else return (Symb & 0x7) + 9; } Есть правила, по которым сохраняются или неявно преобразуются типы представления переменных. 1. В условии if(Symb <= '9') тип выражения будет int, потому что '9' имеет этот тип, а все возможные значения u8 "влазят" в диапазон представления положительных значений int. 2. В операторе return Symb - '0' тип выражения будет int. Однако функция возвращает u32. Будет ли здесь иметь место какое-либо неявное преобразование? 3. Какой тип будут иметь выражения (Symb & 0x7) + 9 и return (Symb & 0x7) + 9? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 36 минут назад, Arlleex сказал: 1. В условии if(Symb <= '9') тип выражения будет int, потому что '9' имеет этот тип, а все возможные значения u8 "влазят" в диапазон представления положительных значений int. Нет, не поэтому. ISO/IEC 9899, параграф 6.5.8 Цитата Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 1 минуту назад, andrew_b сказал: Нет, не поэтому. ISO/IEC 9899, параграф 6.5.8 Ну да. Но, все-таки, Symb будет рассматриваться как int, так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 3 часа назад, Arlleex сказал: 1. В условии if(Symb <= '9') тип выражения будет int, потому что '9' имеет этот тип Имхо '9' имеет тип char. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 3 часа назад, Arlleex сказал: Допустим, есть функция static u32 HexToInt1(u8 Symb) { if(Symb <= '9') return Symb - '0'; else return (Symb & 0x7) + 9; } Имхо оптимальнее так: static u32 HexToInt1(u8 Symb) { uint i; if ((i = Symb - '0') > 9) i = i - 'A' + '0' & 7; return i; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 13 минут назад, jcxz сказал: Имхо оптимальнее так: static u32 HexToInt1(u8 Symb) { uint i; if ((i = Symb - '0') > 9) i = i - 'A' + '0' & 7; return i; } Неа, подаю символ 'F' на вход, получаю 5 =) Моя функция в исходном виде выше была предназначена для преобразования ASCII HEX-тетрады в двоичный вид. Причем, на вход подаются только символы '0'-'9', 'a'-'f' или 'A'-'F'. Однако, сейчас в голову стукнуло, что я пишу парсер протокола, в котором, на самом деле, все может быть... В итоге написал так static u32 HexToInt1(u32 Symb, u32 *IntBuf) { if(Symb >= '0' && Symb <= '9') {*IntBuf = Symb - '0'; return 0;} if((Symb >= 'a' && Symb <= 'f') || (Symb >= 'A' && Symb <= 'F')) {*IntBuf = (Symb & 0x7) + 9; return 0;} return 1; } В случае, если встретится запрещенный символ - функция вернет 1, иначе - 0, при этом записав адекватное преобразование в *IntBuf. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 42 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 49 minutes ago, jcxz said: Имхо '9' имеет тип char. In C, character literals such as 'a' have type int Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 3 часа назад, Arlleex сказал: Неа, подаю символ 'F' на вход, получаю 5 =) Ну да - там ещё 10 надо было прибавить. ;) Цитата Моя функция в исходном виде выше была предназначена для преобразования ASCII HEX-тетрады в двоичный вид. Причем, на вход подаются только символы '0'-'9', 'a'-'f' или 'A'-'F'. Однако, сейчас в голову стукнуло, что я пишу парсер протокола, в котором, на самом деле, все может быть... А я думал - у Вас точка вызова гарантирует, что символы только из допустимого диапазона. Я заключил это из кода функции, даже не подумал что Вы об этом не подумали... Цитата В итоге написал так static u32 HexToInt1(u32 Symb, u32 *IntBuf) { if(Symb >= '0' && Symb <= '9') {*IntBuf = Symb - '0'; return 0;} if((Symb >= 'a' && Symb <= 'f') || (Symb >= 'A' && Symb <= 'F')) {*IntBuf = (Symb & 0x7) + 9; return 0;} return 1; } В случае, если встретится запрещенный символ - функция вернет 1, иначе - 0, при этом записав адекватное преобразование в *IntBuf. Очень громоздко! Одних только ветвлений 6 штук! Если для ручного ввода ещё как-то пойдёт, то для парсинга протокола я не стал бы так делать. Сравните: static int HexToInt1(u8 Symb) { uint i; if ((i = Symb - '0') > 9) { i = (i & ~0x20) - 0x11; if (i > 5) return -1; i += 10; } return i; } Всего 2 ветвления. Сравните листинги. Да и аргумент лучше переделать на uint Symb. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 1 час назад, jcxz сказал: Всего 2 ветвления. Сравните листинги... Не понимаю, как Вы это делаете Шо то я сидел сидел, да не придумал, потому в лоб и накатал... Спасибо, оно работает! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 4 августа, 2019 Опубликовано 4 августа, 2019 · Жалоба 19 минут назад, Arlleex сказал: Не понимаю, как Вы это делаете Надо думать как процессор. 19 минут назад, Arlleex сказал: Шо то я сидел сидел, да не придумал, потому в лоб и накатал... Спасибо, оно работает! Да пожалуйста. Пользуйтесь на здоровье Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ae_ 2 16 августа, 2019 Опубликовано 16 августа, 2019 · Жалоба Последнее сложение можно сократить: static int HexToInt1(u8 Symb) { uint i; if ((i = Symb - '0') > 9) { i = (i & ~0x20) - 7; if (i > 15) return -1; } return i; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 16 августа, 2019 Опубликовано 16 августа, 2019 (изменено) · Жалоба 18 минут назад, ae_ сказал: Последнее сложение можно сократить... Я, в общем-то, сразу так и сделал, к тому же избавился от лишней переменной i static s32 HexToInt1(u32 Symb) { if((Symb = Symb - '0') > 9) { Symb = (Symb & ~0x20) - 7; if(Symb > 15) return -1; } return Symb; } Изменено 16 августа, 2019 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 16 августа, 2019 Опубликовано 16 августа, 2019 · Жалоба 6 часов назад, ae_ сказал: Последнее сложение можно сократить: Нельзя. Сначала подумайте почему именно такие значения, прежде чем что-то сокращать. 5 часов назад, Arlleex сказал: Я, в общем-то, сразу так и сделал, к тому же избавился от лишней переменной i И зря. Добавили баг. Там нет лишних операций. Сначала подумайте почему именно такие операции, прежде чем что-то сокращать. А переменная та же или отдельная - это дело вкуса. На код это никак не повлияет. Повлиять может только замена u8 на u32 (или uint) - это полезно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 16 августа, 2019 Опубликовано 16 августа, 2019 · Жалоба 56 минут назад, jcxz сказал: И зря. Добавили баг. Там нет лишних операций. Сначала подумайте почему именно такие операции, прежде чем что-то сокращать. Ваша правда, баг на ровном месте... Действительно поспешная корректировка. Верну назад. Благодарю за бдительность Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться