Другой вопрос о типах данных C - PullRequest
4 голосов
/ 16 апреля 2010

Ну, я полностью получаю самые основные типы данных C, такие как short, int, long, float, если быть точным, все числовые типы. Эти типы должны быть известны, чтобы выполнять правильные операции с правильными числами. Например, использовать FPU для добавления двух чисел с плавающей точкой. Таким образом, компилятор должен знать, что это за тип.

Но когда дело доходит до персонажей, я немного не в себе. Я знаю, что базовый тип данных C предназначен для кодирования символов ASCII. Но я не знаю, зачем вам нужен еще один тип данных для персонажей. Почему вы не можете просто использовать 1-байтовое целочисленное значение для хранения символа ASCII. Если вы вызываете printf, вы указываете тип данных в вызове, чтобы вы могли сказать printf, что целое число представляет символ ASCII. Я не знаю, как cout разрешает тип данных, но я думаю, вы могли бы просто указать это как-то.

Другое дело, что если вы хотите использовать Unicode, вы должны использовать тип данных wchar. Но что, если я хотел бы использовать какое-то другое, например, ISO или кодирование Windows вместо UTF? Так как wchar кодирует символы как UTF-16 или UTF-32 (я читаю их специфичные для компилятора). И что, если я захочу использовать, например, какое-нибудь воображаемое новое 8-байтовое кодирование текста? Какой тип данных я должен использовать для этого? Я на самом деле довольно смущен этим, потому что я всегда ожидал, что если я захочу использовать UTF-32 вместо ASCII, я просто скажу компилятору «получить значение UTF-32 для введенного мной символа и сохранить его в поле 4 символа». Я думал, что кодирование текста должно решаться до конца, например, функция печати. Мне просто нужно указать кодировку, которую должен использовать компилятор, так как Windows не использует ASCII в приложениях win32, я полагаю, что компилятор C должен преобразовывать тип символов, который я набрал, в ASCII из любого типа, который Windows отправляет в редактор C.

И последнее, что если я захочу использовать, например, 25-байтовое целое число для некоторых математических операций? C не имеет определенного типа данных. Да, я знаю, что это будет сложно, так как все математические операции нужно будет изменить, потому что ЦП не может сложить 25-байтовые числа вместе. Но есть ли способ сделать это? Или есть математическая библиотека для этого? Что если я хочу вычислить число Пи до 1000000000000000 цифр? :)

Я знаю, что мой вопрос довольно длинный, но я просто хотел объяснить мои мысли как можно лучше на английском, поскольку это не мой родной язык, это сложно. И я считаю, что есть простой ответ на мой вопрос (ы), что я пропустил, что объясняет все. Я много читал о кодировании текста, учебниках по Си, но ничего о нем. Спасибо за ваше время.

Ответы [ 4 ]

2 голосов
/ 16 апреля 2010

Ваш вопрос очень широкий, я постараюсь ответить на некоторые конкретные вопросы, которые вы подняли, надеюсь, это поможет вам разобраться.

  • Тип char может быть просто еще одним числовым типом, таким как int, short и long. Это нормально писать char a=3;. Разница в том, что при char s компилятор дает вам некоторую добавленную стоимость. вместо просто чисел вы также можете назначить символы ASCII для переменной, такой как char a='U';, и тогда переменная получит значение ASCII этого символа, и вы также можете инициализировать массивы символов, используя буквенные строки, например: char *s="hello";.
    Это не меняет того факта, что в конце концов char все еще является числовым типом, а строка - просто массивом чисел. Если вы посмотрите на память строки, вы увидите коды ASCII строки.

  • Выбор char в качестве 1 байта является произвольным и в значительной степени сохраняется в C по историческим причинам. более современные языки, такие как C # и Java, определяют char как 2 байта.

  • Вам не нужен «другой» тип для символов. char - это просто числовой тип, который содержит один пропущенный / беззнаковый байт, такой же, как short - это числовой тип, который содержит 16-битное слово со знаком. Тот факт, что этот тип данных используется для символов и строк, является просто синтаксическим сахаром, предоставленным компилятором. 1-байтовые целые числа == символ .

  • printf() работает только с символами, так как это был способ С. если бы он был разработан сегодня, он, вероятно, будет работать с шортами. Действительно, в Windows у вас есть версия printf(), которая работает с шортами, она называется wprintf()

  • тип wchar_t в Windows - это просто другое имя для short. где-то в заголовочных файлах Windows есть такое выражение: typedef short wchar_t;, которое делает это возможным. Вы можете использовать их взаимозаменяемо. Преимущество использования слова wchar_t состоит в том, что тот, кто читает ваш код, знает, что теперь вы хотите использовать символы, а не цифры. Другая причина заключается в том, что если есть небольшой шанс, что когда-нибудь Microsoft решит, что теперь они хотят использовать UTF32, тогда все, что им нужно, это переопределить приведенный выше typedef, чтобы он был typedef int wchar_t;, и все (на самом деле это будет довольно сложно. добиться этого вряд ли в обозримом будущем)

  • Если вы хотите использовать некоторую 8-битную кодировку, которая не является ASCII, например кодировку для иврита, которая называется «Windows-1255», вы просто используете символы. Таких кодировок много, но в наши дни использование UNICODE всегда предпочтительнее. Действительно, на самом деле существует версия самого Unicode, которая вписывается в 8-битные строки, это UTF-8. Если вы имеете дело со строками UTF-8, вам следует работать с типом данных char. Ничто не ограничивает его работу с ASCII, поскольку это просто число, оно может означать что угодно.

  • Работа с такими длинными числами обычно выполняется с использованием так называемых «десятичных типов». C не имеет этого, но C # имеет. Основная идея этих типов заключается в том, что они обрабатывают число, похожее на строку. Каждая цифра десятичного представления сохраняется с использованием 4 битов, поэтому 8-битная переменная может сохранять числа в диапазоне 0-99, 3-байтовый массив может сохранять значения в диапазоне 0-999999 и так далее. Таким образом, вы можете сохранить номера любого диапазона.
    Недостатком этого является то, что выполнение вычислений по ним намного медленнее, чем выполнение вычислений по обычным двоичным числам.
    Я не уверен, есть ли библиотеки, которые делают такие вещи в C. Используйте Google, чтобы узнать.

