Форум программистов, компьютерный форум CyberForum.ru

Тип char.Signed/unsigned.Отличие типов данных. - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 168, средняя оценка - 4.99
toxxin
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
30.08.2009, 22:17     Тип char.Signed/unsigned.Отличие типов данных. #1
Вопрос немного может быть не туда... Прошу прощения. Пишу прошивку к контроллеру, на С. Интересует отличие типов данных. ДОпустим есть тип char и тип unsigned char. Первый -128...127, а второй 0...255 соответственно. Оба типа занимают 8 бит. В чем разница?? Или разница в обработки типов библиотеками(к примеру) или правильном распозновании например кодировки ASCII ну и т.д. Интересует разница на битовом уровне. Т.е. по идее и там и там 8 бит..

Вопрос появился, когда мне необходимо было считать байт из регистра. Для этого я завел переменную(допустим t) типа char, считал байт. Если я правильно понимаю t фактически это тоже байт памяти, поэтому при считывании регистра в эту переменную t у меня все эти 8 бит просто дублируются. Вопрос что бы изменилось если бы я переменную обозначил типа unsigned char?? И вообще пишут что тип char это символ, а мне не очень понятно ГДЕ/ЧТО/КАК этот символ. И как СИМВОЛ отличается от типа ИНТЕДЖЕР например(кроме того что int - 16 бит)??
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.08.2009, 22:17     Тип char.Signed/unsigned.Отличие типов данных.
Посмотрите здесь:

C++ Signed/Unsigned
C++ Разница между char и signed char
C++ Значения типов данных (signed, unsigned, char)
C++ Надо перевести переменную типа unsigned char* в signed int и обратно
C++ [C++ Warning] Unit1.cpp(24): W8012 Comparing signed and unsigned values
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
10.11.2010, 19:59     Тип char.Signed/unsigned.Отличие типов данных. #41
Цитата Сообщение от norge_goth Посмотреть сообщение

Добавлено через 12 минут
Вопрос по вашему коду, что это за объявление? то есть что это символ/код
unsigned char Bxbit1:1
битовые поля
объявлена переменная (Bxbit1) типа (unsigned char) размером 1 бит(:1).
при таком объявлении cout выводит символ, а вот если объявить unsigned Bxbit1:1, то выводить будет код символа(точнее, числовое значение переменной:1 или 0, что и нужно в данном случае).
Вопрос как раз в том, что значит такое объявление, что это за тип - unsigned?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
10.11.2010, 20:03     Тип char.Signed/unsigned.Отличие типов данных. #42
Цитата Сообщение от st_dent Посмотреть сообщение
unsigned
без знаковый это значит что в одном байте можно поместить от 0 до 255 значение, то есть он содержит только натуральные числа(не отрицательные), signed напротив -127..128
1111 1111 = 255(unsigned)
1111 1111 = -1 (signed)

вообще unsigned это не тип а модификатор типа может быть unsigned int, unsigned char, unsigned double
а если просто как в вашем объявлении то под unsigned подразумеваеться неявно unsigned int(то есть число, а не символ для cout), тоже было бы если б вы объявили просто short или long
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
10.11.2010, 20:08     Тип char.Signed/unsigned.Отличие типов данных. #43
norge_goth, спасибо, но это понятно.
объявление знакового/без знакового:
C++
1
2
unsigned int x;
signed int x;//(или просто int x, т.к. по умолчанию идет signed )
а вот что значит такое объявление??
C++
1
unsigned x;
что это за тип? тут по умолчанию int подставляется или как?
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
10.11.2010, 20:10     Тип char.Signed/unsigned.Отличие типов данных. #44
Цитата Сообщение от st_dent Посмотреть сообщение
norge_goth, спасибо, но это понятно.
объявление знакового/без знакового:
C++
1
2
unsigned int x;
signed int x;//(или просто int x, т.к. по умолчанию идет signed )
а вот что значит такое объявление??
C++
1
unsigned x;
что это за тип? тут по умолчанию int подставляется или как?
оно самое
C++
1
unsigned x;
==(неявно)

C++
1
unsigned int x;
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
10.11.2010, 20:13     Тип char.Signed/unsigned.Отличие типов данных. #45
norge_goth, в таком случае почему код, приведенный выше, при объявлении по разному дает разный результат, если такие объявления эквивалентны?
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
10.11.2010, 20:21     Тип char.Signed/unsigned.Отличие типов данных. #46
Цитата Сообщение от st_dent Посмотреть сообщение
norge_goth, в таком случае почему код, приведенный выше, при объявлении по разному дает разный результат, если такие объявления эквивалентны?
вы имеете ввиду почему

