КИТ и Э КБГУ Понедельник, 06.05.2024, 20:56
Приветствую Вас Гость | RSS
Меню сайта

Наш опрос
Оцените мой сайт
Всего ответов: 118

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Типы, операторы, выражения языка С/С++

  1. Типы и размеры данных. Имена переменных. Константы. Объявления.
  2. Преобразование типов.
  3. Операторы и выражения преобразования.
  4. Приоритет и очередность вычислений.
  5. Арифметические операторы.
  6. Операторы отношения.
  7. Логические операторы.
  8. Операторы инкремента и декремента.
  9. Побитовые операторы.
  10. Условные выражения.

Практическая работа 1. Программирование арифметических операций

Практическая работа 2. Программирование с преобразованием типов

 

1. Типы и размеры данных. Имена переменных. Константы. Объявления.

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

Как константы, так и переменные могут быть различных типов, которые определяют их структуру, набор допустимых значений, правила использования и способ представления в ЭВМ. Иерархию типов данных можно представить следующей схемой.

Простые (скалярные) типы:

  • целые,
  • вещественные,
  • символьные,
  • указатели,
  • перечислимый тип.

Составные (структурированные) типы:

  • массив,
  • структура,
  • объединение.

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

Целые и вещественные переменные предназначены для хранения чисел, символьные переменные – это также числовые переменные, они хранят ASCII коды символов.

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

Массив – это группа элементов одинакового типа (double, float, int и т. п.). Из объявления массива компилятор должен получить информацию о типе элементов массива и их количестве.

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

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

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

  1. Типы данных

Числовые типы данных языка C представлены в табл. 2.1.

Таблица 2.1

Тип данных

Размер памяти, бит

Диапазон значений

char (символьный)

8

от–128 до 127

signed char (знаковый символьный)

8

от–128 до 127

unsigned char (беззнаковый символьный)

8

от 0 до 255

short int (короткое целое)

16

от–32768 до 32767

unsigned int (беззнаковое целое)

16

от 0 до 65535 (16-битная платформа)
от 0 до 4294967295 (32-битная платформа)

int (целое)

16
32

от–32768 до 32767 (16-битная платформа)

от –2147483648 до 2147483647 (32-битная платформа)

long (длинное целое)

32

от–2147483648 до 2147483647

unsigned long (длинное целое без знака)

32

от 0 до 4294967295

long long int (C99)

64

от–(263–1) до 263–1

unsigned long long int (C99)

64

от 0 до 264–1

float (вещественное)

32

от 3.4E–38 до 3.4E38

double (двойное вещественное)

64

от 1.7E–308 до 1.7E308

long double (длинное вещественное)

80

от 3.4E–4932 до 3.4E4932

_Bool (C99)

8

true(1), false(0)

bool (C++)

8

true(1), false(0)

 

В 32-разрядной ОС Windows типint занимает в памяти 32 бита, и диапазон допустимых значений для знакового int в этом случае от минус 2147483648 до 2147483647. Такое различие в размере памяти, выделяемой под переменную типа int, объясняется тем, что тип int – машинно-зависимый, и для него выделяется одно машинное слово, длина которого в 16-разрядных процессорах – 16 бит, в 32-разрядных – 32 бита.

При объявлении целых типов можно использовать ключевые слова signed и unsigned, которые указывают, как интерпретируется старший бит объявляемой переменной. Если указано ключевое слово unsigned, то старший бит интерпретируется как часть числа, в противном случае старший бит интерпретируется как знаковый. В случае отсутствия ключевого слова unsigned целая переменная считается знаковой. В том случае, если спецификатор типа состоит из ключевого типа signed или unsigned и далее следует идентификатор переменной, то она будет рассматриваться как переменная типа int. Отметим, что ключевые слова signed и unsigned не обязательны.

Однако тип char по сравнению с другими целыми типами имеет особое назначение: он используется для представления символа или объявления строковых литералов. Следует помнить, что по умолчанию тип char или signed char интерпретируется как однобайтовая целая величина со знаком и с диапазоном значений от минус 128 до 127, хотя только значения в диапазоне 0 – 127 имеют символьные эквиваленты. Для представления символов русского алфавита модификатор типа идентификатора данных имеет вид unsigned char, так как коды русских букв превышают величину 127.

 

1.2. Объявление переменных

Переменная — это именованный участок памяти, в котором хранится значение, которое может быть изменено программой.

Первый символ должен быть буквой или символом подчеркивания, последующие символы должны быть буквами, цифрами или символами подчеркивания.

Объявление переменной имеет следующий формат:

[спецификатор_класса_памяти] спецификатор_типа идентификатор [=инициатор].

Спецификатор класса памяти определяется одним из 4 ключевых слов языка C: auto,extern,register,static и указывает, во-первых, каким образом будет распределяться память под объявляемую переменную и, во-вторых, область видимости этой переменной, т. е. из каких частей программы можно к ней обратиться.

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

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

register пытается поместить переменную в регистр, доступ к которому значительно быстрее, чем к оперативной памяти. В силу того, что регистр располагает малым объемом памяти, спецификатор register не гарантирует того, что переменная будет помещена в регистр. В регистр следует помещать только такие данные, доступ к которым происходит многократно. Поскольку переменная со спецификатором register ссылается не на оперативную память, но на регист CPU, то получить адрес переменной нельзя, а значит нельзя и создать соответствующий указатель.

extern позволяет «наследовать» переменную, то есть сделать ее во истину глобальной. Вам достаточно объявить глобальную (видимую в одном файле) переменную в одном файле исходников вашей программы, а в другом вам достаточно написать:

extern <data type> <variable_name>, чтобы компилятор понял, что значение переменной с именем <variable_name> следует искать в других файлах.

 

Спецификатор типа - одно или несколько ключевых слов, определяющих тип объявляемой переменной.

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

Пример 1.

int i=5; float f=12.35; char ch='a';

int k=0, b=5, d=7;

Переменная любого типа может быть объявлена немодифицируемой, что достигается добавлением ключевого слова const к спецификатору типа. Объекты с типом const представляют собой данные, используемые только для чтения, т. е. этой переменной не может быть присвоено новое значение: например, const int a=5.

Отметим, что если после слова const отсутствует спецификатор типа, то подразумевается спецификатор типа int. Если ключевое слово const стоит перед объявлением составных типов (массив, структура, объединение), то это приводит к тому, что каждый элемент также должен являться немодифицируемым, т. е. значение ему может быть присвоено только один раз.

Ключевое слово void означает отсутствие типа.

Квалификатор volatile указывает компилятору на то, что значение переменной может измениться независимо от программы, т.е. вследствие воздействия еще чего-либо, не являющегося оператором программы. Например, адрес глобальной переменной можно передать в подпрограмму операционной системы, следящей за временем, и тогда эта переменная будет содержать системное время. В этом случае значение переменной будет изменяться без участия какого-либо оператора программы. Знание таких подробностей важно потому, что большинство компиляторов С автоматически оптимизируют некоторые выражения, предполагая при этом неизменность переменной, если она не встречается в левой части оператора присваивания. В этом случае при очередной ссылке на переменную может использоваться ее предыдущее значение. Некоторые компиляторы изменяют порядок вычислений в выражениях, что может привести к ошибке, если в выражении присутствует переменная, вычисляемая вне программы. Квалификатор volatile предотвращает такие изменения программы.

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

 

Стандарт С определяет четыре типа областей видимости идентификаторов:

Тип области видимости

Область видимости

область действия - файл (имя, объявленное вне всех блоков и классов, можно использовать в транслируемом файле, содержащем это объявление; такие имена называются глобальными (global))

Начинается в начале файла (единица трансляции) и кончается в конце файла. Такую область видимости имеют только идентификаторы, объявленные вне функции. Эти идентификаторы видимы в любом месте файла. Переменные с этой областью видимости являются глобальными)

область действия - блок

Начинается открывающейся фигурной скобкой "{" блока и кончается с его закрытием скобкой "}". Эту область видимости имеют также параметры функции. Переменные, имеющие такую область видимости, являются локальными в своем блоке

область действия - прототип функции

Идентификаторы, объявленные в прототипе функции, видимы внутри прототипа

область действия - функция (имена, объявленные в функции, могут быть использованы только в теле функции)

Начинается открывающейся фигурной скобкой "{" функции и кончается с ее закрытием скобкой "}". Такую область видимости имеют только метки. Метка используется оператором goto и должна находится внутри той же функции

 

 

Переменные, объявленные внутри функций, называются локальными переменными. В некоторых книгах по С они называются динамическими переменными. В этой книге используется более распространенный термин локальная переменная. Локальную переменную можно использовать только внутри блока, в котором она объявлена. Иными словами, локальная переменная невидима за пределами своего блока. (Блок программы — это описания и инструкции, объединенные в одну конструкцию путем заключения их в фигурные скобки.)

Локальные переменные существуют только во время выполнения программного блока, в котором они объявлены, создаются они при входе в блок, а разрушаются — при выходе из него. Более того, переменная, объявленная в одном блоке, не имеет никакого отношения к переменной с тем же именем, объявленной в другом блоке.

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

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

2. Привидение типов

Переменной (параметру функции, результату функции и т. п.) присваивается значение, имеющее не её тип:

char K = 100; short P = K;

long long T = 100L;

float R = 3;

double Z = R;

float Bound() {return 10;}

Это возможно, т. к. программа произведёт приведение типов — преобразует (приведёт) передаваемое значение к требуемому типу.

Приведение типов выполняется автоматически.

Возможны проблемы:

short P = 500; char K = P;

Значение может выходить за рамки назначаемого типа — переполнение.

При этом:

  • либо генерируется ошибка при выполнении программы (Runtime Error);
  • либо в результате получается неверное значение.

 

Приведения, не вызывающие проблем:

  • «коротких» целочисленных типов — к более «длинным» с такой же знаковостью (расширение типа):

short ← char,

 unsigned long long ← unsigned short;

  • «коротких» вещественных типов — к более «длинным» (расширение типа):

double ← float, long double ← double;

  • целых типов — к вещественным достаточной точности:

float ← char, float ← short, double ← long.

Возможны переполнения при приведении:

  • «длинных» числовых типов — к более «коротким» (сужение типа):

char ← long (500), float ← double (7.5E+50);

  • беззнаковых целочисленных типов — к знаковым целочисленным:

signed short ← unsigned short (40000);

  • знаковых целочисленных типов — к без знаковым целочисленным:
  • unsigned char ← signed char (-1).

Возможны потери точности при приведении:

  • вещественных типов — к целочисленным (отбрасывается дробная часть):

short ← float (6.9);

  • целочисленных типов — к вещественным недостаточной точности (потеря младших разрядов):

float ← long (1000000000),

double ← long long (200000000000000000).

Можно явно указать тип, к которому нужно преобразовать значение (операция приведения типа):

char K = 120; P = (short)K;

Z = (unsigned long long)40000;

return (_Bool) F;

При приведении числового типа к типу _Bool значение 0 остаётся 0, любое другое — преобразуется к значению 1.

Явное указание типа не предотвращает возможных проблем.

3. Операции

Группы операций (операторов):

  • арифметические (сложение, умножение…);
  • сравнения («равно», «меньше»…);
  • логические («не», исключающее «или»…);
  • битовые (сдвиги, битовые логические…);
  • присваивания;
  • прочие (индекс, разыменование, приведение типа, инкремент…).

Операнд — величина, над которой выполняется операция.

По числу операндов операции бывают:

  • унарные (1 операнд):

–F, (short)Z, i++;

  • бинарные (2 операнда):

a = b, 7 – t, K >> 4, L & 0xFC;

  • тернарные (3 операнда):

F ? a : b.

По способу записи унарные операции бывают:

  • префиксные — записываются перед операндом:

!K, (float)Y, ~6, –F;

  • постфиксные — записываются после операнда:

i++, j––.

4. Приоритет

Приоритет — свойство операции, влияющее на порядок вычисления её результата по отношению к другим операциям.

Приоритет выражается числом. Больше число — выше приоритет.

Операция вычисляется только после того, как над её операндами вычислены все операции с бо́льшим приоритетом:

z = C + A * (long)x + B * (long)y;

Порядок вычисления, как правило, такой:

  1. Унарные.
  2. Арифметика, сдвиги.
  3. Логика: сравнения, битовая, обычная.
  4. Условие.
  5. Присваивания.

Приоритет обычно соответствует «естественному» порядку их понимания. Приоритет можно менять с помощью скобок (): R = (2 + 2) * 2;

Ассоциативность

Ассоциативность — свойство операции, означающее порядок вычисления в цепочке операций с таким же приоритетом. Бывает:

  • слева направо: a + 7 – 2 + 6 – f — 2;
  • справа налево: a = b = c = d = 0.

На порядок вычисления операций влияют их приоритет и ассоциативность.

z = C + A * (long)x + B * (long)y;