1 голос
/ 16 апреля 2010

В C символ равен 1-байтовому целому числу, которое также используется для хранения символа. Символ - это всего лишь 1-байтовое целое число в C.

И что если я захочу использовать для пример некоторого воображаемого нового 8-байтового текста кодирование?

Вы должны построить его самостоятельно, основываясь на типах, доступных через ваш компилятор / аппаратное обеспечение. Один из подходов может состоять в том, чтобы определить структуру с массивом из 8 символов и построить функцию для манипулирования указанной структурой со всеми операциями, которые вы хотите над этим выполнить,

потому что я всегда ожидал, что если я хочу использовать UTF-32 вместо ASCII, я просто скажите компилятору "получить значение UTF-32 персонажа, которого я напечатал, и сохраните его в поле 4 символа.

Вы ограничены типами вашего компилятора C, на который сильно влияет аппаратное обеспечение (и стандарт C + немного истории). C является языком низкого уровня и не дает много магии. Тем не менее, есть библиотечные функции, которые могут позволить вам переводить между (некоторыми) наборами символов, например, mbtowc() и аналогичные функции, которые делают именно это, вы говорите: «Вот 16 байтов символов ISO8859-1, переведите их в UTF-16 в этот буфер для меня, пожалуйста».

И последнее, что, если я хочу использовать, например, целое число 25 байт для некоторые высокие математические операции? С не имеет укажите свой тип данных.

C позволяет вам определять ваши собственные типы данных, структуры. Вы можете построить абстракцию поверх них. Люди создали такие библиотеки, см., Например, здесь . Другие языки могут позволить вам более естественно моделировать такие типы, например C ++, которые также позволяют вам перегружать операторы, такие как +, -, * и т. Д., Для работы с вашими собственными типами данных.

1 голос
/ 16 апреля 2010

На самом деле, существует множество языков, в которых типы переменных не известны во время компиляции. Это, как правило, добавляет некоторые накладные расходы во время выполнения.

Чтобы ответить на ваш первый вопрос, я думаю, вы зациклены на названии "char". Тип символа - это однобайтовое целое число в C (на самом деле это не совсем так - это целочисленный тип, достаточно большой, чтобы содержать любой символ из базового набора символов, но его размер зависит от реализации.) Обратите внимание, что вы можете имеют как подписанные, так и неподписанные символы, что не имеет большого смысла, если вы говорите о типе данных, который содержит только символы Но однобайтовое целое число называется "char" в C, потому что это наиболее распространенное его использование (снова см. Отказ от ответственности выше.)

Остальная часть вашего вопроса охватывает лот земли - возможно, было бы лучше разбить это на несколько вопросов. Как и тип char, размер wchar_t зависит от реализации - единственное требование - он должен быть достаточно большим, чтобы вместить любой широкий символ. Важно понимать, что Unicode и кодировки символов в целом на самом деле не зависят от языка Си. Также важно понимать, что наборы символов - это не то же самое, что кодировки символов.

Вот статья (я полагаю, одного из основателей SO), которая дает краткое введение в наборы символов и кодировки: http://www.joelonsoftware.com/articles/Unicode.html. Как только вы лучше поймете, как они работают, вы станете лучше Позиция, чтобы сформулировать некоторые вопросы для себя. Обратите внимание, что многие наборы символов (например, кодовая страница Windows) требуют только одного байта памяти.

0 голосов
/ 16 апреля 2010

Существует (не было) никакого типа "1-байтовое целое число", кроме char (и его вариантов signed и unsigned). И хотя Windows NT (то есть не 9x или ME) действительно использует Unicode для внутреннего использования, ваша программа будет использовать Unicode, только если вы напишите его таким образом - вам придется либо использовать WCHAR и все версии W вызовов win32, либо TCHAR и #define UNICODE.

...