Типы данных в языке Си

Язык Си / Типы данных в языке Си

 

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

Процесс проверки и накладывания ограничений на типы используемых данных называется контролем типов или типизацией программных данных. Различают следующие виды типизации:

  • Статическая типизация — контроль типов осуществляется при компиляции.
  • Динамическая типизация — контроль типов осуществляется во время выполнения.

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

Различают простые, составные и прочие типы данных.

 

Простые данные

Простые данные можно разделить на

  • целочисленные,
  • вещественные,
  • символьные
  • логические.

 

Составные (сложные) данные

  • Массив — индексированный набор элементов одного типа.
  • Строковый тип — массив, хранящий строку символов.
  • Структура — набор различных элементов (полей записи), хранимый как единое целое и предусматривающий доступ к отдельным полям структуры.

 

Другие типы данных

  • Указатель — хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило — указатель на переменную.

 
Программа, написанная на языке Си, оперирует с данными различных типов. Все данные имеют имя и тип. Обращение к данным в программе осуществляется по их именам (идентификаторам).

Идентификатор — это последовательность, содержащая не более 32 символов, среди которых могут быть любые буквы латинского алфавита a — z, A — Z, цифры 0 — 9 и знак подчеркивания (_). Первый символ идентификатора не должен быть цифрой.

Несмотря на то, что допускается имя, имеющее до 32 символов, определяющее значение имеют только первые 8 символов. Помимо имени, все данные имеют тип. Указание типа необходимо для того, чтобы было известно, сколько места в оперативной памяти будет занимать данный объект.

Компилятор языка Си придерживается строгого соответствия прописных и строчных букв в именах идентификаторов и лексем.

Верно Неверно
int a = 2, b;
b = a+3;
Int a=2;  // правильно int
INT a=2;
int a = 2, b;
b = A + 3; // идентификатор А не объявлен
int a = 2;
b = a + 3; // идентификатор b не объявлен

Целочисленные данные

Целочисленные данные могут быть представлены в знаковой и беззнаковой форме.

Беззнаковые целые числа представляются в виде последовательности битов в диапазоне от 0 до 2n-1, где n-количество занимаемых битов.

Знаковые целые числа представляются в диапазоне -2n-1…+2n-1-1. При этом старший бит данного отводится под знак числа (0 соответствует положительному числу, 1 – отрицательному).

Основные типы и размеры целочисленных данных:

Количество бит Беззнаковый тип Знаковый тип
8 unsigned char
0…255
char
-128…127
16 unsigned short
0…65535
short
-32768…32767
32 unsigned int int
64 unsigned long int long int

Вещественные данные

Вещественный тип предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме.

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

12345,678 = 1,2345678·104

Число 0,009876 в нормированной форме можно представить как

0,009876 = 9,876·10-3

В двоичной системе счисления значащий разряд, стоящий перед разделителем целой и дробной части, может быть равен  только 1. В случае если число нельзя представить в нормированной форме (например, число 0), значащий разряд перед разделителем целой и дробной части равен 0.

Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа.

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

  • знак — бит, определяющий знак вещественного числа (0 для положительных чисел, 1 — для отрицательных).
  • степень — определяет степень 2, на которую требуется умножить число в нормированной форме. Поскольку степень 2 для числа в нормированной форме может быть как положительной, так и отрицательной, нулевой степени 2 в представлении вещественного числа соответствует величина сдвига, которая определяется как

    2n-1,

    где n — количество разрядов, отводимых для представления степени числа.

  • целое — бит, который для нормированных чисел всегда равен 1, поэтому в некоторых представлениях типов этот бит опущен и принимается равным 1.
  • мантисса — значащие разряды представления числа, стоящие после разделителя целой и дробной части в нормированной форме.

 
Различают три основных типа представления вещественных чисел в языке Си:

Тип Обозна-
чение в Си
Кол-во бит Биты степени Мантисса Сдвиг
простое float 32 30…23 22…0 127
двойной точности double 64 62…52 51…0 1023
двойной расширен- ной точности long double 80 78…64 62…0 16383

Как видно из таблицы, бит целое у типов float и double отсутствует. При этом диапазон представления вещественного числа состоит из двух диапазонов, расположенных симметрично относительно нуля. Например, диапазон представления чисел типа float можно представить в виде:
Число типа float

Пример: представить число -178,125 в 32-разрядной сетке (тип float).

Для представления числа в двоичной системе счисления преобразуем отдельно целую и дробную части:

17810 = 101100102.

0,12510 = 0,0012.

Тогда

178,12510 = 10110010,0012=1,0110010001·2111

Для преобразования в нормированную форму осуществляется сдвиг на 7 разрядов влево).

Для определения степени числа применяем сдвиг:

0111111+00000111 = 10000110.

Таким образом, число -178,125 представится в разрядной сетке как

Представление числа в разрядной сетке float

 

Символьный тип

Символьный тип хранит код символа и используется для отображения символов в различных кодировках. Символьные данные задаются в кодах и по сути представляют собой целочисленные значения. Для хранения кодов символов в языке Си используется тип char.
Подробнее о кодировке символов

 

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

Логический тип применяется в логических операциях, используется при алгоритмических проверках условий и в циклах и имеет два значения:

  • истина — true
  • ложь — — false

В программе должно быть дано объявление всех используемых данных с указанием их имени и типа. Описание данных должно предшествовать их использованию в программе.

Пример объявления объектов

 
 
int n;    // Переменная n целого типа
double a; // Переменная a вещественного типа двойной точности


Назад: Язык Си