C++
1
2
3
4
 unsigned char Bxbit1:1;  //        (1)
        //и т.д.
        
       //unsigned Bxbit1:1;         //        (2)
(1) и (2) дают разные результаты?

(1) cout выводит как чар(символ) Си-еквивалент printf("%c", Bxbit1)

(2) cout выводит как unsigned int(число) Си-еквивалент printf("%d", Bxbit1)
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
10.11.2010, 20:48     Тип char.Signed/unsigned.Отличие типов данных. #47
norge_goth, спасибо. а как заставить cout выводить unsigned char как не символ, а как число(аналог printf("%d", Bxbit1))?
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
10.11.2010, 21:17     Тип char.Signed/unsigned.Отличие типов данных. #48
Цитата Сообщение от st_dent Посмотреть сообщение
norge_goth, спасибо. а как заставить cout выводить unsigned char как не символ, а как число(аналог printf("%d", Bxbit1))?
По моему есть четыре способа вывести код чара:
1. Использовать тот же printf("%d", Bxbit1) в С++ никто не запрещает
2. Перегрузить cout, не разу не делал но предполагаю что можно аля:
C++
1
2
3
4
   void cout(unsigned char& ch) 
    {
         printf("%d", ch);
    }
Такое хоть и кажется оптимальным но не советую делать, во-первых искажаеться смысл cout'a а во-вторых если захочеш пользоваться стандартным выводом надо использовать разрешение видимости ::cout

3. Определить ф-ции типа myCout
C++
1
2
3
4
   void myCout(unsigned char& ch) 
    {
         printf("%d", ch);
    }
имеешь и свой персональный коут и стандартный под рукой

4. использовать оператор приведения типов перед выводом:
C++
1
int iCh = static_cast<int> (ch)
и делать вывод iCh как инта

намой взгляд оптимальный вариант 3. и 4.
для 3. и 2. варианта можно даже переопределить операторы << чтоб было как в стандартном но эт уже по геморойней
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
10.11.2010, 21:41     Тип char.Signed/unsigned.Отличие типов данных. #49
norge_goth,
спасибо, последний вариант - оптимальный!
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
10.11.2010, 23:39     Тип char.Signed/unsigned.Отличие типов данных. #50
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от toxxin Посмотреть сообщение
Вопрос немного может быть не туда... Прошу прощения. Пишу прошивку к контроллеру, на С. Интересует отличие типов данных. ДОпустим есть тип char и тип unsigned char. Первый -128...127, а второй 0...255 соответственно. Оба типа занимают 8 бит. В чем разница?? Или разница в обработки типов библиотеками(к примеру) или правильном распозновании например кодировки ASCII ну и т.д. Интересует разница на битовом уровне. Т.е. по идее и там и там 8 бит..

Вопрос появился, когда мне необходимо было считать байт из регистра. Для этого я завел переменную(допустим t) типа char, считал байт. Если я правильно понимаю t фактически это тоже байт памяти, поэтому при считывании регистра в эту переменную t у меня все эти 8 бит просто дублируются. Вопрос что бы изменилось если бы я переменную обозначил типа unsigned char?? И вообще пишут что тип char это символ, а мне не очень понятно ГДЕ/ЧТО/КАК этот символ. И как СИМВОЛ отличается от типа ИНТЕДЖЕР например(кроме того что int - 16 бит)??
Тут много написано, я не стал читать.

В случае, если процессор работает с целыми числами в дополнительном коде (а это так для всех "нормальных" процессоров и для большинства специализированных), то разница между знаковым типом и беззнаковым только в трактовке величины. Т.е. битовое представление int и unsigned int ничем не отличается. При операции сложения знаковых или беззнаковых типов для одного и того же набора параметров (в битовом представлении) получим один и тот же результат. Таким же свойством обладают операции вычитания, умножения, все побитовые операции, операция сдвига влево. Знаковость критична для операций деления и операций сдвига вправо. Так же знаковость критична при целочисленном преобразовании к более широкому типу. Т.е. преобразования char->int и unsigned char->int в общем случае НЕ эквивалентны

Добавлено через 3 минуты
Цитата Сообщение от novi4ok Посмотреть сообщение
например:

C
1
2
3
4
5
    char ch = -1;
    unsigned char uch = ch;
 
    int boolean = ch == uch;
    int comp = memcmp (&ch, &uch, sizeof (char));
в результате boolean окажется равным нулю, что означает, что результат сравнения отрицательный (не равно), а comp тоже окажется равным нулю, что означает положительный результат, т.е. равно. в памяти - то же самое, но там где важен тип, будут различия.
Рассуждения неверные. По стандарту языка Си любые операции над типами короче int'а вызывают promotion: аргумент будет расширен до int'а и только потом произведётся арифметическая операция. Т.е. при записи "ch == uch" реально выполняется операция "(int)ch == (int)uch". Результат будет false потому, что операции расширения (преобразования от короткого типа к длинному) для знаковых и беззнаковых НЕ эквивалентны (а не потому, что знаковый и беззнаковый char отличаются)

Добавлено через 10 минут
Цитата Сообщение от norge_goth Посмотреть сообщение
C
1
2
3
4
5
6
7
signed char ch=255;
unsigned char uch=255;
int sig_i;
int unsig_i;
 
sig_i = ch;
unsig_i = uch;
возник вопрос какой и куда компилятор устанавливает признак, что для случая
sig_i это будет значение -1 (в двоичной форме .... 1111 1111 1111 1111 1111 1111 1111 1111), а для
unsig_i = 255 (0000 0000 0000 0000 0000 0000 1111 1111), то есть как он решает что в одном случае надо просто нули добавить слева, а в другом единицы?
Это и есть то, что я выше называл "операция расширения". Для обеих переменных ch и uch мы имеем одно и то же битовое представление. Но при преобразовании к int'у используются различные операции: "знаковое расширение" и "беззнаковое расширение". Применительно к нашему примеру в первом случае знаковый (седьмой) бит значения распространяется на всю старшую часть, появившуюся при расширении: т.е. биты с 8 по 31 становятся равными 7-му биту ("знаковое расширение 8->32"). А во втором случае биты с 8 по 31 заполняются нулями ("беззнаковое расширение 8->32"). Знаковость расширения определяется знаковостью SRC-аргумента (но не dst). Т.е. преобразования "char->int" и "char->unsigned int" эквивалентны (поскольку в обоих случаях один и то же src-тип), а "char->int и unsigned char->int" НЕ эквивалентны (src-тип разный)

Добавлено через 8 минут
Цитата Сообщение от st_dent Посмотреть сообщение
Вопрос как раз в том, что значит такое объявление, что это за тип - unsigned?
Некая фривольность языка Си. О том, какие типы как можно обозначать - см. Вопрос о типах данных С++

Добавлено через 48 секунд
Цитата Сообщение от st_dent Посмотреть сообщение
norge_goth, спасибо. а как заставить cout выводить unsigned char как не символ, а как число(аналог printf("%d", Bxbit1))?
C++
1
cout << (int)uch;
norge_goth
62 / 62 / 7
Регистрация: 27.01.2009
Сообщений: 279
11.11.2010, 00:05     Тип char.Signed/unsigned.Отличие типов данных. #51
Цитата Сообщение от Evg Посмотреть сообщение
По стандарту языка Си любые операции над типами короче int'а вызывают promotion:
вы имеете ввиду операции сравнения? например
C
1
2
3
4
5
char ch1, ch;
short i, i1;
 
i = i1;
ch = ch1;
я полагаю не вызывают преобразований?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2010, 15:13     Тип char.Signed/unsigned.Отличие типов данных.
Еще ссылки по теме:

C++ 8-битовый тип signed char может представлять значения от -128 до 127
C++ Comparison between signed and unsigned integer expressions
C++ Приведение типов unsigned char[2] to unsigned char [64]

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16822 / 5243 / 318
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
11.11.2010, 15:13     Тип char.Signed/unsigned.Отличие типов данных. #52
norge_goth, имелись в виду арифметические операции и сравнения. В операции присваивания преобразование не нужно, потому как там делается копирование значения. А в арифметических операциях и сравнениях как бы делается "трактовка значения", т.е. некое виртуальное преобразование битового набора, загруженного из памяти, в некоторое "число", над которым можно производить действия.
Yandex
Объявления
11.11.2010, 15:13     Тип char.Signed/unsigned.Отличие типов данных.
Ответ Создать тему
Опции темы

Текущее время: 20:25. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru