Студопедия — ПРОГРАММА В ЦЕЛОМ
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

ПРОГРАММА В ЦЕЛОМ






 

 

Программа в целом состоит из функций.

Одна из функций должна иметь имя main(),

 

С ФУНКЦИИ main НАЧИНАЕТСЯ ВЫПОЛНЕНИЕ ПРОГРАММЫ.

 

(на самом деле этому предшествует отведение и инициализация

глобальных переменных; смотри последующие лекции).

 

Часто 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.

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);

/* сколько звездочек? столько же, каков номер строки */

}

C

 

/* Треугольник из звездочек */

/* Тот же пример со вложенным циклом, а не с функцией */

 

#include

 

void main(){

/* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */

int nline; /* номер строки */

int i; /* номер печатаемой звездочки, счетчик */

 

/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */

for(nline=1; nline <= 25; nline++){

/* сколько звездочек? столько же, каков номер строки */

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

putchar('*');

putchar('\n');

}

}

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 */

);

}

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);

}

C

 

/*

Тип переменных для хранения БУКВ называется

 

char

 

(от слова character).

 

Буквы изображаются в одиночных кавычках 'a' 'b' '+'.

 

Пример:

char letter;

 

letter = 'a';

putchar(letter);

letter = 'b';

putchar(letter);

letter = '\n';

putchar(letter);

 

Символ '\n' обозначает "невидимую букву" -

переход на новую строку, new line.

Есть несколько таких специальных букв, о них - позже.

 

Зато сразу сделаем оговорку.

Чтобы изобразить саму букву \

следует использовать '\\'

 

putchar('\'); или

printf ("\"); ошибочны.

 

Надо: putchar('\\'); printf("\\");

 

Дело в том, что символ \ начинает последовательность из ДВУХ букв,

изображающих ОДНУ букву, иногда вызывающую специальные

действия на экране или на принтере.

*/

 

/*

Число делится на n, если ОСТАТОК от деления его на n равен 0,

то есть если

 

(x % n) == 0

 

В частности, так можно проверять числа на четность/нечетность,

беря x%2.

 

Остатки от деления числа x на n

это 0 1 2... n-1.

В случае деления на 2 остаток

0 соответствует четному x

1 соответствует нечетному x

 

*/

 

/* Задача:

Нарисовать треугольник

из звездочек в нечетных строках

из плюсиков в четных строках

*--------------------------------------------------------*

 

Решение: используем прежнюю программу,

добавив в функцию drawOneLine еще один аргумент - symbol -

каким символом рисовать строку.

 

Далее в основном цикле используем условный оператор и

проверку номера строки на четность.

 

*/

 

#include

 

void drawOneLine(int nspaces, int nsymbols, char symbol){

int i; /* счетчик */

 

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

putchar(' ');

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

putchar(symbol);

putchar('\n');

}

 

/* Мы вынесем объявление этой переменной из функции,

сделав ее "глобальной", то есть видимой во ВСЕХ функциях.

*/

int LINES = 25; /* всего строк. */

 

void main(){

/* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */

int nline; /* номер строки */

 

/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */

for(nline=0; nline < LINES; nline++){

 

if((nline % 2) == 0) /* четное? */

drawOneLine(LINES - nline - 1, nline*2 + 1, '+');

else drawOneLine(LINES - nline - 1, nline*2 + 1, '*');

}

}

C

 

/* То же самое, но теперь нужно еще и печатать номер строки.

*/

 

#include

 

/* Вообще-то глобальные переменные

принято объявлять в самом начале файла с программой.

*/

 

int LINES = 25; /* всего строк. */

 

/* Добавим к функции еще один аргумент, указатель - печатать ли

номер строки. Назовем его drawLineNumber.

Не впадите в заблуждение по аналогии с именем ФУНКЦИИ drawOneLine()!

В данном случае - это имя ПЕРЕМЕННОЙ - АРГУМЕНТА ФУНКЦИИ.

 

Оператор if(x).....;

РАБОТАЕТ ТАКИМ ОБРАЗОМ (так он устроен):

в качестве условия он принимает целое число (типа int).

Условие истинно, если x!= 0,

и ложно, если x == 0.

 

Второй добавленный аргумент - собственно номер строки.

*/

void drawOneLine(int nspaces,

int nsymbols,

char symbol,

/* а это мы добавили */

int drawLineNumber,

int linenum

){

int i; /* счетчик */

 

if(drawLineNumber)

printf("%d\t", linenum); /* без перевода строки */

 

/* На самом деле это условие более полно надо записывать как

 

if(drawLineNumber!= 0)

 

но в языке Си это то же самое.

*/

 

/* Тут мы снова видим новый специальный символ \t - ТАБУЛЯЦИЯ.

Весь экран (или лист бумаги) условно поделен

на колонки шириной по 8 позиций.

Примерно так:

| | | | | | | | |...

Символ табуляции вызывает переход из текущей позиции в начало следующей

колонки. Например

| | | | | | | | |...

^ отсюда

 

| | | | | | | | |...

^ в это место

 

*/

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

putchar(' ');

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

putchar(symbol);

putchar('\n');

}

 

void main(){

/* ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ */

int nline; /* номер строки */

 

/* ВЫПОЛНЯЕМЫЕ ОПЕРАТОРЫ (ДЕЙСТВИЯ) */

for(nline=0; nline < LINES; nline++){

 

if((nline % 2) == 0) /* четное? */

drawOneLine(LINES - nline - 1, nline*2 + 1, '+', 1, nline);

else drawOneLine(LINES - nline - 1, nline*2 + 1, '*', 9, nline);

}

 

/* А почему именно 1 или именно 9?

* А все что попало, лишь бы не 0.

* Можно 3, 333, 666, -13445, итп

*

* Вопрос: что будет, если тут написать 0?

*/

}

C

 

/* Следующая задача будет касаться того,

чтобы каждая строка треугольника печаталась

в виде:

*+*+*+*.....*+*

 

Тут нам уже придется модифицировать функцию рисования строки.

*/

 

#include

 

int LINES = 25; /* всего строк. */

 

void drawOneLine(int nspaces, int nsymbols){

int i;

 

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

putchar(' ');

 

/* в цикле мы будем проверять на четность НОМЕР

печатаемого символа.

*/

for(i=0; i < nsymbols; i++){

if((i % 2) == 0)

putchar('*');

else putchar('+');

}

putchar('\n');

}

 

void main(){

int nline; /* номер строки */

 

for(nline=0; nline < LINES; nline++) {

drawOneLine(LINES - nline - 1, nline*2 + 1);

}

}

C

 

/* Задача нарисовать РОМБ:

*

***

*****

***

*

*/

 

#include

 

int LINES = 10; /* всего строк в половине ромба. */

 

void drawOneLine(int nspaces, int nsymbols){

int i;

 

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

putchar(' ');

 

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

putchar('+');

putchar('\n');

}

 

void main(){

int nline; /* номер строки */

 

for(nline=0; nline < LINES; nline++)

drawOneLine(LINES - nline - 1, nline*2 + 1);

 

/* Мы нарисовали треугольник.

Теперь нам нужен перевернутый треугольник.

Пишем цикл по убыванию индекса.

С данного места номера строк отсчитываются в обратном порядке:

от LINES-2 до 0

*/

 

for(nline=LINES-2; nline >= 0; nline--)

drawOneLine(LINES - nline - 1, nline*2 + 1);

}

C

 

/* А теперь рисуем ромб, используя математические формулы. */

 

#include

 

void draw(int nspaces, int nstars, char symbol){

int i;

 

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

putchar(' ');

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

putchar(symbol);

putchar('\n');

}

 

void main(){

int LINES = 21;

int MIDDLELINE = LINES/2 + 1; /* середина ромба */

int nline;

 

for(nline=0; nline < MIDDLELINE; nline++)

draw(MIDDLELINE - nline -1, nline*2+1, 'A');

 

/* У следующего цикла for() нет инициализации

начального значения индекса.

Начальное nline наследуется из предыдущего цикла,

таким, каким оно осталось после его окончания, то есть

равным MIDDLELINE.

*/

 

for(; nline < LINES; nline++)

draw(nline - MIDDLELINE + 1, (LINES - 1 - nline) * 2 + 1, 'V');

}

* 12_ARRAYS.txt *

 

 







Дата добавления: 2015-03-11; просмотров: 485. Нарушение авторских прав; Мы поможем в написании вашей работы!



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

Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

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

Гносеологический оптимизм, скептицизм, агностицизм.разновидности агностицизма Позицию Агностицизм защищает и критический реализм. Один из главных представителей этого направления...

Функциональные обязанности медсестры отделения реанимации · Медсестра отделения реанимации обязана осуществлять лечебно-профилактический и гигиенический уход за пациентами...

Определение трудоемкости работ и затрат машинного времени На основании ведомости объемов работ по объекту и норм времени ГЭСН составляется ведомость подсчёта трудоёмкости, затрат машинного времени, потребности в конструкциях, изделиях и материалах (табл...

Типовые ситуационные задачи. Задача 1.У больного А., 20 лет, с детства отмечается повышенное АД, уровень которого в настоящее время составляет 180-200/110-120 мм рт Задача 1.У больного А., 20 лет, с детства отмечается повышенное АД, уровень которого в настоящее время составляет 180-200/110-120 мм рт. ст. Влияние психоэмоциональных факторов отсутствует. Колебаний АД практически нет. Головной боли нет. Нормализовать...

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

Признаки классификации безопасности Можно выделить следующие признаки классификации безопасности. 1. По признаку масштабности принято различать следующие относительно самостоятельные геополитические уровни и виды безопасности. 1.1. Международная безопасность (глобальная и...

Studopedia.info - Студопедия - 2014-2024 год . (0.008 сек.) русская версия | украинская версия