Uint c что это

от admin

C2017/Типы данных в C

Целочисленные типы данных используются для хранения целых чисел (тип char также используется для хранения ASCII-символов). Все размеры диапазонов представленных ниже типов данных минимальны и на отдельно взятой платформе могут быть больше.

Стандарт не требует, чтобы два разных типа имели разный размер: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) . Таким образом, даже типы char и long могут иметь одинаковый размер, но такие платформы очень редки. Стандарт гарантирует, что sizeof(char) всегда равен 1.

Минимальный диапазон значений целых типов по стандарту определяется с [math]-(2^N-1)[/math] по [math]2^N-1[/math] , где [math]N[/math] — разрядность типа. Реализация компиляторов может расширять этот диапазон по своему усмотрению. Отметим, что такие ограничения позволяют использовать то или иное представление знаковых чисел:

  • дополнительный код (two’s complement) — для отрицательного числа код можно получить инвертированием его двоичного модуля и прибавлением к инверсии единицы
  • обратный код (ones’ complement) — двоичный код отрицательного целого числа состоит из одноразрядного кода знака (двоичной цифры 1), за которым следует ( [math]n−1[/math] )-разрядное двоичное число, представляющее собой инвертированное ( [math]n−1[/math] )-разрядное представление модуля числа
  • прямой код (sign and magnitude method) — знаковый бит и затем модуль числа без инвертирования.

Отдельное внимание стоит уделить типу char . Формально это отдельный тип, но фактически char эквивалентен либо signed char , либо unsigned char , в зависимости от компилятора.

Для того, чтобы избежать путаницы между размерами типов стандарт C99 ввел новые типы данных, описанные в файле stdint.h. Среди них такие типы как: intN_t , int_leastN_t , int_fastN_t , где N = 8, 16, 32 или 64. Приставка least- обозначает минимальный тип, способный вместить N бит, приставка fast- обозначает тип размером не менее 16 бит, работа с которым наиболее быстрая на данной платформе. Типы без приставок обозначают типы с фиксированном размером, равным N бит.

Типы с приставками least- и fast- можно считать заменой типам int , short , long , с той лишь разницей, что первые дают программисту выбрать между скоростью и размером.

Тип данных Размер Минимальный диапазон значений Первое появление
signed char минимум 8 бит от -127 (= -(2 8 -1)) до 127 K&R C
unsigned char минимум 8 бит от 0 до 255 (=2 8 -1) K&R C
char минимум 8 бит от -127 до 127 или от 0 до 255 в зависимости от компилятора K&R C
short int минимум 16 бит от -32,767 (= -(2 15 -1)) до 32,767 K&R C
unsigned short int минимум 16 бит от 0 до 65,535 (= 2 16 -1) K&R C
int минимум 16 бит от -32,767 до 32,767 K&R C
unsigned int минимум 16 бит от 0 до 65,535 (= 2 16 -1) K&R C
long int минимум 32 бита  от -2,147,483,647 до 2,147,483,647 K&R C
unsigned long int минимум 32 бита  от 0 до 4,294,967,295 (= 2 32 -1) K&R C
long long int минимум 64 бита от -9,223,372,036,854,775,807 до 9,223,372,036,854,775,807 C99
unsigned long long int минимум 64 бита от 0 до 18,446,744,073,709,551,615 (= 2 64 -1) C99
int8_t 8 бит от -127 до 127 C99
uint8_t 8 бит от 0 до 255 (=2 8 -1) C99
int16_t 16 бит от -32,767 до 32,767 C99
uint16_t 16 бит от 0 до 65,535 (= 2 16 -1) C99
int32_t 32 бита от -2,147,483,647 до 2,147,483,647 C99
uin32_t 32 бита от 0 до 4,294,967,295 (= 2 32 -1) C99
int64_t 64 бита от -9,223,372,036,854,775,807 до 9,223,372,036,854,775,807 C99
uint64_t 64 бита от 0 до 18,446,744,073,709,551,615 (= 2 64 -1) C99
Ошибки

Memsize-типы

Для представления величин, связанных с памятью, в C есть typedef’ы size_t и ptrdiff_t. Размер определяется архитектурой процессора.

size_t — беззнаковый тип для представления размера любого объекта (включая массив). Он способен хранить в себе размер максимального массива, который может быть теоретически выделен в рамках данной архитектуры.

Оператор sizeof возвращает результат типа size_t. Для size_t гарантируется, что он как минимум 16-битный.

Тип ptrdiff_t знаковый, используется для хранения разности указателей. Стандартом допускается вычисление разности только для указателей одного типа, для разных типов — зависит от реализации.

Модели данных

Под моделью данных следует понимать соотношения размерностей типов, принятых в рамках среды разработки на С.

Примеры приведены в таблице.

Вещественные типы

Стандартом гарантируется только, что sizeof(float) <= sizeof(double) <= sizeof(long double) .

На большинстве платформ применяются типы с плавающей точкой в соответствии со стандартом IEEE 754.

Логический тип

В языке C в стандарте C99 введён тип _Bool.

Массивы

Для каждого типа T, кроме void и типов функций, существует тип «массив из элементов N типа T». Массив — это коллекция значений одного типа, хранящихся последовательно в памяти. Массив размера N индексируется целым числом от 0 до N-1.

Массивы могут быть инициализированы с помощью списка инициализации, но не могут быть присвоены друг к другу.

В C99 добавлены динамические многомерные массивы:

Указатели

Для любого типа T существует тип «указатель на T».

Переменные могут быть объявлены как указатели на значения различных типов с помощью символа * . Для того чтобы определить тип переменной как указатель, нужно предварить её имя звёздочкой.

Поскольку указатель — тоже тип переменной, правило «для любого типа T» выполняется и для них: можно объявлять указатели на указатели. К примеру, можно пользоваться int*** :

Существуют также указатели на массивы и на функции. Указатели на массивы имеют следующий синтаксис:

pc  — массив указателей, занимающий 10 * sizeof(char*) байт (на распространённых платформах — обычно 40 или 80 байт), а pa  — это один указатель; занимает он обычно 4 или 8 байт, однако позволяет обращаться к массиву, занимающему 10 байт: sizeof(pa) == sizeof(int*) , но sizeof(*pa) == 10 * sizeof(char) . Указатели на массивы отличаются от указателей на первый элемент арифметикой. Например, если указатели pa указывает на адрес 2000, то указатель pa+1 будет указывать на адрес 2010.

Структуры

Композитный тип данных, инкапсулирующий без сокрытия набор значений различных типов.

При инициализации элементов структуры надо иметь в виду следующий момент:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

Важное отличие между С и C++.

В C++ можно писать

В C нужно писать

Так сделано специально. Названия структур находятся в отдельном пространстве имён. Их всего четыре вида:

  • названия меток (для goto);
  • теги (названия структур, объединений, перечислений);
  • члены структур и объединений;
  • все прочие идентификаторы.

Это позволяет, например, назвать переменную так же, как называется структура.

Или же можно сделать typedef:

Доступ к элементам структуры осуществляется с помощью оператора .. Для обращения к полям структуры по указателю существует оператор «стрелочка» ->, синонимичный предыдущей записи: (*p).x — то же самое, что и p->x.

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

Структуры не всегда занимают число байт, равное сумме байт их элементов. Компилятор обычно выравнивает элементы. The Lost Art of C Structure Packing

Адрес памяти первого поля структуры равен адресу самой структуры.

Объединения

Доступ к одним и тем же данным разными способами:

Т. н. type punning (каламбур типизации)

Стандартом C99 это разрешается (в отличие от приведения указателей разных типов).

If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.

Name already in use

docs / docs / csharp / language-reference / builtin-types / integral-numeric-types.md

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink
  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