Ассоциативность операций обычно соответствует «естественному» порядку их понимания:

  • Унарные префиксные — справа налево.
  • Унарные постфиксные — слева направо.
  • Присваивания — справа налево.
  • Остальные бинарные — слева направо.

5. Арифметические операции

Определены 5 арифметических операций:

  • сложение (+):      5 + 6, a + b + c, 1.5 + K;
  • вычитание (–): 9.0 – 7.4, -6E-3 – A;
  • умножение (*): 10 * a, k * x;
  • деление (/): 100 / 3, Prime / 5, 4.2 / 0.6;
  • получение остатка от деления (деление по модулю) (%): 100 % 3, U % p.

Операнды целые или вещественные (для % — только целые).

Тип результата — «больший» из типов операндов.

Если появляется «минус», то знаковый.

Смена знака

Определены 2 операции смены знака:

  • плюс (+):    +b, +(e - 2);
  • минус (смена знака) (–): –Y, -(B + 2).

Операнды целые или вещественные.

Тип результата — как у операнда.

Если появляется «минус», то знаковый. Возможно расширение типа.

Битовый сдвиг

Определены 2 операции битового сдвига:

  • сдвиг вправо (>>):        A >> 7, 0xFF >> p;
  • сдвиг влево (<<): 1 << p.

Операнды целые.

Тип результата — int или long long.

Второй операнд может быть отрицательным (сдвиг в обратную сторону).

Сдвиг вправо — арифметический, сохраняет старший бит (знак) операнда.

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

K << 4                   ~                 K * 16

P >> 10                 ~                 P / 1024

(для положительных P)

P >> 10                 ~                 (P - 1) / 1024

(для отрицательных P)

6. Операции сравнения

Определены 6 операций сравнения:

  • равно (==);
  • больше (>);
  • меньше (<);
  • не равно (!=);
  • меньше или равно (<=);
  • больше или равно (>=).

Операнды логического типа (целые — 0 или 1), результат логического типа.

У операций «равно» и «не равно» приоритет ниже, чем у остальных операций сравнения. Не путайте сравнение на равенство (==) с присваиванием (=).

7. Логические операции

Определены 7 логических операций:

Логические:

  • «НЕ» (!);
  • «И» (&&);
  • «ИЛИ» (||).

Битовые:

  • «НЕ» (~).
  • «И» (&);
  • «ИЛИ» (|);
  • исключающее «ИЛИ» (^).
  • Операции «НЕ» — префиксные: ~P, !(K > 5).
  • Типы операндов и результата битовых операций — int или long long, логических — логический.

8. Приращения

Определены 4 операции приращения:

  • префиксный инкремент (++): ++P;
  • префиксный декремент (––): ––P;
  • постфиксный инкремент (++): P++;
  • постфиксный декремент (––): P––.

Увеличивают (уменьшают) значение операнда на единицу. Операнд — только переменная.

Результат того же типа, что и операнд.

Префиксный инкремент (декремент) изменяет значение аргумента и возвращает его новое значение:

k = 7; p = ++k;                                  k = 8, p = 8

k = 7; p = ––k;                                   k = 6, p = 6

Постфиксный инкремент (декремент) возвращает текущее значение аргумента и только потом его изменяет:

k = 7; p = k++;                                  k = 8, p = 7

k = 7; p = k––;                                   k = 6, p = 7

 

9. Присваивания

Определены 10 операций присваивания:

=, +=, –=, *=, /=, %=, <<=, >>=, &=, ^=, |=.

Левый операнд — только переменная.

Сами возвращают присвоенное значение с типом левого операнда: a = b + (c = 6) * 2.

Присваивания с операциями работают так:

k += 7;                            аналогично         k = k + 7;

T *= 7 + e;   аналогично         T = T * (7 + e);

Приоритет — низкий.

Ассоциативность — справа налево.

10. Условие

Единственная тернарная операция— условие:

операнд1 ? операнд2 : операнд3

Если значение первого операнда «истинно» (не ноль), то возвращает второй операнд, иначе возвращает третий операнд:

если операнд1 , то операнд2 , иначе операнд3

max = x > y ? x : y;

sign = a == 0 ? 0 : a > 0 ? 1 : -1;

Ассоциативность — справа налево.

 

Вход на сайт

Поиск

Календарь
«  Май 2024  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031

Архив записей

Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz

  • Copyright Fatima_Zh © 2024Бесплатный хостинг uCoz