русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Занятие №20. Некоторые особенности цикла for. Оператор последовательного вычисления.


Дата добавления: 2015-06-12; просмотров: 651; Нарушение авторских прав


Выдалась свободная минутка, решил написать небольшой пост, по мотивам уже заданных мне ранее вопросов. Быть может кому-то эти советы, тоже будут полезны. Итак, сегодня займемся циклами.

Рассмотрим цикл for().

Как вы уже знаете, синтаксис этой конструкции имеет следующий вид:

for(инициализация счетчика; условие; изменение счетчика)

оператор

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

Если вы еще не забыли, а это не мудрено с моей-то частотой выпуска занятий, то последнем уроке мы изучали двойные массивы. Одной из типичных задач является вывод массива размерности [N][M] на экран в виде таблицы (или матрицы) в N-строк и M столбцов. Для этой задачи очень крайне удобно использовать два вложенных цикла for. Например:

Листинг 1.

#include <stdio.h>

#include <stdlib.h>

#define N 10

#define M 8

int main(void){

int arr[N][M];

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

for (int j=0; j<M; j++)



arr[i][j]=rand();

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

for (int j=0; j<M; j++)



printf("%d\t",arr[i][j]);

return (0);

}

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

Листинг 2.

#include <stdio.h>

#include <stdlib.h>

#define N 10

#define M 8

int main(void){

int arr[N][M];

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

for (int j=0; j<M; j++)



arr[i][j]=rand();

for (int i=0;i<N;i++){

for (int j=0; j<M; j++)



printf("%d\t",arr[i][j]);

printf("\n");

}

return (0);

}

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

Рис.1. Результат работы программы.

А теперь поговорим о красоте. Этот вот дополнительный перенос строки , он как шило в заднице. Из-за него одного пришлось добавить составной оператор. Некрасиво получилось. Есть ли способ этого избежать. Да, есть!

Я вам раньше не говорил, а теперь скажу. В заголовке цикла for на месте инициализации счетчика и на месте изменения счетчика, могут стоять не одна, а сразу несколько инструкций. Чтобы их туда записать нужно использовать еще один оператор, оператор последовательного выполнения – ,. Да-да, просто запятая.

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

Листинг 3.

#include <stdio.h>

#include <stdlib.h>

#define N 10

#define M 8

int main(void){

int arr[N][M];

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

for (int j=0; j<M; j++)



arr[i][j]=rand();

for (int i=0;i<N;i++,printf("\n"))

for (int j=0; j<M; j++)



printf("%d\t",arr[i][j]);

return (0);

}

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

Рассмотрим один показательный пример. Используем для вывода двойного массива на экран один цикл for. Это будет выглядеть например так:

Листинг 4:

#include <stdio.h>

#include <stdlib.h>

#define N 10

#define M 8

int main(void){

int arr[N][M];

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

for (int j=0; j<M; j++)



arr[i][j]=rand();

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

printf("%d\t",arr[i][j]);

if (M-j==1){

printf("\n");

i++;

j=-1;

}

}

return (0);

}

А на мониторе снова никаких изменений. ))

Рис.2. Результат работы программы.

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

UPD(от 2.02.14):Я говорил же вам, что этот код может запутать любого. Я и сам попался в эту ловушку. Записанный ранее код, был ошибочен. Стараниями внимательного читателя он исправлен, и теперь работает так, как ему и подобает. =))

Я не помню, рассказывал я о именованных константах, которые использую в своих примерах в этом уроке. На всякий случай расскажу еще раз.

Для объявления именованных констант служит директива #define. Её синтаксис таков

#define имя значение

Важно! Не нужно ставить в конце точку с запятой. А так же между именем и значением знак присвоения =.

Как работает эта инструкция, рассмотрим на нашем примере. Перед тем как компилятор начнет обрабатывать программу, он пройдется по всему коду и заменит все места, где встречается N или M и вместо них подставит в код их значения: 10 и 8 соответственно. Причем компилятору вообще по барабану, что на что мы заменяем. С учетом этой особенности, некоторые используют при написании код «Боярский язык». Ну т.е. пишут код на обычном русском языке. Например вот так.

Листинг 5.

#include <stdio.h>

#include <stdlib.h>

#define N 10

#define M 8

#define целое int

#define присвоить =

целое main(void){

целое arr[N][M];

for (целое i присвоить 0;i<N;i++)

for (целое j присвоить 0; j<M; j++)

arr[i][j] присвоить rand();

for (целое i присвоить 0, j присвоить 0 ;i<M,j<N;i++){

printf("%d\t",arr[i][j]);

if (M-i==1){

printf("\n");

j++;

i присвоить 0;

}

}

return (0);

}

И если вы думаете, что такой код не будет работать, то вы ошибаетесь. Хотя, конечно это все для забавы, и писать что-то серьезное так не следует. Но кому стало интересно - погуглите и найдете что-нибудь интересное для себя.



<== предыдущая лекция | следующая лекция ==>
Зачем нужны двумерные массивы? | Занятие 21. Заголовочные файлы.


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 2.389 сек.