Комментариев к записи: 37

  • Здравствуйте форумчане ! Не могу найти объяснения в простейшей программке:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <stdio.h>
    #include <stdlib.h>

    int main()
    {     //float a,b,e,f;
         double a,b,e,f;
          b=0;        //Начало счёта
          e=10 ;     //// КОНЕЦ СЧЁТА
          f=0.05;     /*  Приращение */
          for (a=b;a<=e;a=a+f)
         {
           printf("%.3f\t",a);
         }
        printf("\n");
        printf("Last A= %.18f\n",a);
        printf("     F=   %.18f     0x%x\n\n",f,f);// Вот он "ПОЛТЕРГЕЙСТ" !!!
        printf("Prob 1-2 Poltergeist\n");
        return 0;
    }
    Переменная F больше на 0.(17 нулей)3 чем заданное значение f=0.05, т.е на самом деле f=0,050000000000000003. И эти 0.(17 нулей)3 в цикле не дают "досчитать" до 10. Если переменные заявить как float, то картина будет ещё веселее. Если кто знает как с этим бороться, поясните плиз. Объявление переменных long double не работает- возвращаются нули.

    • Проблема известная и заключается в ограниченной разрядной сетке и представлении в ней вещественных чисел. Именно поэтому крайне не рекомендуется использовать проверку на равенство вещественных чисел. Используйте нестрогие неравенства в условиях, чтобы можно было не рассматривать в условиях "семнадцать нулей".



    • Елена Вставская
      Для этого лучше воспользоваться бытовыми полями в языке Си. Но данные будут сохраняться всё равно кратно байтам. Интересна цель для 5-битных данных. Где они будут использоваться?

    • вводи . Но будь окуратен бывали случаи что люди погибали при 5 бит от интерполяции частиц матрицы во второй степени.

  • Александр
    Здравствуйте) Задана переменная w типа беззнаковый символ и равная 241. Какое значение примет она после выполнения операции: w&=0xC7; Вот код:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <iostream>
    using namespace std;


    void main()
    {
      unsigned char w = 241;
      w &= 0xC7;
      cout << w << endl;



    }
    При компиляции в visual 17 выводится непонятный символ и всё. Подскажите пожалуйста, в чём ошибка?

    • Елена Вставская
      Поскольку код переменной больше 127, это вторая половина ASCII-таблицы. А кодовая страница в windows и в консоли не совпадает. Поэтому и символ в консоли может отличаться от ожидаемого. Посмотрите тему "создание консольного приложения" на сайте.


    • Елена Вставская
      Перенести место объявления переменной за пределы всех функций

  • Здравствуйте! Не могли бы вы подсказать где здесь ошибка:
    1
    2
    3
    double k=1.00;
    int i=2, q=3;
    k +=(double)(i/q);
    k дает результат 0. Уверенна, что ошибка в типах, но не могу найти.

    • Елена Вставская
      Ошибка в порядке действий
      1
      k +=((double)i)/q;
      В Вашем случае сначала целое 2 делится на 3. Получается 0. А затем этот 0 приводится к типу double. Я сначала привожу 2 к типу double, а потом делю уже вещественное число.

  • Можете подсказать как выполнить это задание: Из стандартного ввода загрузите два целых числа в диапазоне [-10 000; 10 000] , включая экстремальные значения.

  • Григорий
    Всем доброго время суток! Я совсем начинающий , поэтому не посылайте сразу. Подскажите как в while(1){} переменной присвоить(определить) тип данных? Именно в цикле. Пример:(естественно компилятор ругается)
    1
    2
    3
    4
    5
    6
    7
    8
    while (1) 
        {
        if(~PINB&(1<<0))
        {
          _delay_ms(200),(unsigned char x ++);// ???
          ICR1= uint16_t(f_pwm-=200);//???
          
        }

    • Елена Вставская
      Не понятно, что за переменная x и зачем она нужна? В ней и проблема. Что предполагалось сделать в этой строчке?

      • Григорий
        Елена, спасибо что ответили!!! Я учусь программировать микроконтроллеры. Я написал кусок кода где инкрементирую нажатие кнопки (x). Я читаю статьи из нета, где-то попадался код в котором автор в цикле определяет тип данных. На тот момент мне без надобности а сейчас уже и не найду где видел. Не только в х проблема, еще компилятор ругается на
        1
        ICR1= uint16_t(f_pwm-=200);
        f_pwm тоже переменная. Было-бы красиво определить их в цикле а не в шапке проекта. В связи с выше изложенным - Вопрос не отпал.

        • Елена Вставская
          Надеюсь, что регистр ICR1 16- битный? В этом случае корректнее записать так:
          1
          2
          f_pwm-=200;
          ICR1=(uint16_t)f_pem;

          • Григорий
            Спасибо!!! Я все понял, не нужно в одной строке стока заданий путать. ICR1= uint16_t(f_pwm-=200). Нужно как Вы написали. Спасибо. Буду к Вам обращаться.


  • Алексей
    Объясните пожалуйста что значит фраза "определяющее значение имеют только первые 8 символов". Спасибо.

    • Елена Вставская
      Различие в именах переменных должно содержаться в первых 8 символах.

  • Николай
    В абзаце: "Для определения степени числа применяем сдвиг: 0111111+00000111 = 10000110." видимо есть ошибка вместо 0111111, должно быть число 1111111, если я всё правильно понял.

    • Елена Вставская
      Нет, ошибки нет. В качестве сдвига берется число, у которого старший разряд равен 0, а все остальные равны 1 (середина диапазона). И к этому числу добавляется положительная или отрицательная степень представляемого в разрядной сетке числа.

      • Александра
        Для определения степени числа применяем сдвиг:
        0111111+00000111 = 10000110.
        А что эта степень тогда значит? И почему мы ее именно так получаем?

        • Елена Вставская
          Степень числа может быть как положительной, так и отрицательной. Нулевой степени соответствует величина сдвига. Если нормированное число должно быть умножено на 2 в нулевой степени, то в биты степени записывается 011...1.


  • Владимир
    В разделе Логический тип "Логический тип имеет применяется в логических операциях" слово "имеет", наверное, лишнее.

  • не имеет значения
    "Обращение к данному в программе осуществляется по его имени (идентификатору)" возможно опечатка в слове "данному"

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *