Часто main() - единственная функция в программе.
---------------------------------------------------------------------------
Структура программы такова:
#include /* магическая строка */
/* ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ (о них позже) */ int a = 7; int b; /* по умолчанию 0 */
/* ФУНКЦИИ */ f1(){....} f2(){....}
/* НАЧАЛЬНАЯ (ГЛАВНАЯ) ФУНКЦИЯ */ void main(){ ... } ---------------------------------------------------------------------------
Пример программы:
#include
int f1(int x, int y){ return (x + y*2); }
int f2(int x){ int z;
z = x+7; return 2*z; }
void main(){ /* Объявления переменных */ int a, b, c;
/* Операторы */ a = 5; b = 6;
c = f1(a, b+3); b = f1(1, 2); a = f2(c);
printf("A есть %d B есть %d C есть %d\n", a, b, c); }
Она печатает:
A есть 60 B есть 5 C есть 23
КАК НЕ НАДО ПРОГРАММИРОВАТЬ ЦИКЛЫ
int i;
for(i=0; i < 4; i++){ if(i == 0) func0(); else if(i == 1) func1(); else if(i == 2) func2(); else if(i == 3) func3(); }
В данном примере цикл АБСОЛЮТНО НЕ НУЖЕН. То, что тут делается, есть просто ПОСЛЕДОВАТЕЛЬНОСТЬ операторов:
func0(); func1(); func2(); func3();
Цикл имеет смысл лишь тогда, когда много раз вызывается ОДНО И ТО ЖЕ действие, но может быть зависящее от параметра, вроде func(i). Но не разные функции для разных i.
Аналогично, рассмотрим такой пример:
int i;
for(i=0; i < 10; i++){ if(i==0) func0(); else if(i == 1) func1(); else if(i == 2) func2(); else funcN(i); }
Тут funcN(i) берет на себя роль "а в остальных случаях". Однако, этот пример более естественно может быть записан так:
int i;
func0(); func1(); func2(); for(i = 3; i < 10; i++) funcN(i);
Заметьте, что цикл теперь начинается с индекса 3.
А теперь - случай, где смесь цикла и условного оператора оправдана:
int i;
for(i=0; i < 100; i++){ if((i % 2) == 0) even(); /* четный */ else odd(); /* нечетный */ }
Тут в цикле проверяется четность индекса i. 03.c
/* Треугольник из звездочек */
#include
/* putchar('c') - печатает одинокий символ c */ /* символ \n - переводит строку */ /* nstars - сколько звездочек напечатать */
/* Функция рисования одной строки треугольника */ void drawOneLine(int nstars){ int i; /* номер печатаемой звездочки, счетчик */
for(i=0; i < nstars; i++) /* Рисуем nstars звездочек подряд */ putchar('*'); putchar('\n'); /* И переходим на следующую строку */ }
void main(){ /* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */ int nline; /* номер строки */
/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */ for(nline=1; nline <= 25; nline++) drawOneLine(nline); /* сколько звездочек? столько же, каков номер строки */ } 04.c
/* Треугольник из звездочек */ /* Тот же пример со вложенным циклом, а не с функцией */
#include
void main(){ /* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */ int nline; /* номер строки */ int i; /* номер печатаемой звездочки, счетчик */
/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */ for(nline=1; nline <= 25; nline++){ /* сколько звездочек? столько же, каков номер строки */ for(i=0; i < nline; i++) putchar('*'); putchar('\n'); } } 05.c
/* Треугольник из звездочек */ /* Теперь треугольник должен быть равнобедренным */
#include
/* nstars - сколько звездочек напечатать */ /* nspaces - сколько пробелов напечатать перед звездочками */
void drawOneLine(int nspaces, int nstars){ int i; /* номер печатаемой звездочки, счетчик */ /* он же - номер печатаемого пробела */
for(i=0; i < nspaces; i++) putchar(' '); for(i=0; i < nstars; i++) putchar('*'); putchar('\n'); }
/* n (номер строки) ...* 1 ..*** 2 .***** 3 ******* 4
Всего строк: LINES Число звездочек в n-ой строке: n*2 - 1 Число пробелов спереди (обозначены точкой): LINES - n
Все эти числа подсчитываются с картинки...
Их мы будем передавать в функцию drawOneLine в точке _вызова_, а не вычислять в самой функции. Функция для того и заведена, чтобы не вычислять ничего КОНКРЕТНОГО - все параметры ее переменные, и должны ПЕРЕДАВАТЬСЯ в нее из точки вызова.
В качестве параметра в точке вызова можно передавать не только значение переменной, но и значение выражения, то есть формулы.
*/ void main(){ /* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */ int LINES = 25; /* всего строк. Это описание переменной сразу с ее инициализацией */ int nline; /* номер строки */
/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */ for(nline=1; nline <= LINES; nline++) drawOneLine(LINES - nline, /* число пробелов --> nspaces */ nline*2 - 1 /* число звездочек --> nstars */ ); } 06.c
/* Треугольник из звездочек */ /* Теперь треугольник должен быть равнобедренным */
#include
void drawOneLine(int nspaces, int nstars){ int i; /* номер печатаемой звездочки, счетчик */ /* он же - номер печатаемого пробела */
for(i=0; i < nspaces; i++) putchar(' '); for(i=0; i < nstars; i++) putchar('*'); putchar('\n'); }
void main(){ /* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */ int LINES = 25; /* всего строк. */ int nline; /* номер строки */
/* Для человека естественно считать с 1. Для машины же первое число - это НУЛЬ. Поэтому цикл for(nline=1; nline <= LINES; nline++) Следует записать в виде for(nline=0; nline < LINES; nline++)
Он тоже выполнится 25 раз, но значение переменной-счетчика nline будет на каждой итерации на 1 меньше. Поэтому надо поменять расчет параметров для функции рисования.
n (номер строки) ...* 0 ..*** 1 .***** 2 ******* 3
Всего строк: LINES Число звездочек в n-ой строке: n*2 + 1 Число пробелов спереди (обозначены точкой): LINES - n - 1
*/
/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */ for(nline=0; nline < LINES; nline++) drawOneLine(LINES - nline - 1, nline*2 + 1); } 07.c
/*
|