Програмування С, С++теорія та практика (частина 1)
1.16.3 Передача параметрів
Усі параметри, за винятком параметрів типу покажчик та масивів, передаються за значенням. Це означає, що при виклику функції їй передаються тільки значення змінних. Сама функція не в змозі змінити цих значень у викликаючій функції. Наступний приклад це демонструє:
#іпс1игіе<8'Ьгііо. Ь>
Vоій. 'Ьез'Ь (іп£ а) { а=15 ;
ргіп^£(" іп їезї : а==%гі\п",а);
};
Vоій. таіп () {
іп£ а=10;
ргіп^£("Ье£оге їезї : а==%гі\п",а); їезї(а);
ргіп'Ь£("а£'Ьег їезї : а==%й\п",а);
};
При передачі параметрів за значенням у функції утворюється локальна копія, що приводить до збільшення об’єму необхідної пам’яті. При виклику функції стек відводить пам’ять для локальних копій параметрів, а при виході з функції ця пам’ять звільняється. Цей спосіб використання пам’яті не тільки потребує додаткового її об’єму, але й віднімає додатковий час для зчитування. Наступний приклад демонструє, що при активізації (виклику) функції копії створюються для параметрів, що передаються за значенням, а для параметрів, що передаються за допомогою покажчиків цього не відбувається. У функції два параметри - опе, ґмо - передаються за значенням, ґкгее - передається за допомогою покажчика. Так як третім параметром є покажчик на тип іпі, то він, як і всі параметри подібного типу, передаватиметься за вказівником:
#іпс1игіе <з,Ьгііо.Ь>
VОІЙ. ■ЬеЗ'Міп'Ь опе, іп£ ■Ьмо, іп£ * ■ЬЬгее)
{
ргіп^£( "\пАдреса опе дорівнює %р", &опе ); ргіп^£( "\пАдреса 'Ьмо дорівнює %р", &£мо ) ; ргіп^£( "\пАдреса 'ЬЬгее дорівнює %р", і'ЬЬгее ) ; *'ЬЬгее+=1;
}
таіп()
{
іп£ а1,Ь1; іп£ с1=42;
ргіп^£( "\пАдреса а1 дорівнює %р", &а1 ); ргіп^£( "\пАдреса Ь1 дорівнює %р", &Ь1 ); ргіп^£( "\пАдреса с1 дорівнює %р", &с1 ); ^ез^(а1,Ь1,&с1);
ргіп'Ь£("\пЗначення с1 = %й\п",с1);
}
На виході ми отримуємо наступне:
Адреса а1 дорівнює ЕЕС6 Адреса Ь1 дорівнює ЕЕС8 Адреса с1 дорівнює ЕЕСА Адреса опе дорівнює ЕЕС6 Адреса їмо дорівнює ЕЕС8 Адреса їЬгее дорівнює ЕЕСА Значення с1 = 43
Після того, як змінна *1гее в тілі функції ґезґ збільшується на одиницю, нове значення буде присвоєно змінній сі, пам’ять під яку відводиться у функції таіп().
У наступному прикладі напишемо програму, що відшукує та видаляє коментарі з програми на Сі. При цьому слід не забувати коректно опрацьовувати рядки у лапках та символьні константи. Вважається, що на вході - звичайна програма на Сі. Перш за все напишемо функцію, що відшукує початок коментарю (/*):
/♦функція шукає початок коментарю */
Vоій гсоттепї (іпї с) { іпї й; і£ (с==' /')
і£ (( й=де'ЬсЬаг ())=='*') іп_соттепї(); е1зе і£ (й=='/') {
риїсЬаг(с); гсоттепї(й) ;
}
е1зе {
риїсЬаг(с) ; риїсЬаг(й) ;
}
е1зе і£ (с=='\''|| с=='"') есЬо_дио'Ье(с); е1зе
риїсЬаг(с) ;
}
Функція гсоттепґ(іпґ с) відшукує початок коментарю, а коли знаходить, викликає функцію іп_соттепІ(), що відшукує кінець коментарю. Таким чином, гарантується, що перша процедура дійсно ігноруватиме коментар:
/♦функція відшукує кінець коментарю */
Vоій іп_еоттеп^ ^оій)
{
іп£ с,й;
с=де'ЬсЬаг() ;
й=де'ЬсЬаг() ;
мЬіІе (с!='*'|| й!='/')
{
с=й;
й=де'ЬсЬаг();
}
}
Крім того, функція гсоттепі(іпі с) шукає також одинарні та подвійні дужки, та якщо знаходить, викликає еско_диоіе(іпі с). Аргумент цієї функції показує, зустрілась одинарна або подвійна дужка. Функція гарантує, що інформація всередині дужок відображається точно та не приймається помилково за коментар:
/♦функція відображає інформацію без коментарю */
Vоій есЬо_дио^е (іп£ с)
{
іп£ й; ри'ЬсЬаг(с) ;
мЬіІе ((й=де'ЬсЬаг()) !=с)
{
ри'ЬсЬаг (й) ; і£ (й=='\\')
ри'ЬсЬаг (де'ЬсЬаг ());
}
ри'ЬсЬаг(й);
}
До речі, функція еско_диоіе(іпі с) не вважає лапки, що слідують за зворотною похилою рискою, заключними. Будь-який інший символ друкується так, як він є насправді. А на кінець текст функції таіп() даної програми, що відкривається переліком прототипів визначених нами функцій:
/* головна програма */
#іпс1ийе <з^йіо.Ь>
Vоій гсоттеп'Ь (іп£ с) ;
Vоій іп_соттеп^(Vоій);
Vоій есЬо_дио^е(іп£ с) ;
таіп()
{
іпї с,й;
мЬі1е ((с=деїсЬаг())!=ЕОЕ) гсоттепї(с) ;
геїигп 0;
}
Програма завершується, коли §еґскаг() повертає символ кінця файлу. Це був типовий випадок проектування програми із застосуванням функціонального підходу.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
