Урок 1. Структура программы

1.  Структура программы

Чтобы получить общее представление о программе на Cu, рассмотрим простой пример. Допустим, необходимо составить программу, которая вычисляет и печатает значение функции y=f(x) в интервале изменения х от 1 до 5 с шагом 0.5, причем, сама функция у=f(x) имеет вид:  (у=СУММА по i от 1 до 10 ДЛЯ x/i).

Остановимся на алгоритмической стороне задачи. Очевидно, что это типичная задача табулирования функции: в цикле, для каждого значения х, нужно вычислять и печатать значения х и у. Блок-схема такого алгоритма представлена на рисунке 2.1а. В процессе реализации такого алгоритма необходимо для каждого значения х производить вычисление у=(СУММА по i от 1 до 10 ДЛЯ x/i), которое, в свою очередь, определяется алгоритмом суммирования, изображенном на рисунке 2.1б. Таким образом, в алгоритме табулирования функции мы выделили вспомогательный алгоритм суммирования, разбив поставленную задачу на две более мелких подзадачи.

а) Алгоритм табулирования y=f(x)        б) Алгоритм вычисления функции

Рис. 2.1. Выделение подзадач.

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

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

На рисунке 2.2 представлена программа на Си, состоящая из главной функции main и функции с именем Summa. Рассмотрим эту программу.

#include <stdio.h>
#include <conio.h>
main() /*Табулирование у=f(х)*/
{
float x,y, Summa();
clrscr();
printf(" Значение х : Значение у:\n");
 
for(x=1; x <= 5; x += 0.5)
{
    y=Summa(10,x);
    printf(" %5.1f %6.3f \n",x,y);
}
}
 
float Summa( hbound, perem) /* Вычисление суммы по i в точке х */
int hbound;
float perem;
/*
такой стиль объявления параметров функции (вне заголовка)
давно не используется и оставлен, только в этой программе, как
"историческая иллюстрация".  Заголовок функции следовало бы записать так:
float Summa(int  hbound, float perem)
*/
{
int i = 1;
float rez = 0;
 
while (i <= hbound) rez += perem/i++;
    return (rez);
}

Рис 2.2 Программа на Си.

Первые две строки:
#include <stdio.h>

#include <conio.h>

не являются операторами языка Си. Символ # говорит о том, что это директивы препроцессора. Препроцессор осуществляет предварительную обработку текста программы перед началом компиляции и, в данном случае, эти директивы говорят о том, что в компилируемый файл нужно включить информацию, содержащуюся в системных файлах stdio.h (STanDard Input/Output Header- заголовок ввода-вывода ) u conio.h (CONsole Input/Output Header- заголовок ввода-вывода на Консоль). Наличие этих директив обусловлено тем, что в тексте программы использованы встроенные функции clrscr() и printf(), информация о которых включается из указанных файлов.

В Си, как впрочем и в большинстве языков программирования, наряду с функциями, определяемыми программистом, имеется богатая библиотека встроенных функций. Две из встроенных функций - clrscr() (очистка экрана) и printf() (вывод форматный) использованы в рассматриваемом примере программы.

Строка в программе:

main()/*Табулирование y=f(x)*/

определяет заголовок главной функции,  main() имя главной функции. Далее после имени записан комментарий, роль которого состоит в пояснении смысла программы. Пара самых внешних фигурных скобок - первая открывающая после main() и соответствующая ей закрывающая фигурная скобка определяют операторы, составляющие тело главной функции main().

Далее идет оператор описания данных:

float x,y, Summa();

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

После оператора описания данных следуют два оператора обращения к встроенным функциям библиотеки Турбо Си:

clrscr();

printf("Значение х : Значение у :/n");

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

Затем записан оператор цикла:

for(x=1; x <= 5; x += 0.5)
{
    y=Symma(10,x);
    printf(" %5.1f %6.3f \n",x,y);
}

 


реализующий алгоритм рисунка 2.1а. В цикле выполняются операторы, заключенные между фигурными скобками. При первом выполнении цикла, х принимает значение 1, при повторном выполнении х увеличивается на 0.5 ( об этом говорит конструкция х+=0.5 в заголовке цикла) и так происходит до тех пор, пока условие х<=5, истино.

