Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C лекції / 5.Функц_ї в С.docx
Скачиваний:
36
Добавлен:
05.03.2016
Размер:
53.42 Кб
Скачать

Передача параметрів

 Усі параметри, за винятком параметрів типу покажчик та масивів, передаються за значенням. Це означає, що при виклику функції їй передаються тільки значення змінних. Сама функція не в змозі змінити цих значень у викликаючій функції. Наступний приклад це демонструє:

#include

void test(int a)

{

  a=15;

  printf(" in test : a==%%d ",a);

}

void main()

{

  int a=10;

  printf("before test : a==%%d ",a);

  test(a);

  printf("after test : a==%%d ",a);

}

 При передачі параметрів за значенням у функції утворюється локальна копія, що приводить до збільшення об'єму необхідної пам'яті. При виклику функції стек відводить пам'ять для локальних копій параметрів, а при виході з функції ця пам'ять звільняється. Цей спосіб використання пам'яті не тільки потребує додаткового її об'єму, але й віднімає додатковий час для зчитування. Наступний приклад демонструє, що при активізації (виклику) функції копії створюються для параметрів, що передаються за значенням, а для параметрів, що передаються за допомогою покажчиків цього не відбувається. У функції два параметри - one, two - передаються за значенням, three - передається за допомогою покажчика. Так як третім параметром є покажчик на тип int, то він, як і всі параметри подібного типу, передаватиметься за вказівником:

#include

void test(int one, int two, int * three)

{

   printf( " Адреса one дорівнює %%р", &one );

   printf( " Адреса two дорівнює %%р", &two );

   printf( " Адреса three дорівнює %%р", &three );

   *three+=1;

}

main()

{

   int a1,b1;

   int c1=42;

   printf( " Адреса a1 дорівнює %%р", &a1 );

   printf( " Адреса b1 дорівнює %%р", &b1 );

   printf( " Адреса c1 дорівнює %%р", &c1 );

   test(a1,b1,&c1);

   printf(" Значення c1 = %%d ",c1);

}

   На виході ми отримуємо наступне:

Адреса а1 дорівнює FEC6

Адреса b1 дорівнює FEC8

Адреса c1 дорівнює FECA

Адреса one дорівнює FEC6

Адреса two дорівнює FEC8

Адреса three дорівнює FECA

Значення c1 = 43

   Після того, як змінна *three в тілі функції test збільшується на одиницю, нове значення буде присвоєно змінній c1, пам'ять під яку відводиться у функції main().

   У наступному прикладі напишемо програму, що відшукує та видаляє коментарі з програми на Сі. При цьому слід не забувати коректно опрацьовувати рядки у лапках та символьні константи. Вважається, що на вході - звичайна програма на Сі. Перш за все напишемо функцію, що відшукує початок коментарю (/*):

/*функція шукає початок коментарю */

void rcomment(int c)

{

   int d;

   if (c=='/')

  if (( d=getchar())=='*')

  in_comment();

  else

  if (d=='/')

  {

    putchar(c);

    rcomment(d);

  }

  else

  {

    putchar(c);

    putchar(d);

  }

   else   

   if (c=='\''|| c=='"') echo_quote(c);

  else putchar(c);

}

   Функція rcomment(int c) відшукує початок коментарю, а коли знаходить, викликає функцію in_comment(), що відшукує кінець коментарю. Таким чином, гарантується, що перша процедура дійсно ігноруватиме коментар:

/*функція відшукує кінець коментарю */

void in_comment(void)

{

   int c,d;

   c=getchar();

   d=getchar();

   while (c!='*'|| d!='/')

   {

  c=d;

  d=getchar();

   }

}

   Крім того, функція rcomment(int c) шукає також одинарні та подвійні дужки, та якщо знаходить, викликає echo_quote(int c). Аргумент цієї функції показує, зустрілась одинарна або подвійна дужка. Функція гарантує, що інформація всередині дужок відображається точно та не приймається помилково за коментар:

/*функція відображає інформацію без коментарю */

void echo_quote(int c)

{

   int d;

   putchar(c);

   while ((d=getchar()) !=c)

   {

  putchar(d);

  if (d=='\\')

  putchar(getchar());

   }

   putchar(d);

}

   До речі, функція echo_quote(int c) не вважає лапки, що слідують за зворотною похилою рискою, заключними. Будь-який інший символ друкується так, як він є насправді. А на кінець текст функції main() даної програми, що відкривається переліком прототипів визначених нами функцій:

/* головна програма */

#include 

void rcomment(int c);

void in_comment(void);

void echo_quote(int c);

main()

{

   int c,d;

   while ((c=getchar())!=EOF)

   rcomment(c) ;

   return 0;

}

   Програма завершується, коли getchar() повертає символ кінця файлу. Це був типовий випадок проектування програми із застосуванням функціонального підходу.