Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: в чем отличие uint8_t от char?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Метценгерштейн
могу ли я всегда использовать uint8_t ? ведь оба беззнаковые и оба 8 бит.
и в программе вывода текста в UART uint8_t работает прекрасно.
demiurg_spb
char по умолчанию знаковый тип, более того его размерность заранее не известна...
Насчёт знаковости я погорячился, она тоже может меняться от реализации...
Его единственное назначение - это строки и символы. Для всего остального есть stdint.h.
Genadi Zawidowski
Цитата(Метценгерштейн @ Jan 18 2013, 15:14) *
могу ли я всегда использовать uint8_t


Советую просто прочитать что стандарт говорит про это и посмотреть на то, что можно выиграть от uint_fast8_t, например (на проектах, переносимых между ARM и AVR).
Каждому из типов своё применение.
Xenia
Цитата(Genadi Zawidowski @ Jan 19 2013, 03:49) *
... и посмотреть на то, что можно выиграть от uint_fast8_t, например (на проектах, переносимых между ARM и AVR).


Много тут не выиграешь, а скорее проиграешь.

Тип char крепко прижился в языке, т.к. на него все стринги завязаны, то бишь текстовые строки. Совсем обойтись без строковых сообщений сложно, а если их использовать, то окажется, что все строковые аргументы у библиотечных функций объявлены именно как char, а не иначе. Самим же написать что-то типа форматного printf'а слабО. А форматная печать (когда текст перемежается с цифирью) нужна бывает очень часто. А каждый раз сращивать такую строку из кусочков текста и чисел утомительно.

Конечно, буквам все равно где лежать, в char'ах или uint8_t'ах, однако строковые функции хотят только char, а всякий раз явно переопределять тип аргументов накладно.