При каждом выполнении цикла происходит обращение к функции Summa(). При обращении к функции Summa(), ей передаются значения аргументов - число 10, определяющее верхний предел суммирования по i и очередное значение х. Функция Summa() реализует алгоритм рисунка 2.1б. и вычисленное ею значение присваивается у.

Значения х и у в цикле печатаются встроенной функцией printf(), которая, в данном случае, содержит 3 аргумента: строку вывода, заключенную между кавычками, аргумент х, и аргумент у. Обратим внимание на строку вывода. Она состоит, из пробелов, среди которых записаны символы %5.1f, далее %6.3f, и в конце \n. Признак % в строке вывода говорит о том, что за ним следует, так называемый, формат вывода. Форматы вывода говорят о том, что в печатаемую строку надо вставить вместо %5.1f значение х, для которого отводится 5 позиций, в том числе, 1 позиция для дробной части, вместо %6.3f значение y, для которого отводится 6 позиций, в том числе, 3 позиции для дробной части.

В конце строки вывода имеется символ \n, который трактуется в Си, как управляющий символ, осуществляющий перевод печати на новую строку. Таким образом, функция printf() осуществляют печать строки вывода и, если в ней имеется формат, то вместо i- ого формата вставляется в печатаемую строку значение i- ого аргумента, записанного после строки вывода; если в строке вывода встречается управляющий символ , то на устройстве вывода, осуществляются действия, предписанные управляющим символом.

В контексте рассматриваемой нами программы функция printf () "впечатывает" под ранее напечатанный заголовок, в нужных позициях строки, значения х и у. В конечном итоге результат выполнения программы будет выглядеть так, как это представлено на рисунке 2.3. Пойдем дальше. Рассмотрим нашу функцию Summa(). Она записана вслед за функцией main(). Первые три строки содержат описание функции. Первая строка определяет имя функции (Summa), тип возвращаемого значения (float), имена формальных аргументов (hbound и perem). Следующие две строки определяют тип аргументов функции: hbound - целый (int), perem - плавающий, вещественный (floаt). Далее открывающая и закрывающая фигурные скобки ограничивают тело функции Summa. Первые две строки тела функции:

int i = 1;
float rez = 0;

являются операторами описания с инициализацией и устанавливают для i целый тип с присвоением начального значения 1, а для rez плавающий с присвоением начального значения 0.

Затем следует оператор цикла:

while(i <= hbound) rez += perem/i++;

который задает циклическое выполнение оператора

rez += perem/i++;

до тех пор, пока истино условие i<=hbound. Накопление суммы в rez осуществляется применением составной операции присваивания += , которая предписывает увеличить значение rez на perem/i. Как же происходит выход из цикла? В данном случае, здесь применена к i операция увеличения на единицу i++, характерная для Си. После вычисления значения perem/i и увеличения rez на это значение i увеличится на единицу, ввиду того, что применена постфиксная операция увеличения ++, т.е. оператор записан так, как это имеет место в программе rez+=perem/i++.

После завершения цикла сработает оператор выхода из функции:

return(rez);

который вернет в функцию main() значение rez.

Обращение к функции Summa() происходит всякий раз тогда, когда в функции main() выполняется оператор:

y=Summa(10,x).

При этом функция Summa() получает для hbound значение 10, а для perem значение х. С этими значениями, полученными для hbound и perem, выполняются операторы функции Summa(). После выполнения функции Summa(), что определяется отработкой оператора return (rez), значение rez передается в главную функцию main() и замещает собой сделанное оттуда обращение Summa (10, x), т.е. для у присваивается значение rez. Выполнение этой программы дает результат, представленный на рисунке 2.3.

Значение х :    Значение у :
1.0             2.929
1.5             4.393
2.0             5.858
2.5             7.322
3.0             8.787
3.5             10.251
4.0             11.716
4.5             13.180
5.0             14.645

Рис 2.3 Результат выполнения программы.

Итак, мы получили самое общее представление о программе на Си. Естественно, что при первом знакомстве некоторые элементы языка могут быть непривычными и, на первый взгляд, показаться неясными. Однако, учитывая собственный опыт работы на Си, уверяем вас, что это весьма интересный и эффективный язык программирования, позволяющий решать широчайший круг научных и прикладных задач. Дальнейшие разделы учебного пособия посвящены систематизированному и достаточно детальному рассмотрению языка Си для персональных компьютеров.

 

рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов