Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Данные и операторы программы



 

Программа в ключает два элемента:

- данные, которые размещаются а различных местах оперативной памяти;

- последовательности операторов, определяющих алгоритм преобразования данных.

 

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

 

Переменные и типы

Переменная – это имя (идентификатор) области памяти, в которой хранятся данные этой переменной.

 

Данные могут быть разных типов (символьные, целые, вещественные и т.д.).

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

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

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

Эта проблема решается использование специальных операторов объявления переменных.

 

Пример оператора объявления:

 

int var;

 

В операторе можно объявлять несколько переменных одного типа, сначала следует идентификатор типа, а затем список переменных:

 

int var1, var2, var3;

 

Пример программы, которая объявляет переменную, вводит в неё значение и выводит.

 

#include " stdafx.h"

#include < iostream>

 

using namespace std;

 

 

int _tmain(int argc, _TCHAR* argv[])

{

int var; // объвление переменной типа int

 

cout< < " Input value of int: ";

cin> > var; // ввод значения переменной

 

cout< < endl< < " var=" < < var;

 

return 0;

}

 

 

Понятие типа данных

 

Тип данных в языке программирования характеризуется именем типа и определяет такие свойства данных как:

1) формат представления данных в памяти (т.е. правила хранения данных этого типа в памяти);

2) диапазон допустимых значений этого типа, т.е. все возможные значения которые может принимать переменная этого типа (т.е. которые допускает формат представления данных этого типа);

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

 

Сообщение компилятору в программе в форме оператора объявления типа переменой позволяет компилятору правильно организовать хранение переменной и контролировать правильность её использования в действиях преобразования.

 

Основные элементарные типы данных

 

В языке С можно использовать различные типы данных: простые (элементарные), составные (сложные), пользовательские типы данных.

Ниже представлены основные элементарные типы данных.

 

тип Допустимые значения Длина в байтах
bool false (0) и true (1)
signed char -127...128
unsigned char 0...255
signed int -32768...32767
unsigned int 0...65535
signed short int -32768...32767
unsigned short int 0...65535
signed long int -2 147 483 648... 2 147 483 647
unsigned long int 0...4 294 967 295
float 3.4Е-38...3.4Е+38
double 1.7Е-308...1.7Е+308
long double 3.4Е-4932...3.4Е+4932

 

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

Для определения размера данных в программе можно использовать функцию sizeof().

 

Вызов функции, например, sizeof(long double)вернет целое значение равное числу байт требуемых для размещения в памяти данных типа long double.

 

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

 

Объявление и определение переменных в программе

 

В языке С различают понятии объявления и определения данных.

 

Объявление – указание компилятору как следует интерпретировать переменную.

 

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

В языке С объявление переменной вида:

 

ТИП имя_переменной;

 

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

 

При определении переменных в программе можно одновременно выполнить их инициализацию (присвоение начального значения переменной).

 

Пример:

 

int int_var=7;

 

Этим оператором объявляется и определяется переменная int_var, которой так же устанавливается начальное значение 7.

 

Этот оператор равносилен следующим двум:

 

int int_var;

int_var=7;

 

Константы

 

Константами называются данные, которые не могут быть изменены в программе.

 

Объявление констант реализуется как объявление переменных, значения которых нельзя менять.

Синтаксис (правила) объявления констант следующий:

 

const ТИП имя_константы=значение;

 

Пример:

 

const int const_int_var=7;

 

После такого обявления const_int_var – это константа, имеющая значение 7, которое в программе изменить не удасться.

Заметим, что инициализировать константу можно только во время ее объявления.

 

Операторы, операции и выражения

 

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

Оператор определяет операцию (действие преобразования данных). С помощью операторов строятся выражения, определяющие способ преобразования данных.

В языке С насчитывается более 40 операторов. Рассмотрим некоторые из них в их первоначальном смысле.

Арифметические операторы

 

Арифметические операции используются для выполнения преобразований над числовыми данными. Они приведены в табл.1.

Таблица 1

Арифметические операторы

Оператор Описание Применение
+ Суммирует два операнда A+B
- Вычитание из первого операнда второго A-B
* Умножение операндов A*B
/ Делит первый операнд на второй A/B
% Определяет остаток от деления первого операнда на второй A%B

 

Замечание:

1. все арифметические операторы являются бинарными.

2. *, /, % имеют более высокий приоритет чем + и -.

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

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

 

Оператор присваивания

 

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

 

Пример:

 

int_var=7;

 

При выполнении операции присваивания левому операнду присваивается значение, определяемое операндом стоящим справа, т.е. оператор выполняется справа на лево.

 

Замечание:

 

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

 

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

Сложные операторы присваивания

 

Сложные операторы присваивания реализуются составными операторами присваивания, формат записи которого следующий:

 

< *> =

где вместо < *> Допустимо использовать операторы:

 

+, -, *, /, %, < <, > >, &, ^, |

 

Например:

 

A+=B; равносилен оператору A=A+B;

Операторы отношения

 

Назначение этих операторов выполнять сравнение операндов. Результатом выполнения этих операндов является значение типа bool.

Операторы отношения приведены в табл.2.

Таблица 2

Операторы отношения

Оператор Описание Применение
== Формирует результат отношения равенства A==B
! = Формирует результат отношения не равенства A! =B
< Формирует результат отношения меньше A< B
> Формирует результат отношения больше A> B
< = Формирует результат отношения менше или равно A< =B
> = Формирует результат отношения більше или равно A> =B

 

Логические операторы

 

Используются для формирования логических выражений над данными типа bool или целочисленными (в том числе и указателями).

Логические операторы приведены в табл.3.

Таблица 3

Операторы отношения

Оператор Описание Применение
& & Операция логическое И A& & B
|| Операция логическое ИЛИ A||B
! Операция логического отрицания ! A

 

Тип результата в логических операциях – bool.

 

Оператор sizeof()

 

Оператор sizeof(oper) возвращает число байтов, требуемое для хранения объекта того типа, который имеет операнд oper.

В качестве oper может использоваться переменная, идентификатор типа или выражение.

 

2.6.7. Операторы ++ и - -

 

Это унарные операторы, т.е. они выполняются на д одним операндом.

++ - опеределяет операцию инкремента, например, х++; равносилен x=x+1;

- - - определяет операцию декремента, например, х - -; равносилен x=x-1;

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

 

Префиксные:

 

++oper

- - oper

Постфтксные:

oper++

oper - -

 

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

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

 

Например:

 

Фрагмент кода:

int a=1, b=1;

int c;

 

c=++a+b--;

 

cout< < " a=" < < a< < endl;

cout< < " b=" < < b< < endl;

cout< < " c=" < < c< < endl;

 

Приведет к выводу на консоль:

a=2

b=0

c=3

 

т.е. операции выполняются в следующей последовательности:

++a - a=2

a+b - c=3

b-- - b=0

 

Операторы проверки условия

 

Для управления порядком выполнения операторов в программе служат управляющие операторы, которые реализуют разные управляющие конструкции.

 

Оператор if

 

Организует условное выполнение оператора. Он имеет следующий синтаксис:

 

if(условие) оператор;

 

где:

 

условие – это логическое выражение;

оператор – это оператор, который будет выполняться, если результат выражения условия – true. Если результат условия false, то управление передается оператору, который записан после оператора if.

 

2.7.2. Оператор if…else

 

if(условие)

оператор1;

else

оператор2;

 

где:

 

условие – это логическое выражение;

оператор1 – это оператор, который будет выполняться, если результат выражения условия – true;

Оператор2 – это оператор, который будет выполняться, если результат выражения условия – false.

 

Оператор switch

Реализует много альтернативный if. Имеет следующий синтаксис:

 

switch(выражение)

{

case конст_выражение1: оператор1;

break;

case конст_выражение2: оператор2;

break;

 

case конст_выражениеN: операторN;

break;

 

default: оператор_default;

};

 

Логика, которую реализует этот оператор следующая.

Сначала вычисляется значение выражения в скобках. Это значение сравнивается с константными выражениями, указанными после case. Если значение выражения совпало с конст_выражениеK, то выполняется операторК, после чего, если стоит оператор break управление передается на оператор, который записан после оператора switch.

 

2.7.4. Оператор перехода на метку

 

В программе можно явно указать переход на желаемый исполняемый оператор. Для этого предусмотрены такие операторы как метка и оператор перехода на метку.

 

Оператор метка представляет собой идентификатор, после которого следует двоеточие. Если вы хотите передать управление на конкретный оператор в программе, перед ним необходимо поставить оператор метки, например:

metka: k=k+1;

 

 

Для передачи управления на метку используется оператор goto, например:

 

goto metka;

 

Операторы циклов

 

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

В языке С используются следующие операторы циклов.

 

2.8.1. Цикл while

 

Синтаксиc:

 

while(выражение)

оператор;

 

Оператор while выполняется следующим образом:

 

1) вычисляется выражение

2) если результат выражения true, то выполняется оператор,

иначе управление передается на оператор, следующий после цикла

3) выполняется переход к 1)

 

2.8.2 Цикл do while

 

Синтаксиc:

 

do

оператор;

while(выражение)

 

Оператор do while выполняется следующим образом:

 

1) выполняется оператор

2) вычисляется выражение

3) если результат выражения true, то выполняется выполняется переход к 1),

иначе управление передается на оператор, следующий после цикла

 

2.8.3. Цикл for

 

Синтаксис:

 

for(выражение_1; выражение_2; выражение_3)

оператор;

 

Оператор for выполняется следующим образом:

1) Вычисляется выражение_1. Оно обычно используется для инициализации переменных цикла. Если необходимо инициализировать несколько переменных, то операторы выражения_1 разделяются запятой.

Выражение_1 может быть опущено, но разделитель -; должен присутствовать.

2) выполняется проверка условия выполнения цикла, для чего вычисляется выражение_2. Если его значение true, то выполняется оператор, пределяющий тело цикла, иначе управление передается на оператор следующий за оператором цикла.

Выражение_2 может быть опущено, тогда считается, что условие выполнения цикла всегда истинно.

3) Выполняется выражение_3. В этом выражении обычно задается приращение переменных параметров цикла. Если необходимо указать приращение для нескольких переменных, то соответствующие операторы этого выражения разделяются запятой.

 

Выражение_3 также может быть опущено.

Если в операторе цикла опущены сразу все три выражения, то пулучаем так называемый вечны цикл:

 

for(; ; )

оператор;

 

2.8.4. Операторы continue и break

 

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

Но для циклов специально были предложены операторы continue и break.

 

Оператор continue возвращает управление к первому оператору тела цикла.

 

Оператор break передает управление на оператор за оператором цикла, т.е. приводит к завершению цикла.

 

Составной оператор

 

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

Для этого служит так называемый составной оператор или блок операторов. Он может объединять в себе целую группу операторов и использоваться там где по синтаксису можно использовать только один оператор. Блок операторов обозначается фигурными скобками. Например:

if(a< 0)

{ // начало составного оператора

c=a+b;

d+=c;

} // конец составного оператора

 

Оператор запятая

 

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

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

 

for(i=0, j=N-i; i< =N; i++, j--)

a[i]=b[j];

 

Сокращенный оператор

 

Синтаксис:

 

условие? выражение_1: выражение_2;

 

Оператор предполагает следующий порядок выполнения:

 

1) вычисляется значение выражения условие

2) если результат – true, то выполняется выражение_1, вычисленное значение которого является результатом оператора в целом.

3) Если результат – false, то выполняется выражение_2, вычисленное значение которого является результатом оператора в целом.

 

Эта форма условного оператора обычно используется, если невозможно по синтаксису применить обычный if. Например: i=a< b? 0: 1;

 

Тип указателя

Во время выполнения программы обрабатываемые данные размещаются в оперативной памяти.

Память представляет собой последовательность байт с номерами от 0 до не которого Аmax.

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

 

Переменная – это область памяти, где располагается данное. Для идентификации этой области памяти, а значит и данного используется идентификатор переменной (имя переменной). Таким образом, с идентификатором переменной фактически связан адрес этой области в памяти, а её длина определяется типом переменной.

 

Использование переменных упрощает процесс программирования, которое ведётся не в терминах адресов размещения данных в памяти, а в терминах сопоставленных им им символических имён (идентификаторов).

Но для некоторых задач необходимо иметь возможности для работы с памятью непосредственно в адресах.

Для этого в языке существует специальный тип данных – тип указателя.

 

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

 

Правила работы с указателями:

 

1) Объявление указателей

Для возможности использования переменной-указателя она должна быть объявлена:

 

ТИП *имя_указателя;

 

ТИП – определяет тип данных, адреса размещения которых будет хранить переменная имя_указателя.

 

Символ * объявляет следующую за ним переменную как указатель.

Пример:

 

int *pint; // переменная указатель на данные типа int

 

2) Инициализация указателя

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

Инициализацию можно выполнить следующими способами:

 

(1) присвоением адреса существующего объекта

 

Пример:

 

int var; // переменная целого типа

int *pint; // переменная указатель

 

pint=& var; // взятие адреса переменной и присвоение указателю

 

& - это оператор взятия адреса переменной.

Замечание:

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

 

(2) присвоением инициализированного указателя

 

int var; // переменная целого типа

int *pint1; // переменная указатель

 

pint1=& var; // взятие адреса переменной и присвоение указателю

 

 

int *pint2=pint1; // присвоение инициализированного указателя

(3) присвоения идентификатора массива

 

int mas[10]; // маccив из 10 элементов типа int

 

int *pint=mas; // имя массива в языке С трактуется как адрес 0 го

// элемента массива в памяти

 

 

(4) присвоением NULL указателя

 

NULL (константа NULL-указатель) определяет значение адреса памяти 0. Если указатель не инициализирован, то он содержит неопределенное значение, обращение к памяти по котрому может привести к ошибке.

Такой указатель рекомендуется инициализировать значением NULL.

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

 

3) Доступ (обращение) к переменной по указателю

 

Зная указатель всегда можно обратиться к переменной, на которую он указывает. Для этого используется оператор косвенности * (оператор доступа по указателю). Если р – это указатель, то *р – обозначает переменную, которая размещается по адресу, который хранит указатель р.

 

Пример:

 

int var; // переменная целого типа

int *pint1; // переменная указатель

 

pint1=& var; // взятие адреса переменной и присвоение указателю

 

 

*pint1=10; // записать по адресу, хранимому в указателе pint1 значение 10

// т.е. записать по сути в переменную var значение 10

 

4) работа с динамической памятью

 

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

 

Выделения памяти может быть выделено с использованием функции malloc() или оператора new, а овсвобождение с помощью функции free() или оператора delete.

 

1) выделение памяти с помощью функции malloc().

 

Функция имеет прототип (в alloc.h или stdlib.h):

 

void* malloc(size_t size);

 

тип size_t объявляется как typedef unsigned int size_t;

 

malloc() возвращает void* указатель на выделенную динамическую память размером size байт.

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

 

2) выделение памяти с помощью оператора new для одной переменной.

 

Оператор вида

 

указатель=new ТИП;

 

выделяет динамическую память для размещения переменной типа ТИП.

 

3) выделение памяти с помощью оператора new для массива переменных.

 

Оператор вида

 

указатель=new ТИП [число_элементов];

 

выделяет динамическую память для размещения массива типа ТИП раз мера число_элементов.

 

4) Освобождение памяти с помощью функции free().

 

Функция имеет прототип (в alloc.h или stdlib.h):

 

void* free(void* ptr);

 

освободить память по указателю ptr.

5) Освободить память оператором delete от скалярной переменной.

 

Оператор вида

 

delete указатель;

 

освобождает память от скалярной переменой, определяемую указателем.

 

6) Освободить память оператором delete от массива переменных

 

Оператор вида

 

delete [] указатель;

 

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

 

Пример:

 

#include " stdafx.h"

#include < iostream>

#include < stdlib.h>

 

using namespace std;

 

 

int _tmain(int argc, _TCHAR* argv[])

{

int *mas1, *mas2;

 

// выделить память под 10 элементов целого типа

mas1=(int*)malloc(10*sizeof(int));

mas2=new int [10];

 

for(int i=0; i< 10; i++)

mas1[i]=i+1;

 

cout< < " mas1[]: ";

for(int i=0; i< 10; i++)

cout< < mas1[i]< < " ";

 

// копируем єлементы из mas1 в mas2 в обратном порядке

for(int i=0, j=9; i< 10; i++, j--)

mas2[i]=mas1[j];

 

cout< < endl< < " mas2[]: ";

for(int i=0; i< 10; i++)

cout< < mas2[i]< < " ";

 

// освободить память

free(mas1);

delete [] mas2;

 

return 0;

}

 

7) Рекомендации при работе с динамической памятью

 

(1) переменная указатель всегда должна быть явно инициализирована либо адресом существующей переменной либо NULL-указателем.

(2) Освобождение памяти и обращение к памяти для не инициализированного указателя так же как и к NULL-указателю приводит к сбою во время работы.

(3) Перед выделением и освобождением памяти анализируйте текущее состояние переменной указателя, для которой вы собираетесь выполнять действие.

(4) Операция вида x=y, если x и y – это переменные указатели допустима, но если x хранит указатель на неосвобожденную память, то она будет потеряна.

Адресная арифметика

 

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

Пусть:

 

pe - выражение типа „указатель на Т”;

pv – переменная типа „указатель на Т”;

ie – выражение типа «целое»,

тогда:

 

val(pe+ie)ó val(pe)+val(ie)*sizeof(T)

val(pv+ie)ó pv+val(ie)*sizeof(T)

val(pe-ie)ó val(pe)-val(ie)*sizeof(T)

val(pv-ie)ó pv-val(ie)*sizeof(T)

val(++pv)ó val(pv++)ó pv+sizeof(T)

val(--pv)ó val(pv--)ó pv-sizeof(T)

pv+=ieó pv+val(ie)*sizeof(T)

pv-=ieó pv-val(ie)*sizeof(T)

 

где val() обозначает вычисление значения операции.

 

Т.е. в действиях с указателями: +, -, ++, - -, +=, -= могут быть использованы любые целочисленные значения.

При этом фактическая величина увеличения или уменьшения значения указателя зависит от его типа т.е. от размера переменной на которую он указывает.

Если к указателю на определенный тип Т прибавляется или отнимается некоторая целая константа, то значение указателя изменяется на величину этой константы, умноженную на sizeof(T).

При вычитании указателей:

 

Val(pe1-pe2) ó (val(pe1) – val(pe2))/sizeof(T)

 

И по смыслу означает целое число объектов типа Т, которые можно разместить в памяти начиная с адреса val(pe1) и до адреса val(pe2)

 

Над парой указателей можно выполнять операции отношения:

 

- pe1 Op pe2, где Op є {==,! =, <, >, < =, > =}

- операцию доступа по индексу pe[ie] ó *(pe+ie) и имеет результат типа Т.

При этом если pe – это сложное выражение не обходимо писать (pe)[ie], поскольку операция [] имеет более вісокий приоритет.

 

Тип ссылки

(не давать)

Функции

 

Программа на языке С состоит из одной или нескольких фунций.

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

 


Поделиться:



Последнее изменение этой страницы: 2017-03-14; Просмотров: 340; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.238 с.)
Главная | Случайная страница | Обратная связь