Возможно из-за этого многие ... не пользуются ни тем, ни другим sm.gif, а выдумывают свои обозначения типов, отсутствующие в стандарте языка, которые с помощью дефайна (#define) определяют в заголовке программы должным образом. Чаще всего это типы:
i8, i16, i32
и их беззнаковые аналоги:
u8, u16, u32
Поэтому при переходах с одной архитектуры на другую, бывает достаточно только переопределить эти самодельные типы, не производя правку в алгоритмах. А то после того, как в некоторых архитектурах char стал двухбайтым, положиться стало не на что. И тут проявляет себя слабая сторона языка C/C++, когда типы переменных определены не строго, а в зависимости от архитектуры процессора. Эта особенность полезна, чтобы использовать язык, как кроссассемблер, но вредна, когда ставит работу алгоритмов в зависимость от этого.

Впрочем, проблему взаимодействия со стриговыми функциями этот метод не решает. Но если это C++, то всегда можно доопределить аналоги стринговых функций, с готовностью пожирающие аргументы типа i8 и u8 вместо char. На то полиморфизм и нужен. sm.gif
Сергей Борщ
QUOTE (Xenia @ Jan 19 2013, 03:22) *
Много тут не выиграешь, а скорее проиграешь.
Ксения, расскажите, пожалуйста, про проигрыш? В чем он выражается конкретно? Я знаю и могу рассказать вам о выигрыше.

QUOTE (Xenia @ Jan 19 2013, 03:22) *
Конечно, буквам все равно где лежать, в char'ах или uint8_t'ах, однако строковые функции хотят только char, а всякий раз явно переопределять тип аргументов накладно.
Вы смешали в кучу все, что только можно. char используется для того, о чем говорит его название: для хранения символов. Массивы charов - для последовательностей символов, т.е. строк. Строковые функции предназачены для работы со строками, поэтому будьте любезны передавать им указатель на char.

Если нужно работать со знаковыми или беззнаковыми числами и вы хотите их уложить в такой же размер памяти, какую занимает char - будьте добры использовать signed char или unsigned char. Для уменьшения писанины - объявленные в stdint.h типы int8_t и uint8_t. А вот если вы хотите с этими числами поработать как с символами используя строковые функции - то это явно нетрадиционное использование чисел и должно быть выделено явным преобразованием типа. И проблемы исчезнут, а программа станет читаемой и будет компилироваться без ошибок и предупреждений вне зависимости от того, как создатели компилятора представляют себе char по-умолчанию - знаковым или беззнаковым (имеют право!).
Hamster1979
ИМХО - char всегда пишу если подразумевается строка или символ, всякие uint8 и прочая - для хранения данных в опрделенной размерности бит и указания знака, для переносимости проектов на разные целевые платформы.
yes
у приличных людей строки это массивы wchar_t уже давно sm.gif

я, например, предпочитаю char, в совсем сложных случаях добавляю signed, unsigned. ну не люблю я uint8_t и остальные типы с того инклуда
разницы никакой

-----

например для 55х тмсов (и наверняка для других странных архитектур) где char 16 бит стока надо переделывать в исходниках, что эта разница значения практически не имеет

demiurg_spb
Цитата(yes @ Jan 23 2013, 14:19) *
например для 55х тмсов (и наверняка для других странных архитектур) где char 16 бит стока надо переделывать в исходниках, что эта разница значения практически не имеет

Например что переделывать (конкретно)?
Я как раз-то и агитирую за использование по назначению типа char (только для строк и символов),
а то, что лично вы не используете типы из <stdint.h>, так это лично ваши предпочтения.
Мне очень нравится, к примеру, в небольших циклах использовать в качестве счётчика тип uint_fast8_t - получается оптимально и для кортексов, и для авр8, и для x86.
И переделывать ничего не надо. Если вы ещё не смогли оценить эту возможность - очень жаль.
Ну и насчёт wchar_t, вы тоже слегка преувеличиваете, так например в avr-gcc вообще как класс отсутствуют <wchar.h> и <wctype.h>,
а для работы с winapi TCHAR более уместен. Видите как оно бывает? Я бы сказал что в первую очередь от фреймворка стоит отталкиваться при выборе традиционных для него типов: в Qt одно в BCB другое в VS третье.
yes
бывает и кроме win и авр-а программирование, не правда ли?

а использовать char или uint8_t - дело вкуса, я никаких претензий к пользователям stdint.h не предьявляю

по поводу архитектур с нестандартными размерами long, short, char и т.п. там кроме этого еще много всего нестандартного. ну и арифметика с указателями - да, ес-сно в ней ошибки
demiurg_spb
Цитата(yes @ Jan 23 2013, 21:23) *
бывает и кроме win и авр-а программирование, не правда ли?
Несомненно. Полно и 8-ми и 16-ти разрядных архитектур, а сейчас и 64-ёх битники от ARM на подходе, так что всё только начинаетсяsm.gif
Конечно можно найти какие-либо нестандартные фишки при заточке компилятора под ту или иную архитектуру, но 99% программы можно и ИМХО нужно писать с прицелом на повторное использование на различных платформах. Чему и сопутствует <stdint.h>.
Вот и всё что я хотел сказать.
_Pasha
Самый рекордсмен по кривизне - это тип int sm.gif
Что до stdint.h - их пользовать желательно там, где размер и поведение типов стандартизованы, говорили об этом тыщу раз.
Что такое "стандартизованное поведение"? А я и сам не знаю, допускаю только, что к typedef unsigned char uint8_t можно добавить еще какие-либо атрибуты, но до этого дело пока не дошло. И хорошо, неча мозг утомлять.
Ну и например какой-нить протокол связи, пакет которого описывается структурой. Совершенно очевидно, что для нормальной работы "и там и сям" надо пользоваться stdint.h а не всякой чепухой.
Сергей Борщ
Во, вчера нарвался в исходниках v-usb:
CODE
char    i;
...
    i = len;
    do{                         /* if len == 0, we still copy 1 byte, but that's no problem */
        *p++ = *data++;
    }while(--i > 0);            /* loop control at the end is 2 bytes shorter than at beginning */

И ни дай бог компилятор решит, что char по умолчанию беззнаковый...
Lagman
можно этому верить?
Статья на Хабре
_Pasha
Цитата
От типов вроде int16_t, со строгим указанием размера, страдает переносимость

Чувак не вкуривает, для чего exact-width - типы нужны.
Misile_Inc
char по умолчанию не является ни знаковым, ни беззнаковым. Каким он будет, зависит от платформы. Это единственный тип, для которого наличие знака не определено стандартом. Сам попадал в неудобную ситуацию, когда char оказался знаковым.
Поэтому лучше всегда пользоваться типами с определенной размерностью stdint.h. Это избавит вас от проблем знаковости и некоторых проблем портируемости кода из-за разных размерностей типов на разных платформах. Мне попадался char = int = long размером 32 бит на одной из платформ.

Цитата(yes @ Jan 23 2013, 21:23) *
по поводу архитектур с нестандартными размерами long, short, char и т.п. там кроме этого еще много всего нестандартного. ну и арифметика с указателями - да, ес-сно в ней ошибки


Архитектур с нестандартными размерами long, short, char и т.п. мне еще не встречалось. Ибо в стандарте указано лишь соотношение long>= int >= char. Следовательно, размер long и char может совпадать.
Ошибки чаще всего не в компиляторах, а в программистах, которые не знают как средствами языка (например, stdint) пользоваться
ReAl
Цитата(Misile_Inc @ Feb 20 2013, 10:22) *
Ибо в стандарте указано лишь соотношение long>= int >= char. Следовательно, размер long и char может совпадать.
Ещё там short в цепочке и ещё short не может быть короче 16 бит.
Misile_Inc
Цитата(ReAl @ Feb 20 2013, 12:43) *
Ещё там short в цепочке и ещё short не может быть короче 16 бит.

"int and short be at least 16 bits and long be at least as long as int and not smaller than 32
bits" если быть точнее. Согласен, это я упустил. Главное, что char может быть много больше, чем программист себе изначально представляет.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.