Integral numeric types (C# reference)

The integral numeric types represent integer numbers. All integral numeric types are value types. They’re also simple types and can be initialized with literals. All integral numeric types support arithmetic, bitwise logical, comparison, and equality operators.

Characteristics of the integral types

C# supports the following predefined integral types:

C# type/keyword Range Size .NET type
sbyte -128 to 127 Signed 8-bit integer xref:System.SByte?displayProperty=nameWithType
byte 0 to 255 Unsigned 8-bit integer xref:System.Byte?displayProperty=nameWithType
short -32,768 to 32,767 Signed 16-bit integer xref:System.Int16?displayProperty=nameWithType
ushort 0 to 65,535 Unsigned 16-bit integer xref:System.UInt16?displayProperty=nameWithType
int -2,147,483,648 to 2,147,483,647 Signed 32-bit integer xref:System.Int32?displayProperty=nameWithType
uint 0 to 4,294,967,295 Unsigned 32-bit integer xref:System.UInt32?displayProperty=nameWithType
long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 Signed 64-bit integer xref:System.Int64?displayProperty=nameWithType
ulong 0 to 18,446,744,073,709,551,615 Unsigned 64-bit integer xref:System.UInt64?displayProperty=nameWithType
nint Depends on platform (computed at runtime) Signed 32-bit or 64-bit integer xref:System.IntPtr?displayProperty=nameWithType
nuint Depends on platform (computed at runtime) Unsigned 32-bit or 64-bit integer xref:System.UIntPtr?displayProperty=nameWithType

In all of the table rows except the last two, each C# type keyword from the leftmost column is an alias for the corresponding .NET type. The keyword and .NET type name are interchangeable. For example, the following declarations declare variables of the same type:

The nint and nuint types in the last two rows of the table are native-sized integers. Starting in C# 9.0, you can use the nint and nuint keywords to define native-sized integers. These are 32-bit integers when running in a 32-bit process, or 64-bit integers when running in a 64-bit process. They can be used for interop scenarios, low-level libraries, and to optimize performance in scenarios where integer math is used extensively.

The native-sized integer types are represented internally as the .NET types xref:System.IntPtr?displayProperty=nameWithType and xref:System.UIntPtr?displayProperty=nameWithType. Starting in C# 11, the nint and nuint types are aliases for the underlying types.

The default value of each integral type is zero, 0 .

Each of the integral types has MinValue and MaxValue properties that provide the minimum and maximum value of that type. These properties are compile-time constants except for the case of the native-sized types ( nint and nuint ). The MinValue and MaxValue properties are calculated at runtime for native-sized types. The sizes of those types depend on the process settings.

Use the xref:System.Numerics.BigInteger?displayProperty=nameWithType structure to represent a signed integer with no upper or lower bounds.

Integer literals can be

  • decimal: without any prefix
  • hexadecimal: with the 0x or 0X prefix
  • binary: with the 0b or 0B prefix

The following code demonstrates an example of each:

The preceding example also shows the use of _ as a digit separator. You can use the digit separator with all kinds of numeric literals.

The type of an integer literal is determined by its suffix as follows:

If the literal has no suffix, its type is the first of the following types in which its value can be represented: int , uint , long , ulong .

[!NOTE] Literals are interpreted as positive values. For example, the literal 0xFF_FF_FF_FF represents the number 4294967295 of the uint type, though it has the same bit representation as the number -1 of the int type. If you need a value of a certain type, cast a literal to that type. Use the unchecked operator, if a literal value cannot be represented in the target type. For example, unchecked((int)0xFF_FF_FF_FF) produces -1 .

If the literal is suffixed by U or u , its type is the first of the following types in which its value can be represented: uint , ulong .

If the literal is suffixed by L or l , its type is the first of the following types in which its value can be represented: long , ulong .

[!NOTE] You can use the lowercase letter l as a suffix. However, this generates a compiler warning because the letter l can be confused with the digit 1 . Use L for clarity.

If the literal is suffixed by UL , Ul , uL , ul , LU , Lu , lU , or lu , its type is ulong .

If the value represented by an integer literal exceeds xref:System.UInt64.MaxValue?displayProperty=nameWithType, a compiler error CS1021 occurs.

If the determined type of an integer literal is int and the value represented by the literal is within the range of the destination type, the value can be implicitly converted to sbyte , byte , short , ushort , uint , ulong , nint or nuint :

As the preceding example shows, if the literal’s value isn’t within the range of the destination type, a compiler error CS0031 occurs.

You can also use a cast to convert the value represented by an integer literal to the type other than the determined type of the literal:

You can convert any integral numeric type to any other integral numeric type. If the destination type can store all values of the source type, the conversion is implicit. Otherwise, you need to use a cast expression to perform an explicit conversion. For more information, see Built-in numeric conversions.

Native sized integers

Native sized integer types have special behavior because the storage is determined by the natural integer size on the target machine.

To get the size of a native-sized integer at run time, you can use sizeof() . However, the code must be compiled in an unsafe context. For example:

. code language=»csharp» source=»snippets/shared/NativeIntegerTypes.cs» .

You can also get the equivalent value from the static xref:System.IntPtr.Size?displayProperty=nameWithType and xref:System.UIntPtr.Size?displayProperty=nameWithType properties.

To get the minimum and maximum values of native-sized integers at run time, use MinValue and MaxValue as static properties with the nint and nuint keywords, as in the following example:

. code language=»csharp» source=»snippets/shared/NativeIntegerTypes.cs» .

You can use constant values in the following ranges:

  • For nint : xref:System.Int32.MinValue?displayProperty=nameWithType to xref:System.Int32.MaxValue?displayProperty=nameWithType.
  • For nuint : xref:System.UInt32.MinValue?displayProperty=nameWithType to xref:System.UInt32.MaxValue?displayProperty=nameWithType.

The compiler provides implicit and explicit conversions to other numeric types. For more information, see Built-in numeric conversions.

There’s no direct syntax for native-sized integer literals. There’s no suffix to indicate that a literal is a native-sized integer, such as L to indicate a long . You can use implicit or explicit casts of other integer values instead. For example:

C# language specification

For more information, see the following sections of the C# language specification:

Свод правил по работе с целыми числами в C/C++

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

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

Типы данных

Базовые целочисленные типы

Целочисленные типы устанавливаются с помощью допустимой последовательности ключевых слов, взятых из набора .

Несмотря на то, что битовая ширина каждого базового целочисленного типа определяется реализацией (т.е. зависит от компилятора и платформы), стандартом закреплены следующие их свойства:

  • char : минимум 8 бит в ширину;
  • short : минимум 16 бит и при этом не меньше char ;
  • int : минимум 16 бит и при этом не меньше short ;
  • long : минимум 32 бит и при этом не меньше int ;
  • long long : минимум 64 бит и при этом не меньше long .

Наличие знака

  • Стандартный сhar может иметь знак или быть беззнаковым, что зависит от реализации.
  • Стандартные short , int , long и long long идут со знаком. Беззнаковыми их можно сделать, добавив ключевое слово unsigned .
  • Числа со знаком можно кодировать в двоичном формате в виде дополнительного кода, обратного или как величину со знаком. Это определяется реализацией. Заметьте, что обратный код и величина со знаком имеют различные шаблоны битов для отрицательного нуля и положительного, в то время как дополнительный код имеет уникальный нуль.
  • Символьные литералы (в одинарных кавычках) имеют тип ( signed ) int в C, но ( signed или unsigned ) char в C++.

Дополнительные правила

  • sizeof(char) всегда равен 1, независимо от битовой ширины char .
  • Битовая ширина не обязательно должна отличаться. Например, допустимо использовать char , short и int , каждый шириной в 32 бита.
  • Битовая ширина должна быть кратна 2. Например, int может иметь ширину 36 бит.
  • Есть разные способы написания целочисленного типа. К примеру, в каждой следующей строке перечислен набор синонимов:
    • int , signed , signed int , int signed ;
    • short , short int , short signed , short signed int ;
    • unsigned long long , long unsigned int long , int long long unsigned .

    Типы из стандартных библиотек

    • size_t (определен в stddef.h) является беззнаковым и содержит не менее 16 бит. При этом не гарантируется, что его ширина будет как минимум равна int .
    • ptrdiff_t (определен в stddef.h) является целочисленным типом со знаком. Вычитание двух указателей будет давать этот тип. При этом не стоит ожидать, что вычитание двух указателей даст int .
    • В stdint.h определена конкретная ширина типов: uint8_t , int8_t , 16 , 32 и 64 . Будьте внимательны к операциям, подразумевающим продвижение типов. Например, uint8_t + uint8_t даст int (со знаком и шириной не менее 16 бит), а не uint8_t , как можно было предположить.

    Преобразования

    Представим, что значение исходного целочисленного типа нужно преобразовать в значение целевого целочисленного типа. Такая ситуация может возникнуть при явном приведении, неявном приведении в процессе присваивания или при продвижении типов.

    Как происходит преобразование?

    Главный принцип в том, что, если целевой тип может содержать значение исходного типа, то это значение семантически сохраняется.

    • Когда исходный тип расширяется до целевого типа с аналогичной знаковой характеристикой (например, signed char -> int или unsigned short -> unsigned long ), каждое исходное значение после преобразования сохраняется.
    • Даже если исходный и целевой типы имеют разные диапазоны, все значения в их пересекающейся части будут сохранены. Например, int , содержащий значение в диапазоне [0, 255] , будет без потерь преобразован в unsigned char .
    • При преобразовании в беззнаковый тип новое значение равняется старому значению по модулю 2 целевая ширина в битах . Объяснение:
      • Если исходный тип беззнаковый и шире целевого, тогда старшие биты отбрасываются.
      • Если исходный тип имеет знак, тогда в процессе преобразования берется исходное значение, и из него/к нему вычитается/прибавляется 2 целевая ширина в битах до тех пор, пока новое значение не впишется в диапазон целевого типа. Более того, если число со знаком представлено в дополнительном коде, то в процессе преобразования старшие биты отбрасываются, как и в случае с беззнаковыми числами.
      • Если исходное значение вписывается в диапазон целевого типа, тогда процесс преобразования (например, расширение знака) производит целевое значение, семантически равное исходному.
      • Если же оно не вписывается, тогда поведение будет определяться реализацией и может вызвать исключение (к примеру, прерывание из-за переполнения).

      Арифметика

      Продвижение/преобразование

        Унарный арифметический оператор применяется только к одному операнду. Примеры: — ,
      • В реализации присутствуют 16-битный short и 24-битный int . Если переменные x и y имеют тип unsigned short , то операция x & y продвигает оба операнда до signed int .
      • В реализации присутствуют 32-битный char и 32-битный int . Если переменные x и y имеют тип unsigned char , то операция x – y продвигает оба операнда до unsigned int .
      • (long) + (long) → (long) ;
      • (unsigned int) * (int) → (unsigned int) ;
      • (unsigned long) / (int) → (unsigned long) ;
      • если int является 32-битным, а long 64-битным: (unsigned int) % (long) → (long) ;
      • если int и long оба являются 32-битными: (unsigned int) % (long) → (unsigned long) .

      Неопределенное поведение

      Знаковое переполнение:

Похожие статьи