Операции и основные типы данных 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Операции и основные типы данных



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

Большинство операторов является операторами выражение, которые имеют вид

          выражение;

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

Составной оператор, или блок

Составной оператор (называемый также "блок", что эквивалентно) дает возможность использовать несколько операторов в том месте, где предполагается использование одного:

          составной_оператор:          { список_описаний opt список_операторов opt }          список_описаний:          описание          описание список_описаний          список_операторов:          оператор          оператор список_операторов

Если какой-либо из идентификаторов в списке_описаний был ранее описан, то внешнее описание выталкивается на время выполнения блока, и снова входит в силу по его окончании.

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

Условный оператор

Есть два вида условных операторов

          if (выражение) оператор          if (выражение) оператор else оператор

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

Оператор whilе

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

          while (выражение) оператор

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

Оператор dо

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

          do оператор while (выражение);

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

Оператор for

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

          for (выражение_1 opt; выражение_2 opt; выражение_3 opt)          оператор

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

          выражение_1;          while                                       (выражение_2)                                                                  {                                                           оператор                                                       выражение_3;          }

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

Каждое или все выражения могут быть опущены. Отсутствие выражения_2 делает подразумеваемое while-предложение эквивалентным while(1); остальные опущенные выражения просто пропускаются в описанном выше расширении.

Оператор switch

Оператор switch вызывает передачу управления на один из нескольких операторов в зависимости от значения выражения. Он имеет вид

          switch (выражение) оператор

Выражение должно быть целого типа или типа указателя. Любой оператор внутри оператора может быть помечен одним или более префиксом case следующим образом:

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

где константное выражение должно иметь тот же тип что и выражение- переключатель; производятся обычные арифметические преобразования. В одном операторе switch никакие две константы, помеченные case, не могут иметь одинаковое значение.

Может также быть не более чем один префикс оператора вида

          default:

Когда выполнен оператор switch, проведено вычисление его выражения и сравнение его с каждой case константой. Если одна из констант равна значению выражения, то управление передается на выражение, следующее за подошедшим префиксом case. Если никакая case константа не соответствует выражению, и есть префикс default, то управление передается на выражение, которому он предшествует. Если нет соответствующих вариантов case и default отсутствует, то никакой из операторов в операторе switch не выполняется.

Префиксы case и default сами по себе не изменяют поток управления, который после задержки идет дальше, перескакивая через эти префиксы. Для выхода из switch.

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

Оператор break

Оператор

          break;

прекращает выполнение ближайшего охватывающего while, do, for или switch оператора; управление передается на оператор, следующий за законченным.

Оператор contiпие

Оператор

          continue;

вызывает передачу управления на управляющую продолжением цикла часть наименьшего охватывающего оператора while, do или for; то есть на конец петли цикла. Точнее, в каждом из операторов

          while (...)    do             for (...)          {              {              {         ...           ...           ...          contin:;       contin:;       contin:;          }              }              }                         while (...);

continue эквивалентно goto contin.

Оператор returп

Возврат из функции в вызывающую программу осуществляется с помощью оператора return, имеющего один из двух видов:

           return;          return выражение;

Первый может использоваться только в функциях, не возвращающих значения, т.е. в функциях с типом возвращаемого значения void. Вторая форма может использоваться только в функциях, не возвращающих значение; вызывающей функцию программе возвращается значение выражения. Если необходимо, то выражение преобразуется, как это делается при присваивании, к типу функции, в которой оно возникло. Обход конца функции эквивалентен возврату return без возвращаемого значения.

Оператор gotо

Можно осуществлять безусловную передачу управления с помощью оператора

           goto идентификатор;

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

Помеченные операторы

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

          идентификатор:

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

Пустой оператор

Пустой оператор имеет вид

         ;

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

Оператор deletе

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

          delete выражение;

Результатом выражения должен быть указатель. Объект, на который он указывает, уничтожается. Это значит, что после оператора уничтожения delete нельзя гарантировать, что объект имеет определенное значение; Эффект от применения delete к указателю, не полученному из операции new не определен. Однако, уничтожение указателя с нулевым значением безопасно.

Оператор asм

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

          asm (строка);

Смысл оператора asm не определен. Обычно он используется для передачи информации через компилятор ассемблеру.

 

Массивы. Разработка программ с использованием одномерных и двумерных массивов.

Массивтер. Бірөлшемді және екіөлшемді массивтерді қолдану арқылы программаны өңдеу.

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

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

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

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

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

Описание массива

В C++ можно определить массив любого типа.

int mas[3];

Описан массив из 3 целых чисел.

Нумерация в массивах начинается с 0-го элемента. Поэтому массив mas содежит: mas[0], mas[1], mas[2]

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

int mas[]={23, 25, 81};

Далее создан массив mas из 3-х элементов:

mas[0]= 23,

mas[1]= 25,

mas[2]= 81.

 

char city [ ] = "Москва";

Массив city будет содержать строку из 7 элементов: 6 букв и 0-символ. 0-символ является признаком конца строки, в программе он обозначается \0.

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

Можно описать название города по-другому.

char city1[ ] = {'М', 'о', 'с', 'к', 'в', 'а' }

Массив city1 - это массив символов, он будет содержать 6 элементов

Таблица 1.7.1.

City City1
0 М 0 М
1 О 1 о
2 С 2 с
3 К 3 к
4 В 4 в
5 А 5 а
6 /0    

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

city [0]='м';

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

int m[6] = {4, 3, 1, 4, 7, 8 };

m[3] или (m + 3)[0]       Обращение к 4-му элементу массива.

 Возможны и другие варианты:

(m + 0)[3]

(m + 2)[1]

(m - 2)[5]

Наиболее полезно использовать такой подход к массивам, содержащим символьные строки.

Пример.

char names [ ]={'Иван', 'Петр', 'Елена' }

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

Таблица 1.7.2.

0 И
1 В
2 А
3 Н
4 \0
5 П
6 Е
7 Т
8 Р
9 \0
10 Е
11 Л
12 Е
13 Н
14 А
15 \0

Команда cout << names; выведет Иван (до признака конца строки)

cout << names+5; выведет Петр.

Многомерные массивы

Многомерные массивы - это массивы с более чем одним индексом.

Чаще всего используются двумерные массивы.

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

Пример 1.

int t[3][4];

Описывается двумерный массив, из 3 строк и 4 столбцов.

Элементы массива:

t[0][0] t[0][1] t[0][2] t[0][3]

t[1][0] t[1][1] t[1][2] t[1][3]

t[2][0] t[2][1] t[2][2] t[2][3]

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

Пусть это линейка памяти:

Рисунок 1.7.1.

Пример 2.

int temp [3] [15] [10];

резервируется место под 3-х мерный массив.

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

Рассмотрим на примере двумерного массива.

int a[3][2]={4, l, 5,7,2, 9};

Представляется в памяти:

Таблица 1.7.3.

a[0][0] заносится значение 4
a[0][1] заносится значение 1
a[1][0] заносится значение 5
a[1][1] заносится значение 7
a[2][0] заносится значение 2
a[2][1] заносится значение 9

Второй способ инициализации при описании массива

int а[3][2]={ {4,1}, {5, 7}, {2, 9} };

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

cout<< а[0][0];

Выдаст значение 4.

cout << a[1][1];

Выдаст знaчение 7.

Программа, которая инициализирует массив и выводит его элементы на экран.

#include <iostream.h>

main ()

{

int a[3] [2]={

{1,2}, {3,4}, {5,6}

};

int i,j;

for (i=0; i<=2; i++)

for(j=0;j<=l;j++)

 cout <<"\n a["<< i <<"," << j <<"] ="<< a[i]|j];

return 0;

}

Для того, чтобы убрать из программы явные значения размера и массива, можно воспользоваться директивой define

#include < iostream.h>

#define I 3

#define J 2

main()

{ int a[I][J]={ {l,2}, {3,4}, {5,6} };

int i, j;

for (i=0; i< I; i++)

for(j=0; j< J; j++)

cout <<"\n a["<< i <<"," << j << "] ="<< a[i][j];

return 0;

}

При передаче массива в функцию всегда происходит передача его адреса. Т.о. в C++ все массивы передаются по адресу.

Пример.

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

#include <iostream.h>

 

void vvod (int u[10][10], int n)

{

 int i,j;

 for (i=0; i<n; i++)

 { cout <<"\nVvedi "<< i<<" stroky";

for (j=0; j< n; j++)

cin>> u[i][j];

 }

}

 

void main()

{

int a[10][10];

int n,i,j,min;

cout<<"\nВведите количество строк и столбцов";

cin>>n;

vvod(a, n);

for (i=0; i< n; i++)

 for (j=0; j< n; j++)

if (a[i][j] < 0) a[i][j]=-a[i][j];

 

// Вывод матрицы

cout <<"\n";

for (i=0; i< n; i++)

{

for (j=0; j< n; j++)

cout<< u[i][j]<<" ";

cout<<"\n";

}

}

Принимающая функция получает не весь массив, а только адрес первого элемента массива. Несмотря на то, что в блоке main массив называется а, а в функции vvod - u это один и тот же массив.

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

Си-дегі функциялар. Функцияны құру және қолдану. Жадылар кластары ж ә не программаны өң деу.

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

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

 

Определение функции

Определение функции должно располагаться в глобальной области видимости, до начала функции main. Рассмотрим пример, простого определения:

 

int simple_function ()

{

return 0;

}

Определение функции состоит из заголовка и тела. Заголовок фукнции включает в себя:

Тип возвращаемого значения

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

 

int simple_function()

float simple_function()

char simple_function()

 

В первом случае функция должна вернуть целое число (int), во втором - вещественное число (float), а в третьем случае - символ (char).

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

 

Тело функции

Тело функции располагается сразу под заголовком и заключено в фигурные скобки. В теле функции может содержаться сколько угодно операторов. Но обязательно должен присутствовать оператор return. Оператор return возвращает значение:

int simple_function ()

{

return 0;

}

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

int sum (int a, int b)

{

int c;

c = a + b;

return c;

}

В функцию передаётся два аргумента: a и b типа int. В теле функции они используются как обычные переменные (они и являются обычными переменными). Давайте договоримся: снаружи функции, переменные, которые передаются в неё, мы будем называть аргументами, а эти же переменные в теле функции - параметрами.

В теле функции определяется переменная c. А затем, в эту переменную мы помещаем значение суммы двух параметров.

Последняя строчка возвращает значение переменной c во внешнее окружение.

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

return 32;

return a;

return b;

return a+b;

В последнем случае в вызывающее окружение будет возвращён результат суммы переменных a и b.

Обратите внимание, что оператор return не только возвращает значение, но и служит как бы выходом из функции, после него не будет выполнен ни один оператор:

return a;

c = a+b; // этот оператор не будет выполнен

Благодаря этому, с помощью return удобно создавать условия выхода из функций:

if (a > 0)

{

return 0;

}

else if (a < 0)

{

return 1

}

Здесь, из функции будет возвращено число в зависимости от значения переменной a: если a больше нуля, то будет возвращён 0, в противном случае - 1.

 

Вызов функции

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

int sum (int a, int b)

{

int c;

c = a + b;

return c;

}

 

int main()

{

int s;

s = sum(2,2); // вызов функции

cout << s;

return 0;

}

В результате выполнения программы, на экран будет выведено: 4.

Вызов функции состоит из идентификатора функции и списка аргументов в круглых скобках. Вот несколько вызовов функции sum:

int x = 5;

int y = 4;

int z;

 

sum(0,1); // 1

sum(x,2); // 7

sum(x,y); // 9

z = sum(x,y); // z = 9

 

Вызывающее окружение

То место, откуда вызывается функция, называется вызывающим окружением. Вызывающим окружением функции sum является функция main, а вызывающим окружением функции main является отладчик или операционная система.

Функция может обмениваться данными с вызывающим окружением благодаря списку аргументов и возвращаемому значению: вызывающее окружение передаёт данные в функцию с помощью аргументов, а функция передаёт данные в вызывающее окружение с помощью возвращаемого значения.

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

int simple (int a)

{

return 1;

}

 

int main ()

{

int b;

b = simple(0.5);

return 0;

}

В списке аргументов мы указали тип int, а в функцию передаётся вещественное значение 0.5. Так делать нельзя.

Рассмотрим более полезный пример: напишем функцию для передвижения персонажа:

int x; // глобальная переменная

 

int move_x (int dx)

{

x = x + dx;

return x;

}

 

int main ()

{

int ch;

char act;

 

while (1)

{

act = _getch();

ch = static_cast(act);

 

if (ch == 75) // была нажата стрелочка влево

move_x(-1);

else if (ch == 77) // была нажата стрелочка вправо

move_x(1);

} // конец while

return 0;

} // конец main

 

Обратите внимание, что для тела if и else if не стоит скобочек. Скобочки ветвлений можно опускать, если в теле ветвления всего один оператор.

Функция move_x двигает персонажа на одну единицу влево или вправо в зависимости от клавиши, которую нажал пользователь.

Создадим ещё одну функцию, а заодно уберём из main часть кода:

int x; // глобальная переменная

 

int move_x (int dx)

{

x = x + dx;

return x;

}

 

void move (int ch)

{

if (ch == 75) // была нажата стрелочка влево

move_x(-1);

else if (ch == 77) // была нажата стрелочка вправо

move_x(1);

}

 

int main ()

{

int ch;

char act;

 

while (1)

{

act = _getch();

ch = static_cast(act);

move(ch); // вызов функции move

} // конец while

return 0;

} // конец main

 

Обратите внимание, что в функции move на месте типа возвращаемого значения стоит void, кроме того, в теле move нет оператора return.

Объявления функций (прототипы)

В последнем примере, определение функции move_x должно располагаться выше определения move (а определения move_x и move должны располагаться до main), так как в функции move происходит вызов move_x.

Обычно определения всех пользовательских функций располагаются после определения main. При этом используются объявления функций (прототипы). Внесём изменения в предыдущую программу:

int x; // глобальная переменная

 

void move(int); // прототип (объявление) функции move

int move_x(int); // прототип функции move_x

 

int main ()

{

int ch;

char act;

while (1)

{

act = _getch();

ch = static_cast(act);

move(ch); // вызов move

}

return 0;

}

 

void move (int ch)

{

if (ch == 75) // была нажата стрелочка влево

move_x(-1);

else if (ch == 77) // была нажата стрелочка вправо

move_x(1);

}

 

int move_x (int dx)

{

x = x + dx;

return x;

}

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

int move_x(int dx);

int move_x(int);

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

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

Возврат void

На месте возвращаемого типа, в определении (и в объявлении) функции move стоит ключевое слово void (void - пусто, пустой). Это значит, что функция не возвращает никакого значения. Следовательно не требуется и оператор return, так как функции нечего вернуть в вызывающее окружение.

Указатели в Си.  Использование указателей при обработке одномерных и двумерных массивов.

Си тіліндегі көрсеткіштер. Бірөлшемді және екіөлшемді массивтерді өңдеу барысында көрсеткіштерді қолдану.

Указатели и массивы

Для работы с адресами памяти используются указатели.

int *a; // указатель на переменную целого типа
float *addr_f; // указатель на переменную вещественного типа

 

Размер памяти для переменной-указателя зависит от конфигурации машины. Конкретный адрес является указателем и получается с помощью операции &(адресации). Адресация не может применяться к переменным класса памяти register и к битовым полям структур. Разадресация * применяется для получения значения величины, указатель которой известен. Если значение указателя нулевое, то результат разадресации непредсказуем.

int *рa, x; int a[20]; double d;
рa= &a[5]; // это адрес 6-го элемента массива а
х = *рa; // x присваивается значение 6-го элемента массива а
if (x==*&x) cout<<"true\n"; d=*(double *)(&x);
// адрес х преобразуется к указателю на double и d=x.


       Указатель - это переменная, содержащая адрес другой переменной. Указатели очень широко используются в языке Cи. Это происходит отчасти потому, что иногда они дают единственную возможность выразить нужное действие, отчасти потому, что они обычно ведут к более компактным и эффективным программам, чем те, которые могут быть получены другими способами. Так как указатель содержит адрес объекта, это дает возможность "косвенного" доступа к этому объекту через указатель. Предположим, что X - переменная, например, типа int, а РX - указатель, созданный неким еще не указанным способом. Унарная операция & выдает адрес объекта, так что оператор РX = &X; присваивает адрес X переменной РX; говорят, что РX"указывает" на X. Операция & применима только к переменным и элементам массива, конструкции вида &(X-1) и &3 являются незаконными. Нельзя также получить адрес регистровой переменной.

Унарная операция * рассматривает свой операнд как адрес конечной цели и обращается по этому адресу, чтобы извлечь содержимое. Следовательно, если Y тоже имеет тип int, то Y = *РX; присваивает Y содержимое того, на что указывает РX. Последовательность РX = &X; Y = *РX; присваивает Y то же самое значение, что и оператор Y = X; Переменные, участвующие во всем этом, необходимо описать: int X, Y; int *РX; Описание указателя int *РX; должно рассматриваться как мнемоническое; оно говорит, что комбинация *РX имеет тип int. Это означает, что если РX появляется в контексте *РX, то это эквивалентно переменной тип int. Фактически синтаксис описания переменной имитирует синтаксис выражений, в которых эта переменная может появляться. Это замечание полезно во всех случаях, связанных со сложными описаниями. Например, double atof(), *DР; говорит, что atof() и *DР имеют в выражениях значения типа double.


       Указатели могут входить в выражения. Например, если РX указывает на целое X, то*РX может появляться в любом контексте, где может встретиться X. Оператор Y = *РX + 1; присваивает Y значение, на 1 большее значения X; printf("%d\n", *РX) печатает текущее значение X; D = sqrt((double) *РX) получает в D квадратный корень из X, причем до передачи функции sqrt значение X преобразуется к типу double. В выражениях вида Y = *РX + 1 унарные операции * и & связны со своим операндом более крепко, чем арифметические операции, так что такое выражение берет то значение, на которое указывает РX, прибавляет 1 и присваивает результат переменной Y.


       Ссылки на указатели могут появляться и в левой части присваивания. Если РXуказывает на X, то *РX = 0 полагает X равным нулю, *РX += 1 увеличивает его на единицу, как и выражение (*РX)++. Круглые скобки в последнем примере необходимы; если их опустить, то это выражение увеличит РX, а не ту переменную, на которую он указывает. Если РY - другой указатель на переменную типа int, то РY = РX копирует содержимое РX в РY, в результате чего РY указывает на то же, что и РX.

       Массив рассматривается как набор элементов одного типа. Чтобы объявить массив, необходимо в описании поcле имени массива в квадратных скобках указать его размерность.

int а[5]; // массив, состоящий из 5 целых переменных
char sym[20]; // массив из 20 символьных переменных
double c[10]; // массив из 10 вещественных величин.

       Индексы элементов изменяются от 0 до N-1, где N- размерность массива. Переменная типа массив является указателем на элементы массива.
Многомерный массив определяется путем задания нескольких константных выражений в квадратных скобках:

float d_l[3][5], c_dim[5][3][3];

       Элементы массива запоминаются в последовательных возрастающих адресах памяти. Хранятся элементы массива построчно. Для обращения к элементу массива вычисляется индексное выражение. Для a[i] индексное выражение равно *(а+ i), где а - указатель, например, имя массива; i - целая величина, преобразованная к адресному типу; * - операция разадресации. Для двумерного массива b[i][j] индексное выражение:*(b+i+j).

 

Рассмотрим пример ввода/вывода значений элементов массива с помощью функций scanf и рrintf:

#include <stdio.h> // подключается файл с прототипами функций scanf и рrintf
void main(void) { int a[3]; int i; float b[4]; double c[2];
for (i=0; i<3; i++) { scanf("%d ", &a[i]); рrintf("%d", a[i]); }
i=0; while (i < 4)
{scanf ("%f",b[i]); рrintf("%g",b[i]); i++;}
i=0; do
{ scanf("%lf ", &c[i]); рrintf("%g", c[i]); i++;}
while(i< 2); } }

Динамически выделять память под массивы и другие объекты можно с помощью функций calloc, malloc:

int *dim_i, n_dim_i;
n_dim_i =10;
dim_i =(int *)calloc(n_dim_i*sizeof(int));...

Тогда освобождать память необходимо функцией free:

free(dim_i);

При использовании функицй calloc, malloc, free в текст программы требуется включить файл описаний этих функций alloc.h:


#include <alloc.h>

В Си++ динамическое распределение памяти проводится оператором new, а освобождение - оператором delete. Выделенная по new область памяти занята до соответствующего delete или до конца программы.

int *i_рtr; i_рtr=new int; // резервируется память под величину int
d_рtr = new double(3.1415); // то же, что и *i_рtr=3.1415
c_рtr = new char[str_len]; // область памяти для str_len символов

Реальный размер выделяемой памяти кратен опеределенному числу байт. Поэтому невыгодно выделять память по new для небольших объектов. Если new не может выделить блок памяти, то она возвращает значение NULL.
Примеры освобождения памяти оператором delete:

delete i_рtr; delete d_рtr; delete [str_len] c_рtr;

Результат delete непредсказуемый, если переменная, записанная после него, не содержит адрес блока памяти или равна NULL.

Символьные строки и функции над строками. Функции операции над строками.

Символдық жолдар және жолдарға қолданылатын функциялар. Жолдарға қолданылатын опреациялардың функциялары.

Сөз тіркестерін өңдейтін басқа функциялар.

Сөз тіркестерін енгізу-шығару функциялары

 

Символдар тіркесін пернелерден енгізу үшін екі стандартты функция – scanf() немесе gets() қолданылады, ал олардың прототиптері stdio.h тақырыптық файлында болады.

 

Scanf () функциясы тіркестік айнымалылар мәнін %s форматымен енгізеді, бірақ ол тіркесті тек бірінші босорын таңбасына дейін ғана енгізе алады.  

 

Ал gets() функциясы арасында босорыны бар тіркестерді енгізеді, енгізу ENTER пернесімен аяқ-талады. Екі функция да тіркес соңына нөлдік байт қо-сып жазады. Оның үстіне тіркес – символдық жиым, ал жиым аты – оның компьютер жадындағы алғашқы адресіне сілтеме болғандықтан, тіркестік айнымалы атының алдына «&» символы жазылмайды.

 

Бір мысал келтірейік.

 

/*сөз тіркесін шығару*/

#include <conio.h>

#include <stdio.h>

Void mai n()

{

 char b[]=” Сезам, ашыл! ”;

 clrscr();

 printf("%s",b);

 getch();

 }

 

Мұндағы b жиымының ұзындығы 13 символ, яғни сөздер ұзындығынан 1-ге артық.

Сөз тіркестерін шығару функциялары:

Main()

{ char str1[]= “abc”;

char str 2 []= “def\nghi\n”;

char str 3 []= “jkl”;

puts(str1);

puts(str 2);

puts(str 3);

}

 

Нәтижесі:

abc

def

ghi

jkl

 

cputs(str) – экранға сөз тіркестерін шығарып, олардың түстерін textcolor() және textbackground() функциялары арқылы өзгертуге мүмкіндік береді, conio.h тақырып файлы бойынша жұмыс істейді.

Сөз тіркестерімен орындалатын басқа операциялар да стандартты функциялар арқылы атқарылады. Ол функциялар жұмыс істеуі үшін string.h тақырыптық файлы қажет.

