Файл: ПОНЯТИЕ ПЕРЕМЕННОЙ В ПРОГРАММИРОВАНИИ. ВИДЫ И ТИПЫ ПЕРЕМЕННЫХ (Простые и сложные типы данных).pdf
Добавлен: 01.04.2023
Просмотров: 428
Скачиваний: 1
Класс памяти extern обычно используется в двух случаях:
- если используемая переменная в программе объявляется ниже, чем ссылка на неё;
- если переменная объявляется в другом модуле.
Пример использования внешней переменной:
#include <stdio.h>
int x=145; //Описание внешней переменной
main()
{
extern int x,y;
printf("x=%d y=%d \n",x,y);
}
int y=541; //Описание внешней переменной
Внешние переменные могут быть определены вне какой-либо функции. При этом выделяется фактическая память. В любой другой функции, обращающейся к этим переменным, они должны описываться с помощью описателя extern.
2. Простые и сложные типы данных
2.1. Целочисленные типы
Целочисленный тип данных – один из простейших и самых распространенных типов данных в языках программирования. Множество чисел этого типа представляет собой конечное подмножество бесконечного множества целых чисел, ограниченное максимальным и минимальным значениями.
Целочисленные данные могут быть представлены или в знаковой, или в беззнаковой форме.
Беззнаковые целые числа представлены в виде последовательности битов в диапазоне от 0 до 2n-1, где n-количество занимаемых битов.
Знаковые целые числа представляются в диапазоне от -2n-1 до +2n-1-1. При этом старший бит знаковых чисел отводится для знака числа (0 соответствует положительному числу, 1 – отрицательному).
Основные типы и размеры целочисленных данных представлены в таблице 1.
Таблица 1. Целочисленные типы
|
Количество бит |
Беззнаковый тип |
Знаковый тип |
|
8 |
unsigned char |
char |
|
16 |
unsigned short |
short |
|
32 |
unsigned int |
int |
|
64 |
unsigned long int |
long int |
Над целочисленными переменными может быть выполнено множество операции. Некоторые, наиболее популярные, приведены ниже:
- сравнение. Сюда относятся сравнение на равенство и не равенство, отношения порядка (больше/меньше, больше/меньше или равно);
- инкремент и декремент – арифметическое увеличение и уменьшение числа на единицу;
- арифметические операции – сложение, вычитание, умножение, деление, получение остатка от деления;
- инверсия и получение знака.
Также переменным целочисленного типа могут быть применены побитовые операции – сдвиги, побитовое «И», «ИЛИ» и другие. [6]
2.2. Вещественные типы
Вещественный тип в языке Си предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме.
Нормированная форма числа предполагает наличие одной значащей цифры (не 0) до разделения целой и дробной части. Такое представление умножается на основание системы счисления в соответствующей степени. Например, число 12345,678 в нормированной форме можно представить как
12345,678 = 1,2345678·104
Число 0,009876 в нормированной форме можно представить как
0,009876 = 9,876·10-3
В двоичной системе счисления значащий разряд, стоящий перед разделителем целой и дробной части, может быть равен только 1. В случае если число нельзя представить в нормированной форме (например, число 0), значащий разряд перед разделителем целой и дробной части равен 0.
Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа.
В общем случае вещественное число в разрядной сетке вычислительной машины можно представить в виде 4 полей. Графическое изображение полей представлено на рисунке 2.
Рисунок 2
- знак — бит, определяющий знак вещественного числа (0 для положительных чисел, 1 — для отрицательных);
- порядок — определяет степень 2, на которую требуется умножить число в нормированной форме. Поскольку степень 2 для числа в нормированной форме может быть как положительной, так и отрицательной, нулевой степени 2 в представлении вещественного числа соответствует величина сдвига, которая определяется как
2n-1, где n — количество разрядов, отводимых для представления степени числа; - целое — бит, который для нормированных чисел всегда равен 1, поэтому в некоторых представлениях типов этот бит опущен и принимается равным 1;
- мантисса — значащие разряды представления числа, стоящие после разделителя целой и дробной части в нормированной форме.
В языке Си представлены три основных типа представления вещественных чисел. Они приведены в таблице 2.
Таблица 2. Представление вещественных типов
|
Тип |
Обозначение в Си |
Кол-во бит |
Биты степени |
Мантисса |
Сдвиг |
|
простое |
float |
32 |
30…23 |
22…0 |
127 |
|
двойной точности |
double |
64 |
62…52 |
51…0 |
1023 |
|
двойной расширенной точности |
long double |
80 |
78…64 |
62…0 |
16383 |
2.3 Символьный тип
Символьный тип в языке Си хранит код символа и используется для отображения символов в различных кодировках. Для хранения кодов символов в языке Си используется тип char.
Фактически, тип char является целочисленным однобайтным типом. Значение переменной типа char в программе, например при выводе, может выводиться и как целое, и как символ. Например, код ниже:
#include <stdio.h>
int main()
{
char c = 66;
printf("as int %d. as char %c", c, c);
return 0;
}
выведет следующий результат:
as int 66. as char В
2.4. Логический тип
Логический тип применяется в логических операциях, а также используется при алгоритмических проверках условий и в циклах и может принимать одно из двух значений:
- истина — true;
- ложь — false.
2.5. Структуры
Структура – это объединенное в единое целое множество поименованных элементов данных. В отличии от массива, всегда состоящего из однотипных элементов, компоненты структуры могут быть разных типов и все должны иметь различные имена. [11]
Синтаксис объявления структуры достаточно прост, и представлен ниже:
struct <имя> {
<тип1> <поле1>;
...
<типN> <полеN>;
};
После ключевого слова struct идет имя структуры, после в фигурных скобках перечисляются поля структуры. Элементы <типN> и <полеN> описывают, соответственно, тип и имя соответствующего поля.
После того, как мы объявили структуру, можно создавать переменную такого типа с использованием служебного слова struct. Доступ до полей структуры осуществляется с помощью операции точка. Ниже приведен пример использования структуры в коде программы:
struct point_t {
int x;
int y;
};
void main() {
struct point_t A = { 5, 15 };
A.x = 10;
A.y = 20;
}
В данном примере структура A сначала была проинициализирована, после чего были изменены значения её полей.
2.6. Объединения
Объединения в языке Си несколько похожи на структуры. Особенностью объединения в Си является то, что все поля объединения имеют одинаковый адрес в памяти. Это приводит к тому, что в данный момент можно определить значение только одного поля объединения в Си.
Память для объединения выделяется по размеру самого длинного из полей. Когда определяется значение одного из полей – то оно затирает предыдущее значение любого поля. [10]
Пример объявление и использования объединений представлен ниже:
union myUnion
{
int x;
double d;
};
void main(void)
{
union myUnion uUnion = {150};
uUnion.d = 123.12;
}
2.7. Массивы
Язык Си предоставляет возможность создания массивов для описания набора переменных с идентичными свойствами. Все члены массива доступны по имени массива, а каждый отдельный элемент получается по своему индексу. Пример объявления массива:
double ar[100];
Именем массива выступает ar, массив объявляется на 100 элементов, и все элементы доступны через индексы от 0 до 99 включительно. Для доступа к конкретному индексу используется синтаксис ar[5].
Каждый из элементов массива принадлежит к типу, указанному при описании массива, в нашем примере типу double. [9]
2.8. Приведение типов
Операция приведения типа в языке Си временно изменяет тип переменной с одного на другой. Ниже приведен формат операции приведения типа:
(<типДанных>)<значение>
Элемент <типДанных> может быть любым типом данных языка Си, например int или float. Элемент <значение> — это любая переменная, литерал или выражение.
Предположим, что целочисленная переменная age содержит значение 6, следующая строка конвертирует это значение в значение с плавающей точкой 6.0:
(float)age;
Целочисленная переменная age не превращается в переменную типа float, а лишь временно приводится к этому типу только для вычисления значения этого выражения. В остальных участках программного кода, где тип переменной age не приводится, эта переменная так и остается целочисленной. [5]
3. Указатели
Указатель — переменная, содержащая адрес объекта. Указатель не несет информации о содержимом объекта, а содержит сведения о том, где размещен объект. [7]
Указатель объявляется также, как и любая другая переменная, но после имени типа ставится звездочка.
int *pointerToInteger;
Здесь объявляется переменная pointerToInteger.
Тип данной переменной – указатель на переменную типа int.
Рассмотрим две переменные: первая - целочисленная переменная x. Вторая - указатель на целочисленную переменную.
int x;
int *p;
Чтобы получить адрес переменной, нужно перед ее именем написать амперсанд.
p = &x;
Данная конструкция будет выполняться справа налево. Сначала с помощью оператора &, примененного к переменной x, будет получен адрес x. Затем адрес x будет сохранен в указателе p.
Есть и обратная операция. Чтобы получить значение переменной по ее адресу, следует написать звездочку перед именем указателя.
int y = *p;
Такая операция в русском языке называется разыменование.
В данном примере с помощью оператора * мы получим то значение, которое находится в памяти по адресу p. Затем мы сохраним его в переменную y. В итоге получится, что значения x и y совпадают. [2]
Одной из более распространенных конструкций с использованием указателей являются массивы. Результатом использования указателей для массивов являются меньшее количество используемой памяти, а также высокая производительность. Если был создан массив values, который содержит 100 целочисленных переменных, можно создать указатель с именем valuesPtr, который будет использоваться для доступа к значениям элементов массива. Например
int *valuesPtr;
valuesPtr = values;
В данном случае указатель valuesPtr будет ссылаться на первый элемент массива values. Оператор адресации в данном случае не используется, так как компилятор языка Си трактует имя массива без индекса как указатель на массив. [8]
Для обращения к третьему элементу массива (values[3]) с помощью указателя valuesPtr можно воспользоваться следующей записью:
* (valuesPtr + 3)
В общем случае используется выражение:
* (valuesPtr + i)
где i – индекс нужного элемента массива.
Заключение
В процессе знакомства и изучения языка программирования Си, приходит понимание, что даже сейчас данный язык остается очень полезным, важным и в том числе, фундаментальным при изучении технологий программирования.
Язык Си предоставляет возможность программисту получения прямого доступа к ячейкам памяти, регистрам компьютера. Такое поведение частично напоминает язык низкого уровня Ассемблер. Хотя на самом деле, Си представляет более универсальные и мощные возможности для разработки программного обеспечения, решения трудных задач и создания сложных программных систем.
В данной курсовой работе были рассмотрены самые базовые понятия, которые используются в программировании на Си. Это знакомство с переменными, типами данных.
Эти элементы постоянно используются при разработке. Практически каждая строчка кода содержит как минимум одну переменную.
Поэтому правильное понимание принципов работы переменных, различий между типами данных, способом хранения данных в памяти позволяет программисту создавать эффективные решения, которые наилучшим образом будут решать прикладные задачи.