Блоки и составные операторы
Любая последовательность операторов, заключенная в фигурные скобки, является составным оператором (блоком). Составной оператор может использоваться везде, где синтаксис языка допускает обычный оператор. Идентификатор, объявленный в блоке, имеет область действия от точки объявления до конца блока.
6.2.10.2. Оператор возврата из функции ‑ return
return [<выражение>];
Оператор предназначен для выход из функции со значением указанного выражения. Если выражение отсутствует, то в объявлении функции это указывается параметром void перед именем функции.
6.2.10.3. Условный оператор ‑ if
if (<условие>) <оператор-1 >[else <оператор-2>]
Если условие истинно, то выполняется <оператор-1>, в противном случае - <оператор-2>. Синтаксис предписывает, что else всегда относится к ближайшему оператору if.
Примервложенногооператораif:
int main(int argc, char **argv) { int i = 4, j = 6, k = 8; if (i < k) if (i > j)
printf ( «оператор 1\n» ); else printf ( «оператор 2\n»);getch(); return 0; }
6.2.10.4. Условная операция ‑ ?
<результат>= (<условие>) ?< выражение-1>:< выражение-2 >
Если условие истинно, то результату присваивается значение <выражение-1>, иначе ‑ < выражение-1>.
Пример: main ( ) {int i = 6, j= 4; int result = ( i < j ) ? i : j; }
6.2.10.5. Оператор выбора варианта ‑ switch
switch (< выражение >)
{case <константное выражение_1> : <операторы> [<break;>]
...
case <константное выражение_n > : <операторы> [<break;>]
[default: <операторы>]
}
После вычисления выражения в заголовке оператора его результат последовательно сравнивается с константными выражениями, начиная с самого верхнего, пока не будет установлено их соответствие. Тогда выполняются операторы внутри соответствующего case, управление переходит на следующее константное выражение, и проверки продолжаются. Именно поэтому в конце каждой последовательности операторов должен присутствовать оператор break. После выполнения последовательности операторов внутри одной ветки case, завершающейся оператором break, происходит выход из оператора switch. Обычно оператор switch используется тогда, когда программист хочет, чтобы была выполнена только одна последовательность операторов из нескольких возможных. Каждая последовательность операторов может содержать нуль или более отдельных операторов. Фигурные скобки в этом случае не требуются.
Если ветка, называемая default (умолчание) есть, то последовательность операторов, стоящая непосредственно за словом default и двоеточием, выполняется только тогда, когда сравнение ни с одним из стоящих выше константных выражений не истинно.
6.2.10.6. Оператор безусловного перехода ‑ goto
Оператор goto используется для передачи управления внутри функции от одного оператора к другому. Синтаксис оператора такой:
goto <идентификатор>.Управление передается безусловно на оператор, помеченный указанным идентификатором.
Пример: goto backend; ... backend: x+= 3; ...
Рекомендуется минимизировать число операторов goto и не входить извне внутрь блока операторов if, else, switch или операторов цикла.
6.2.10.7. Цикл с предусловием ‑ while
while (<условие>) <оператор>.
Проверка условия производится перед выполнением тела цикла. Если результат вычисления условного выражения ‑ истина, то выполняется оператор (или группа операторов). Перед входом в цикл while в первый раз обычно инициализируют одну или несколько переменных для того, чтобы условное выражение имело какое-либо значение. Оператор или группа операторов, составляющих тело цикла, должны, как правило, изменять значения одной или нескольких переменных, входящих в условное выражение, с тем, чтобы в конце концов выражение обратилось в нуль, и цикл завершился. Оператор continueпередает управления на начало следующего повторения цикла. Цикл while завершается, если условие стало ложным или в теле цикла встретился оператор breakили return.
Примерпрограммы поиска элемента в массиве:
int main(int argc, char **argv) // основная функция
{ int scores[100];extern int search(int data[ ],int size,int key);// объявл.функции
int i; for (i = 0; i < 100; i++) scores [ i ] = i; // заполнение массива
printf( «\nИндекс числа 107 в массиве = %d\n»,search (scores, 100, 107 ) );
getch(); return 0;
} // конец основной функции
int search (int data [],int size,int key) // функция поиска элемента массива
{ int index = 0; while ( index < size && data [ index ] != key ) index++;
return ( data [index]==key )?index : -1;}
6.2.10.8. Цикл с постусловием ‑ do while
В цикле do while проверка условия осуществляется после выполнения тела цикла. Синтаксис цикла: do <оператор>while (<условие>);
Оператор continue передает управление на начало следующего повторения цикла. Цикл прекращает выполняться, когда условие становится ложным или внутри цикла встретился оператор break или return.
Пример функции сравнения двух строк (str1, str2):
int main(int argc, char **argv) // основная функция
{extern int compare ( char str1 [ ], char str2 [ ] ); char str1 [ 80 ], str2 [ 80 ];
printf («\nВведите первую строку: «); scanf( «%s», str1); // ввод строки 1
printf («\nВведите вторую строку: « ); scanf ( «%s», str2); // ввод строки 2
if ( compare (str1,str2 )< 0) printf ( «\nПервая строка меньше второй «);
else if (compare (str1,str2 )==0) printf ( «\n\nПервая строка равна второй»);
else printf («\n\nПервая строка больше второй»); getch();
} // конец основной функции
int length (char str [ ]) // функция вычисления длины строки
{int index=0; while (str [index++]!= 0 ); return -index;}
int compare (char str1 [ ], char str2 [ ] ) // функция сравнения строк
{extern int length(char str[ ]); int len1 = length(str1); int len2=length( str2 );
int index=-1; int minlength=(len1<len2)?len1:len2; // длина короткой строки
do index++; while (index < minlength && str1[index] ==str2[index]);
if (len1== len2 && str1[index] == str2[index]) return 0; // строки равны
if ( str1[index]==str2[index] &&len1 < len2)return -1; // строка 1 < строки 2
if (str1[index]==str2[index] &&len2 > len1) return 1; // строка 1 > строки 2
if (str1[index ]<str2[index]) return -1; else return 1; // строка 1 > строки 2
}
6.2.10.9. Итерационный цикл ‑ For
for ([<выражение-1>];[<выражение-2>];[< выражение-3>]) <оператор>
Формально правила выполнения этого оператора можно описать так:
1. Если первое выражение присутствует, то оно вычисляется.
2. Вычисляется второе выражение (если оно присутствует). Если вырабатывается значение 0 (false), то цикл прекращается, в противном случае цикл будет продолжен.
3. Исполняется тело цикла (<оператор>).
4. Вычисляется третье выражение (если оно присутствует).
5. Переход к пункту 2.
Появление в любом месте тела цикла оператора continue или break приводит к переходу к шагу 4 или к выходу из цикла соответственно.
Пример программы подсчета суммы ряда 1+1/2+1/3+1/4+...1/1000:
int main(int argc, char **argv) {
float s, i; for (s=0,i=1;i<=1000; s+=1/i++); printf ( «\n%20.8f», s); getch(); }
Пример программы подсчета среднего числа массива чисел 1,2,..,100:
# define size 100 // макроподстановка размерности массива - 100
int main(int argc, char **argv) { // основная функция
int data [size]; extern float average (int a[ ], int s ); int i;
for (i=0; i<size; i++) data [i]= i; // заполнение массива числами от 0 до 99
printf( «\nСреднее значение массива data=%f\n»,average(data,size));getch(); }
float average( int a [ ], int s ) // функция подсчета среднего числа массива
{ float sum = 0.0; int i; for (i = 0; i < s; i++) sum += a [ i ]; return sum / s; }
Пример программы вычисление максимальных и минимальных значений элементов массива случайных чисел:
# define size 100 // макроподстановка size=100 ‑ размерность массива
int main(int argc, char **argv) { // основная функция
float scores [size]; // объявление массива из ста вещественных чисел
float max(float data[ ],int s), min(float data[ ],int s); // объявление функций
int i; randomize(); // включение счетчика случайных чисел
for (i =0; i < size; i++ ) scores[ i ]= rand(); // заполнение массива случ.чисел
printf (« \nМаксимальное значение = %f», max( scores, size ));
printf («\nМинимальное значение = %f\n», min( scores, size )); getch(); } float max(float data [ ], int s ) { // функция поиска максимального числа
float maximum = data [ 0 ]; int i; for(i=1;i <s; i++)
if (data[i]>maximum ) maximum=data[i]; return maximum; }
float min( float data [ ], int s ) { // функция поиска минимального числа
float minimum = data [0]; int i; for (i = 1; i < s; i++)
if ( data [1] < minimum ) minimum = data [i]; return minimum; }
Пример программы сортировки «методом пузырька» массива из десяти случайных чисел. В основной функции в массив data заносится size (десять) вещественных чисел, затем вызывается функция сортировки bubble_sort, после чего отсортированный массив распечатывается.
На первом проходе алгоритма сортировки все элементы массива, начиная с последнего, сравниваются попарно, и если элемент а[j] оказывается меньше, чем элемент а[j-l], то элементы меняются местами. После завершения первого прохода наименьший элемент массива будет помещен в a[0]. На втором проходе выполняются те же действия, однако проход заканчивается на элементе a[1]. После второго прохода второй по значению элемент будет в a[1] и т.д. Название «метод пузырька» дано алгоритму потому, что при каждом просмотре наименьшие элементы как бы медленно всплывают «наверх», подобно пузырьку воздуха в воде.
# define size 10 // макроподстановка size=10 ‑ размерность массива
int main(int argc, char **argv) { // основная функция
float data [size]; // объявление массива
extern void bubble_sort(float a[ ], int s); // объявление функции сортировки
int index; randomize(); // включение счетчика случайных чисел
for (index=0;index<size;index++) data[index]=rand(); // заполнение массива
bubble_sort ( data, size ); // обращение к функции сортировки массива
for (index=0;index<size; index++)// цикл вывода отсортированного массива
printf( «\ndata [ %d ] = %f», index, data [ index ]); getch(); }
void bubble_sort( float a [ ], int s ) { // функция сортировки массива
int i, j; float temp; // объявление переменных
for ( i=0;i<s-1;i++) // внешний цикл
for(j=s-1;j>1;j--) // внутренний цикл
if (a[j]<a[j-1]) {temp=a[j]; a[j]=a[j-1];a[j-1]=temp;} }
Пустой оператор
Пустой оператор представляется символом «;», перед которым нет выражения. Пустой оператор используют там, где синтаксис языка требует присутствия в данном месте программы оператора, однако по логике программы оператор должен отсутствовать.
Необходимость в использовании пустого оператора часто возникает при программировании циклов, когда действия, которые могут быть выполнены в теле цикла, целиком помещаются в заголовок цикла.
Указатели
Указатель- это адрес памяти. Значение указателя сообщает, где размещен объект, но не говорит о самом объекте. Переменная типа указатель описывается так: <тип> *<переменная-указатель>. Данная запись означает, что переменная-указатель является указателем на любую переменную указанного типа.
Символ операции «*»(звездочка) используется для задания указателя на объект.
Пример: int *х; // указатель на любую переменную типа int. Указатель на тип void совместим с любым указателем.
Пример: void *х; int *y; // допустимо присваивание: y = x.
Двумя наиболее важными операциями, связанными с указателями, являются операция обращения по адресу (разадресации) и операция определения адреса. Операция обращения по адресу (*) служит для присваивания или считывания значения переменной, размещенной по адресу «переменная‑ указатель» (*ptr_var = value).
Пример. Предложение *х=16 означает, что по адресу, задаваемому в х, помещается значение 16.
Операция определения адреса возвращает адрес памяти своего операнда. Операндом должна быть переменная. Операция определения адреса выполняется следующим образом:
<указатель-переменная>=&<переменная>;
Пример. Запись a=*&b равносильна записи a=b.
Для определения адреса массива операцию & можно не указывать перед его именем.
Если переменная, например, ptr определена как указатель на структуру, то для доступа к полю структуры (field); можно использовать операцию -> в виде: ptr->field, которая эквивалентна выражению (*ptr).field.
Существует четыре способа задать переменной-указателю начальное значение:
• описать указатель вне любой функции или снабдить его предписанием static. Начальным значением является нулевой адрес памяти ‑ 0;
• присвоить указателю адрес переменной;
• присвоить указателю значение другого указателя;
• использовать операторы распределения памяти newи delete.
Операция динамического выделения памяти имеет вид:
<указатель-переменная>=new[<имя переменной>] [<тип переменной>];
Операция возвращает нулевое значение, если не может выделить память.
Операция освобождения выделенной памяти имеет вид:
delete <указатель-переменная>.
Примеры:
ptr=new int [3];// выделение памяти для массива из трех элементов типа int
ptrf=new float[3][5];// выделение памяти для массива 3 на 5 чисел типа float
ptrstack=new stack; //выделение памяти для структуры (записи) stack
delete ptrstack; // освобождается память выделенная ранее по адресу ptrstack
Пример динамического формирования и вывода стека (п. 1.9.3):
int main(int argc, char **argv) { // создание и вывод стека из чисел 1,2,3,4,5
struct stack { int inf; stack* next;}; // объявление структуры (записи) stack
stack *top=0,*kon,*del;//объявление переменных-указателей на запись stack
for (int i=1;i<=5;i++) // цикл формирования стека из пяти записей
{ kon=new stack; // выделение памяти для новой записи
kon->next=top; kon->inf=i; //запоминание адреса предыдущей записи
top=kon; // запоминание адреса последней записи (вершины стека)
} // конец цикла формирования стека
kon=top; // установка адреса вершины стека (последней записи стека)
while (kon!=0) // цикл вывода записей стека на экран (cout << ) (п. 6.5.2)
{cout<<kon->inf<<endl;del=kon;kon=kon->next;delete del;}//вывод 5,4,3,2,1
getch(); return 0; } // задержка и завершение работы функции
Дата добавления: 2016-03-22; просмотров: 960;