Жалпы сөз тіркестерін қолдану үшін stdlib.h немесе string.h тақырыптық файлдары қолданылады.

Сөз тіркестерімен жұмыс істейтін басқа функциялар

1) strlen(str) функциясы str сөз тір-кесіндегі символдар санын (соңғы нөлді есепке алмайды), яғни жолдың ұзындығын анықтайды, оның типі int, тақырыптық файлы <string.h>

2) strcat(stroka1,stroka2) функциясы тір-кестерді біріктіру үшін қолданылады. Ол stroka1 және stroka2 тіркестерін бірік-тіріп, нәтижені stroka1 айнымалысына меншіктейді.

 

Мысал. Бірнеше сөз тіркестерінің ұзындығын анықтайтын программа құру керек.

// использование функции strlen(str)

#include <conio.h>

#include <stdio.h>

#include <string.h>

Main ()

{

static char t[]= “ Сведения о наших студентах. ”;

clrscr();

printf(“%d\n”,strlen(t));

printf(“%d\n”,strlen(“Сведения о наших студентах.”));

printf(“%d\n”,strlen(“КазНУ им.аль-Фараби”));

printf(“%d\n”,strlen(“”));

getch();

}

 

Мұның нәтижесі:

27

27

19

0

Келесі мысал:

//strcat(str1, str2) ф-циясын пайдалану

#include <conio.h>

#include <stdio.h>

#include <string.h>

Main ()

{

char str1[50]=“ Изучаем язык Си, ";

char str2[]=“ скоро сдадим экзамен.";

clrscr();

printf("%s\n",strcat(str1,str2));

puts(str1); // экранға шығару

puts(strcat(“ Если будем учиться хорошо, ",str2));

getch();

}

 

Мұның нәтижесі:

Main ()

{

printf("%d\n",strcmp("Привет","Привет"));

printf("%d\n",strcmp("Jello","Hello"));

printf ("% d \ n ", strcmp (" Приветствие ", " Приветствую "));

getch();

}

Мұның нәтижесі:

0 2 -59

Алғашқы екі сөз бірдей (0), келесі екі сөздің 1-әрпі әр түрлі, олардың ASCII-кодтарының айырмасы – 2 (J - 74, H - 72), ал 3-жолы - 59 (и – 168, у – 227, олардың кодтарының айырмасы 168-227=-59)

 

//strcmp(str1, str2) функциясын пайдалану

 

#include <conio.h>

#include <stdio.h>

#include <string.h>

#define NAME " Ритчи "

Main ()

{ char f[20];

 puts("Си тілінің авторы кім?");

gets(f);

while(strcmp(f,NAME)!=0)

 {puts("Тағы кім болуы мүмкін?");

gets(f);

}

puts(" Дұрыс!");

getch();

}

 

Нәтижесі:

 

Си тілінің авторы кім?

Керниган

Тағы кім болуы мүмкін?

Ритчи

Дұрыс!

 

4) strcpy(str1, str2) функциясы сөздердің көшірмесін алу үшін қажет, мұндағы str2 айнымалысындағы сөз тіркесі str1 айнымалысына көшіріледі.

 

Мысалы:

 

// strcpy(str1, str2) функциясын қолдану

#include <conio.h>

#include <stdio.h>

#include <string.h>

Main ()

{char str1[21];

strcpy (str 1, " Как дела, друг?");

puts(str1);

 strcpy(str1, " Ура!");

 puts (str 1);

getch ();

}

 

Нәтижесі:

Как дела, друг?

Ура!

 

2-мысал:

//strcpy(str1, str2) функциясын пайдалану

#include <conio.h>

#include <stdio.h>

#include <string.h>

#define stroka " функция копирования "

Main ()

{

 char *ptr=stroka;

 char res[25];

 clrscr();

 puts(ptr);

 puts(res);

 strcpy(res,ptr);

 puts(ptr);

 puts(res);

getch();



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 33; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.224.32.86 (0.432 с.)