Опорный конспект Форма ф со пгу 18. 2/05 Министерство образования и науки Республики Казахстан

Вид материалаКонспект

Содержание


4.3 Потоки. Функции
Пример: #include
Четыре стандартных потока
Пример функции
Формальные параметры функций
Замечание. В Паскале для изменения значений элементов аналогичного массива в процедуре мы написали бы
Возвращаемые значения функций
На Паскале
Функция main
Подобный материал:
1   ...   4   5   6   7   8   9   10   11   ...   15

4.3 Потоки. Функции



Потоком называется абстрактное понятие, относящееся к любому переносу данных от источника (или поставщика данных) к приемнику (или потребителю) данных. Также используются си­нонимы извлечение, прием и получение, когда речь идет о вво­де символов от источника, и вставка, помещение или запомина­ние, когда речь идет о выводе символов на приемник. Кроме того, класс потока может быть использован для форматирования данных в ситуациях, не подра­зумевающих реального выполнения ввода/вывода. Например, форматирование в памяти можно применять к символьным массивам и прочим структурам.

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

Пример:

#include

#include


int main(void)

{ char line[20];

clrscr();

cout<< "\n Ваше имя?: ";

cin>>line;

cout<<"Hello, "<

getch();

return 0;

}

В этом примере cout и cin являются стандартными потоками вывода и ввода соответственно. Операции << и >> имеют при работе с потоками иной смысл, чем в обычном C – здесь используется так называемая перегрузка или переопределение операций – одна из возможностей C.

Четыре стандартных потока


Программы С начинаются с четырьмя предопределенными открытыми потоками, объявленными как объекты классов withassign в iostream.h следующим образом:

extern istream_withassign cin;

extern ostream_withassign cout;

extern ostream_withassign cerr;

extern ostream_withassign clog;

Их конструкторы вызываются всякий раз при включении iostream.h, но фактическая инициализация выполняется только один раз.

Четыре стандартных потока выполняют следующее:
  • cin Стандартный ввод (дескриптор файла 0) (Соответствует stdin)
  • cout Стандартный вывод (дескриптор файла 1) (Соответствует stdout)
  • cerr Стандартный вывод ошибок (дескриптор файла 2).
  • cerr буферизуется поблочно; очистка буфера происходит при каждой новой вставке (Соответствует stderr)
  • clog Данный поток представляет собой полностью буфери­зуемую версию cerr.

Функции


В отличие от Паскаля в Си нет разделения на процедуры и функции. Имеются только функции, а если они ничего не возвращают, то есть являются аналогом процедур в Паскале, то считается (и явно указывается), что они возвращают значение "пустого" типа void.

Пример функции:

#include
unsigned long fact(unsigned long n)
 { unsigned long ret=l;
    while (n>0) {ret*=n;n--;} ;
     return ret;
}


void main(void)
{ unsigned long n;
   printf ("\nЧисло? (<=12) ") ;scanf("%ld", &n) ;
   printf ("Факториал %ld = %ld" , n, fact (n) ) ;
}


Обратите внимание на оператор return. Именно с его помощью функция возвращает значение (и в этом месте заканчивает работу).

Упрощенно заголовок функции может быть описан так:

<тип возвращаемого значения> <имя функции>(<список формальных параметров>)

Формальные параметры функций


Пример: в объявлении функции int sum(int a, int b) а и b — формальные параметры, при вызове — sum(x,y) х и у — фактические. Список параметров функции задается в круглых скобках после имени функции. Разделяются параметры запятыми.

Пример: int f(int n, int m, float r, char с)

При этом надо иметь в виду следующее:

Необходимо явно указывать тип каждого параметра (даже если типы подряд идущих параметров совпадают).

Пример: void f(int n,int m) — верно, void f(int n,m) — неверно.

Дело в том, что Си по умолчанию считает, что если тип параметра не задан, то тип этот — int. Если написать что-нибудь вроде void f (float r,p) , то понято это будет как void f (float f, int p) . А поэтому надо всегда явно указывать тип параметров, а не пользоваться мало кому известными "соглашениями".

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

Примеры:

void f(int a) 
{ а++;}


Следующий фрагмент: t=1; f (t) ; оставит значение переменной t без изменения (как была она равна 1, так и останется).

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

procedure f(var a) ;

begin

inc (a);

end;

Приведем теперь пример функции, в которую передается массив:

void init_10(int a[10])
{ int i;
  for (i=0;i<10;i++) a[i]=i;


}

Если вызвать эту функцию от некоторого массива, то его элементы изменят свои значения. То есть, в терминологии Паскаля, массивы всегда передаются с var.

Замечание. В Паскале для изменения значений элементов аналогичного массива в процедуре мы написали бы:

type arrayl0=array[0..9] of integer;
procedure init_10(var a:arrayl0);
  var i: integer;
    begin
       for i:=0 to 9 do a[i]=i 
  end;


Возвращаемые значения функций


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

На Паскале:

function simple(n: integer):boolean; {является ли число простым}
 var i: integer; sqrtn:real;


begin

simple:=true;

i:=2;sqrtn:=sqrt (n) ;

while (i<=sqrtn) and (n mod i <> 0) inc(i);

if (n mod i=0) then simple:=false
end;


На Си:

int simple(int n) /*является ли число простым*/
 { int i=2; float sqrtn=sqrt(n);
   while (

return (n%i) ;

}

Обратите внимание, что в примере на Паскале после первого присваивания simple :=true ничего не происходит, а вот на Си оператор return "выбросил" бы нас из функции. Переменная sqrtn в обеих программах введена для оптимизации цикла. Ну и, наконец, для корректной работы этой функции в Си требуется подключить math.h (включить в программу строчку #include ).

Функция main


В простейшем случае программа на Си состоит из одного файла, который, в свою очередь, содержит единственную функцию, которая имеет имя main. Можно считать, что функция main является аналогом тела программы в Паскале. В начале выполнения программы на Си управление передается на первый исполняемый оператор функции main. Функция main, конечно, не совсем обычная, и у нее имеется ряд особенностей. Во-первых, она так же, как и все другие функции, может возвращать значения, но лишь определенных типов. Во-вторых, в нее тоже можно передавать параметры (это те самые параметры, которые указываются в командной строке вызова ЕХЕ-файла).