Friday, June 10, 2016

c හා c++ ප්‍රෝග්‍රැමිං - 10

2

ඉහත උදාහරණවලදී කළා මෙන් බොහෝමයක් ෆන්ක්ෂන් අප විසින්මයි සාදා ගන්නේ. එහෙත් සමහර ෆන්ක්ෂන් අප විසින් සාදන්නේ නැති බවද ඉහතදී දුටුවා. ඒවා වෙන අය විසින් සාදා තිබෙනවා. අපට තියෙන්නේ ඒවා අවශ්‍ය තැන්වල පාවිච්චි කිරීමටයි (printf, scanf යනු මෙවැනි ෆන්ක්ෂන්වලට උදාහරණ දෙකකි). අප විසින්ම සාදා ගන්නා ෆන්ක්ෂන් user-defined function (මෙහි තේරුම "අප/යූසර්/ප්‍රෝග්‍රැමර් විසින්ම සාදන ෆන්ක්ෂන්" යන්නයි) ලෙස හැඳින්වෙන අතර, වෙන අය සාදා අපට පාවිච්චි කිරීමට ලබා දී තිබෙන ෆන්ක්ෂන් library function ලෙස හැඳින්වෙනවා. මේවාට ලයිබ්රරි ෆන්ක්ෂන් යන නම ලැබී තිබෙන්නේ මෙලෙස ෆන්ක්ෂන් විශාල සංඛ්‍යාවක් සාමාන්‍යයෙන් ලබා දෙන බැවිනි (පොත් ගොඩක් තිබෙන තැනකට ලයිබ්රරි හෙවත් පුස්ථකාලයක් කියා කියන්නා සේ, ෆන්ක්ෂන් ගොඩක් තිබෙන තැනකුත් ලයිබ්රරි එකක් තමයි).

ඔබ විසින් අනර්ඝ විදියට සාදන ෆන්ක්ෂන් වෙනත් අයටත් නිතර නිතර අවශ්‍ය වේ යැයි සිතනවා නම්, ඔබටත් පුලුවන් ඒවා වෙන අයට ලබා දෙන්නට කටයුතු කරන්න. එවිට ඔබේ එම ෆන්ක්ෂන් එකත් ලයිබ්රිරි ෆන්ක්ෂන් එකක් වේවි. බොහෝ ප්‍රෝග්‍රැමර්ස්ලා ඇත්තටම බහුලව අවශ්‍ය වන වැදගත් වැඩකටයුතු කර ගැනීමට එලෙස ෆන්ක්ෂන් ලයිබ්රරි එකක් (එනම් ෆන්ක්ෂන් පුස්තකාලයක්) සාදා ගන්නවා. එවිට, ඔවුන් ප්‍රෝග්‍රෑම් සාදන විට, බොරුවට වරු ගණන් ප්‍රෝග්‍රෑම් ලිය ලිය ඉන්නේ නැතිව තමන්ගේ ලයිබ්රරි එකේ තිබෙන ෆන්ක්ෂන් යොදා ගෙන ඉක්මනින්ම ප්‍රෝග්‍රෑම් එක සාදන්නට හැකියාව ලැබී තිබෙනවා. ෆන්ක්ෂන් භාවිතය නිසා ඇති වූ තවත් ඉතාම වැදගත් වාසියක් තමයි එය. සමහරුන් නොමිලේ ලයිබ්රරි ෆන්ක්ෂන් (හෝ ෆන්ක්ෂන් ලයිබ්රරි) ලබා දෙන අතර, සමහරුන් මුදලට ලබා දේ.

ෆන්ක්ෂන් එකක් ඩිෆයින් කරන්නේ ප්‍රෝග්‍රෑම් එකේ කොතැනද? main() එකට පෙරද? පසුද? ඇත්තෙන්ම මෙය වැදගත් ප්‍රශ්නයක්. main() ට පෙරයි මාගේ උදාහරණවල නම් එය කර තිබෙන්නේ. ඔබටත් එලෙසම ඔබේ සෑම ෆන්ක්ෂන් එකක්ම main() ට පෙර ඩිෆයින් කළ හැකියි. එහෙත් ප්‍රායෝගික තලයේදී සාමාන්‍යයෙන් ෆන්ක්ෂන් ඩිෆයින් කර තිබෙන්නේ main() ට පසුවයි (එවිට ප්‍රෝග්‍රෑම් එකක් කියවීමට හා තේරුම් ගැනීමට පහසුවක් ඇති වේ). මා පහත දක්වා තිබෙන උදාහරණයේදී ෆන්ක්ෂන් එක ඩිෆයින් කර තිබෙන්නේ main() ට පසුවයි. එය වැඩ කරනවාද නැද්ද කියා බැලීමට ඔබත් එය කම්පයිල් කර බලන්න.

#include <stdio.h>

int main()
    {
    int result2;
    result2 = MultiplyNumbers(20, 10);
    printf("the result2 has %d\n",result2); /* displays the result2 */
    return 0;
    }

/* A simple function to multiply 2 numbers */
int MultiplyNumbers(int a, int b)
    {
    int result;
    result = a * b;
    return(result);
    }

සමහර අයට මෙය කම්පයිල් වේවි; සමහර අයට කම්පයිල් කරන්නට ඉඩ නොදී එරර් එකක් ලබා දේවි. කම්පයිල් වන අයට වුවත්, එය කම්පයිල් වන විට, යම් කිසි අවවාදයක් (warning) නම් ලබා දෙනවාමයි. කම්පයිල් වෙනවාද නැද්ද යන්න තීරණය වන්නේ ඔබ යොදා ගන්නා කම්පයිලරය අනුවයි. එහෙත් සම්මතයක් ලෙස නම්, කම්පයිල් නොවිය යුතුයි! (ඔබ දන්නවා ලෝකයේ සියලු දේම සිදු වන්නේ සම්මතය හෝ නීතියට අනුව නොවෙයිනෙ). මාගේ පරිගණකයේදිත් එය කම්පයිල් වූවා; එහෙත් පහත ආකාරයේ වෝර්නිං එකකුත් (අවවාදයක්) ලැබුණා.


සටහන
කම්පයිල් කිරීමේදී ඔබේ ප්‍රෝග්‍රෑම් එක හරියටම නිවැරදියි නම්, කිසිදු එරර් හෝ වෝර්නිං මැසේජ් නොලැබම එය සිදු වේවි. එහෙත් ප්‍රෝග්‍රෑම් එකේ බරපතල වැරදි ඇත්නම් ඔබ දන්නවා කම්පයිල් නොවී එම වැරැද්ද ගැන කෙටි සටහනක් (ඊට අප error message කියා කියනවා) ලැබේවි. තවත් අවස්ථාවලදී එරර් මැසේජ් නොදී වෝර්නිං මැසේජ් එකක් ලබා දේ. මෙහිදී ඇති විශේෂත්වය වන්නේ ප්‍රෝග්‍රෑම් එක කම්පයිල් වීමයි. එහෙත් සුලු දෝෂ තිබෙන බව වෝර්නිං එකේදී කියයි. බොහෝවිට මෙම සුලු දෝෂ ප්‍රෝග්‍රෑම් එකට හානියක් සිදු නොකරයි (එනිසා තමයි එම දෝෂ තිබියදීත් කෝඩ් එක කම්පයිල් වන්නේ). වෝර්නිං මැසේජ් එක කියවා එම දෝෂද ඉවත් කරන්නට කටයුතු කරන්නේ නම් එය ඉතා හොඳ ප්‍රෝග්‍රෑම් පුරුද්දකි.

ඒ අනුව දැන් ඔබට වැටහෙන්නට ඕන ෆන්ක්ෂන් එකක් main() ට පෙර ඩිෆයින් කර ඇති විට කිසිදු ගැටලුවක් නැතත්, main() ට පසුව ඩිෆයින් කරන විට යම් ගැටලුවක් ඇති බව. ඊට හේතුව සරලයි. නැවත ඉහත උදාහරණය බලන්න. සෝස් කෝඩ් එක ඔබ මුල ඉඳන් පේලියෙන් පේලියට කියවාගෙන යන්න (සාමාන්‍යයෙන් කම්පයිලරයද කියවන්නේ එලෙසයි). එසේ කියවගෙන යන අතරේදී ඔබට/කම්පයිලරයට හමුවෙනවා result2 = MultiplyNumbers(20, 10); යන ස්ටේට්මන්ට් එක. එහි තිබෙනවා MultiplyNumbers යනුවෙන් එකක්. එය කුමක්ද? ඔබ එය කුමක්දැයි දන්නේ නැහැනෙ. (ඔබ දැන් කියාවි මොකද දන්නෙ නැත්තේ ඉන් සිදු කරන්නේ සංඛ්‍යා දෙකක් ගුණ කර ගුණිතය රිටර්න් කරන එක කියා; ඔබ එලෙස කියන්නේ මීට පෙර උදාහරණවලදී අප ඒ ගැන බොහෝමයක් කතා කළ නිසාය; එහෙත් පළමු පාරට කියවන කෙනෙකුට නම්, ඉන් එතරම් දෙයක් හැඟවෙන්නේ නැත.) එම දේමයි කම්පයිලරයටත් සිදු වන්නේ. පසුවට එම ෆන්ක්ෂන් එකෙන් කරන්නේ කුමක්දැයි සටහන් වුවත්, ඔබ එය දැන්ගන්නට දැන් සිටින තැන පසු කර යා යුතුය. ප්‍රශ්නය තිබෙන්නේ ඔබ දැන් සිටින ස්ථානයේය. ඉතිං එම කමාන්ඩ් එක රන් නොකර පස්සෙ ඒක ගැන බලා ගන්නම් කියා යා නොහැකියි. එහෙත් ෆන්ක්ෂන් එක main() ට පෙර ඩිෆයින් කර තිබුණා නම්, එම ගැටලුව ඇති වෙන්නේ නැත මොකද ෆන්ක්ෂන් එක කෝල් කරන්නට පෙර ෆන්ක්ෂන් එක ගැන අප/කම්පයිලරය දන්නවා.

මීට පිළියම් දෙකක් තිබේ. එකක් නම් කම්පයිලරය සෝස්කෝඩ් එකක් කම්පයිල් කිරීමේදී කිහිප පාරක්ම සෝස්කෝඩ් එක කියවා පෙර විස්තර කළ විදියට නොදන්නා ෆන්ක්ෂන් නේම් එකක් දුටු විට, සෝස් කෝඩ් එකේ පසු කොටසේ එය තිබේදැයි සොයා බැලිය හැකියි. ඇත්තටම සමහර කම්පයිලර් සිදු කළේ එය තමයි. එසේ සිදු කළත්, එය සී කම්පයිලර් එක ක්‍රියා කරන සම්මත ක්‍රමය නොවන නිසා, වෝර්නිං එකක් ලබා දෙනවා (තවද සෑම කම්පයිලරයක්ම එය සිදු කරන්නේද නැත).

දෙවැනි පිළියම හැමතිස්සෙම ක්‍රියා කරන ඉතා හොඳ එකකි. මෙහිදීත් සියලුම ෆන්ක්ෂන් ඩිෆයින් කරන්නේ main() ට පසුවයි. එහෙත් එම ෆන්ක්ෂන්වල හෙඩර් කොටස පමණක් main() ට පෙර ලිවිය යුතුය (අගට සෙමිකෝලන් එකක්ද දැමිය යුතුයි). පහත උදාහරණයෙන් එය පැහැදිලි වේවි. පහත ප්‍රෝග්‍රෑම් එකත් කම්පයිල් කර බලන්න. කිසිදු වෝර්නිං එකක් හෝ එරර් එකක් නොලැබී සාර්ථකව කම්පයිල් වේවි.

#include <stdio.h>

int MultiplyNumbers(int a, int b); /* function prototype */

int main()
    {
    int result2;
    result2 = MultiplyNumbers(20, 10);
    printf("the result2 has %d\n",result2); /* displays the result2 */
    return 0;
    }

/* A simple function to multiply 2 numbers */
int MultiplyNumbers(int a, int b)
    {
    int result;
    result = a * b;
    return(result);
    }

ඉහත කෝඩිංවල තද අකුරින් පෙන්වා තිබෙන්නේ සිදු කළ වෙනසයි. එම කොටස බැලූබැල්මට ෆන්ක්ෂන් හෙඩර් එකට සමානයි නේද? ඔව්. එහෙත් දැන් එම කොටසට ෆන්ක්ෂන් හෙඩර් කියා කියන්නේ නැත. එය හඳුන්වන්නේ function prototype කියාය. ෆන්ක්ෂන් ප්‍රොටෝටයිප් එකේ රාජකාරිය තමයි, ප්‍රෝග්‍රෑම් එක ආරම්භයේදීම කම්පයිලරයට (හා ඔබට) මතක් කර දෙනවා, පහත ප්‍රෝග්‍රෑම් එක රන් වීමේදී මෙන්න මේ මේ ආකාරයේ ෆන්ක්ෂන් ඔබට හමු වේවි කියා. එවිට, කම්පයිලරය සූදානම් වෙනවා එම ෆන්ක්ෂන් මොනවාද කියා කල්තියාම සොයා බලන්නට. අප සාදන සෑම ෆන්ක්ෂන් එකකම (එනම් යූසර්-ඩිෆයින්ඩ් ෆන්ක්ෂන් සඳහා) මෙලෙස ප්‍රොටෝටයිප් ලිවිය යුතුයි.

දැන් ප්‍රශ්නයක් මතු වෙනවා එතකොට printf, scanf වැනි ලයිබ්රරි ෆන්ක්ෂන්වල ප්‍රොටෝටයිප් ලිව්වේ නැත්තේ මොකද කියා. ඇත්තෙන්ම ඒවා සඳහාද ප්‍රොටෝටයිප් ලිවිය යුතුයි. එසේනම් ඒවා ඉහත කිසිදු ප්‍රෝග්‍රෑම් එකක් නොතිබුණේ ඇයි? ඒවා නොතිබුණා නොවේ; ඒවා තිබුණා. එහෙත් එකවර ඔබට ඒවා පෙනෙ ලෙස නෙමේ තිබුණේ. එය සිදු කළේ ඒ සෑම ප්‍රෝග්‍රෑම් එකකම මුලින්ම #include <studio.h> යන කොටසින්. මේ ගැන දැන් විමසා බලමු.

#include යන "කමාන්ඩ්" එකෙන් සිදු කරන එකම රාජකාරිය ඊට පසුව ලියනු ලබන වචනයෙන් හඳුන්වන ෆයිල් එක කියවා එම ෆයිල් එකේ තිබෙන සියලුම අන්තර්ගතය හෙවත් අකුරු (කෝඩිං) include කමාන්ඩ් එක තිබෙන තැනට "කොපි පේස්ට්" කිරීම පමණයි. ඇත්තටම මෙය මා කමාන්ඩ් ලෙස හැඳින් වුවත්, එය කමාන්ඩ් එකක් නොවේ. ඊට directive හෝ preprocessor directive යැයි කියනවා (directive යන ඉංග්‍රිසි වචනයේ සාමාන්‍ය තේරුම “අණ කිරීම” යන්නයි). ඇත්තෙන්ම සී වල include හැරුණහම තවත් ඩිරෙක්ටිව් කිහිපයක්ම තිබෙනවා (ඒවා ගැන පසුව බලමු). සෑම ප්‍රෝග්‍රෑම් එකකටම නැතිවම බැරි ඩිරෙක්ටිව් එක තමයි include. ඩිරෙක්ටිව් එකක් හැමවිටම # සලකුණට (මෙම සලකුණ pound හෝ hash සලකුණ ලෙස හඳුන්වනවා) පසුවයි ලියන්නේ. ඩිරෙක්ටිව් එකක් කියා හඳුනාගන්නේ ඒ මඟිනි. කමාන්ඩ් නොවන නිසා, මේවාට පිටුපසින් සෙමිකෝලන් යොදන්නේ නැත.

මීට කමාන්ඩ් කියා නොකියන හේතුව මෙයයි. කමාන්ඩ් එකක් යනු ප්‍රෝග්‍රෑම් එකක් රන් වන විට, ක්‍රියාත්මක වන එකකි. එවිට, සෝස්කෝඩ් එකේ මෙන්ම බයිනරි කෝඩ් එකෙත් එම කමාන්ඩ් පවතිනවා (සෝස්කෝඩ් එකේදි ඉංග්‍රිසි වචනයක් හෝ යම් සංඛේතයක් ලෙසත්, බයිනරි කෝඩ් එකේදී 1 හා 0 ආශ්‍රයෙනුත් එම කමාන්ඩ් පවතිනවා). එහෙත් ඩිරෙක්ටිව් එකක් රන් වන්නේ නැත. ඊට හේතුව කිසිම ඩිරෙක්ටිව් එකක් බයිනරි කෝඩිං තුලට යන්නේ නැති වීමයි. ඇත්තටම සෝස් කෝඩ් එක කම්පයිල් වීමට පෙර, තවත් ක්‍රියාවලියක් සිදු වෙනවා (එම ක්‍රියාවලිය preprocessor ලෙස හැඳින්වෙනවා).

සටහන
මෙතෙක් මා පැවසුවේ සෝස්කෝඩ් ලියා එය කම්පයිල් කරන්න කියා පමණි. එය බැලූබැල්මට තනි ක්‍රියාවක් වගේ ඔබට පෙනුනත් ඇත්තටම එතැන ක්‍රියාවලි කිහිපයක් පිලිවෙලින් සිදු වේ. ඉන් එක් ක්‍රියාවලියක් තමයි preprocessor එක ක්‍රියාත්මක වීම. ඉන්පසු තමයි කම්පයිල් ක්‍රියාවලිය සිදු වන්නේ. මෙම කම්පයිල් ක්‍රියාවලියත් සමහරවිට තවත් උපක්‍රියාවලි කිහිපයකින් යුක්ත විය හැකියි. උදාහරණයක් ලෙස linking නම් උපක්‍රියාවලියක් කම්පයිල් ක්‍රියාවලිය තුල ඇත. එහෙත් මේ සියල්ල සිදු වන්නේ ඔබට නොදැනී ස්වයංක්‍රියවයි. ඒ නිසා අමුතුවෙන් බය වන්නට දෙයක් එහි නැත.

එම ප්‍රීප්‍රොසෙසර් ක්‍රියාවලිය තුලදී තමයි ඩිරෙක්ටිව්වල බලපෑම තිබෙන්නේ. ඉතිං, ප්‍රීප්‍රොසෙසර් ක්‍රියාවලියේදී include ඩිරෙක්ටිව් එකේ රාජකාරිය වන යම් ෆයිල් එකක අන්තර්ගතය සෝස්කෝඩ් එකේ කොපි කිරීම සිදු වේ. එවිට, කම්පයිලරය ක්‍රියාත්මක වන අවස්ථාව වන විට include ඩිරෙක්ටිව් එකක් දක්නට ලැබෙන්නේ නැත; ඒ වෙනුවට තිබෙන්නේ යම් ෆයිල් එකක තිබූ දේවල් කොපි වී තිබීමයි (මෙලෙස කොපි වන්නේද සී කෝඩිං බව අමුතුවෙන් කිව යුතු නැහැනෙ). උදාහරණයක් ඇසුරින්ම මෙය බලමු. පහත කෝඩිං ලියා එය sample.h යන නමින් සේව් කරගන්න.

/* sample.h file for demo */

/* A simple function to multiply 2 numbers */
int MultiplyNumbers(int a, int b)
    {
    int result;
    result = a * b;
    return(result);
    }

දැන් පහත කෝඩිං එකත් sample.c ලෙස (හෝ තමන් කැමති වෙනත් නමකින්) ඉහත sample.h යන ෆයිල් එක සේව් කළ ෆෝල්ඩර් එකේම සේව් කර, කම්පයිල් කර රන් කර බලන්න. සාර්ථකව රන් වේවි.

#include <stdio.h>

#include “sample.h”

int main()
    {
    int result2;
    result2 = MultiplyNumbers(20, 10);
    printf("the result2 has %d\n",result2); /* displays the result2 */
    return 0;
    }

බලන්න දැන් අපි MultiplyNumbers යන ෆන්ක්ෂන් එක යොදා ගෙන තිබුණත්, එම ෆන්ක්ෂන් එකේ ඩෙෆිනිෂන් එක (හා ප්‍රොටෝටයිප් එක) දක්නට නැහැ. ඔබට එකවරම පෙනෙන්නේ ඉහත කුඩා කොඩිං කොටස පමණි. එහෙත් කම්පයිලරයට ඊට වඩා දිගු කෝඩිං එකක් තමයි පෙනෙන්නේ. ඊට හේතුව කම්පයිල් වන්නට මොහොතකට පෙර include යන ඩිරෙක්ටිව්ස් ක්‍රියාත්මක වී වෙනත් අමතර කෝඩිං ප්‍රමාණයක් මෙම සෝස්කෝඩ් එකට එකතු කිරීමයි. ඒ අනුව ඇත්තටම කම්පයිල් වන මොහොතේදී කම්යපයිලරයට පේන්නේ පේලි 1000කට වඩා ඇති විශාල සෝස් කෝඩ් එකකි. කම්පයිලරයට ඇත්තටම පෙනෙන එම පේලි 1000කට අධික සෝස්කෝඩ් එක මා මෙහි පෙන්වන්නට යන්නේ නැත (එය නිකරුණේ පිටු නාස්තියක් නිසා). ඉහත ප්‍රෝග්‍රෑම් එකේ පේලි ඇත්තේ 11ක් පමණය. #include “sample.h” යන්න ක්‍රියාත්මක වීම නිසා තවත් පේලි 9ක් පමණ ඊට එකතු විය (sample.h ෆයිල් එකේ තිබුණේ පේලි 9ක් නිසා). ඉතිරි පේලි නමසිය ගණනම #include <stdio.h> යන්න ක්‍රියාත්මක වීම නිසාය (ඒ කියන්නේ stdio.h යන ෆයිල් එකේ පේලි නමසිය ගණනක් තිබේ).

සටහන
ඔබට ආසාවක් ඇත්නම් stdio.h ෆයිල් එකේ තිබෙන්නේ මොනවාද කියා දැන ගන්නට, ලිනක්ස් මෙහෙයුම් පද්ධතියක නම්, මෙම ෆයිල් එක /usr/include/ යන පාත් එකේදී දැක ගත හැකියි. වින්ඩෝස් මෙහෙයුම් පද්ධතියක නම්, ඔබ භාවිතා කරන කම්පයිලරය හෝ IDE එක අනුව එය පිහිටන පාත් එක වෙනස් වේ (එනිසා search කර එය සොයා ගන්න).

ෆන්ක්ෂන් එකක් තවත් ෆන්ක්ෂන් එකක් තුල සිට කෝල් කළ හැකියි. එවිට කෝල් කරන ෆන්ක්ෂන් එක calling function හෝ caller යනුවෙන් හැඳින්වෙන අතර, කෝල් කරනු ලබන ෆන්ක්ෂන් එක called function හෝ callee ලෙස හැඳින්වේ. පහත උදාහරණය බලන්න.

/* A demo program to show how caller and callee works */

#include <stdio.h>

/* function prototypes */

void CalleeFunc1();
void CalleeFunc2(int num1);
void CallerFunction();

int main()
    {
    printf("I am now in main function\n");
    CallerFunction(); /* Calling the CallerFunction() */

    return 0;
    }

/* function definitions */

void CalleeFunc1()
    {
    printf("I am in callee function 1 now\n");
    CalleeFunc2(29); /* Calling CalleeFunc2 from within CalleFunc1 */
    }

void CalleeFunc2(int num1)
    {
    printf("I am in callee function 2 now with %d\n",num1);
    }

void CallerFunction()
    {
    printf("I am in the caller function\n");
    CalleeFunc1(); /* Calling CalleeFunc1 from within CallerFunction */
    printf(“End of function calls\n”);
    }

ඉහත උදාහරණයේ ෆන්ක්ෂන් 3ක් ඇත. main() තුල සිට පළමුව CallerFunction නම් ෆන්ක්ෂන් එක කෝල් කරයි. එම ෆන්ක්ෂන් එකේ ඇත්තේ ස්ටේටම්න්ට් 2කි. පළමුව අැති printf() ෆන්ක්ෂන් එකෙන් I am in the caller function යන්න දර්ශනය කරයි. දෙවැනි ස්ටේට්මන්ට් එකෙන් කරන්නේ CalleeFunc1 නම් ෆන්ක්ෂන් එක කෝල් කිරීමයි. අප දැනටමත් සිටින්නේ CallerFunction නම් ෆන්ක්ෂන් එක තුලයි. එහි සිට (එනම් එම ෆන්ක්ෂන් බොඩි එකේ සිට) CalleeFunc1 නම් තවත් ෆන්ක්ෂන් එකක් කෝල් කරනවා. මෙහිදී CallerFunction යන්න calling function ලෙසත්, CalleeFunc1 යන්න called function ලෙසත් ක්‍රියා කරනවා නේද? CalleeFunc1 ෆන්ක්ෂන් එක දැන් රන් වන්නට පටන් ගන්නවා. එහෙත් තවමත් CallerFunction එක අවසන් වී නැත. එය අවසන් වන්නේ කෝල් කරපු CalleeFunc1 රන් වී අවසන් වූ පසුවයි.

දැන් CalleeFunc1 තුළද CalleeFunc2 යන ෆන්ක්ෂන් එක කෝල් කරනවා. එවිට, දැන් CalleeFunc2 රන් වන්නට පටන් ගන්නවා (මෙම අවස්ථාවේදී CalleeFunc2 යන්න called function එක වන අතර, CalleeFunc1 යන්න calling function වේ). CalleeFunc2 තුළ තවත් ෆන්ක්ෂන් කෝල් කරන්නේ නැත. ඉතිං එය යම් මැසේජ් එකක් පමණක් දර්ශනය කර අවසන් වෙනවා. ඉන්පසු එය කෝල් කරපු CalleeFunc1 නම් ෆන්ක්ෂන් එකට ආපසු ක්‍රියාකාරිත්වය ලැබෙනවා. CalleeFunc1 තුල ෆන්ක්ෂන් කෝල් එකට පසු තවත් රන් වන්නට කෝඩිං නැති නිසා, CalleeFunc1 එකත් රන් කර අවසන් වෙනවා. එවිට, CalleeFunc1 එක කෝල් කරපු CallerFunction එකට ආපසු ක්‍රියාකාරිත්වය ලැබෙනවා. එහි ෆන්ක්ෂන් කෝල් එකට පසුව තවත් printf() කමාන්ඩ් එකක් රන් වෙන්නට තිබෙන නිසා, එයත් රන් වී එම ෆන්ක්ෂන් එකත් අවසන් වෙනවා. ඉන්පසු CallerFunction එක කෝල් කරපු main() එකට ක්‍රියාකාරිත්වය ලැබෙනවා. එහිත් අමුතුවෙන් තවත් රන් වන්නට කමාන්ඩ් නැති නිසා සම්පූර්ණ ප්‍රෝග්‍රෑම් එකම අවසාන වනවා.

ෆන්ක්ෂන් එකක () තුළ පැරාමීටර්ස් ලිවිය හැකි බව ඔබ දන්නවා. යම් ෆන්ක්ෂන් එකක පැරාමීටර්ස් තිබේ නම්, එම ෆන්ක්ෂන් එක කෝල් කරන මොහොතේදී ඊට සුදුසු දත්තයන් ලබා දිය යුතු බවද ඔබ දන්නවා. එවිට එම දත්තයන්ටද parameter කියා කිව හැකියි. උදාහරණයක් ලෙස, int func1(long a); යන ෆන්ක්ෂන් හෙඩර් එකේ long a ලෙස තිබෙන්නේ එම func1 යන ෆන්ක්ෂන් එකේ පැරාමීටරයනෙ. ඉතිං එම ෆන්ක්ෂන් එක පසුව කෝල් කරන විට, func1(15211); වැනි ආකාරයකට කළ හැකියිනෙ. long දත්ත වර්ගයට ගැලපෙන දත්තයක්නෙ 15211 කියන්නේ. මෙම 15211 යන්නටත් parameter කියා කියන බවයි මා ඉහතදී පවසුවේ.

එහෙත් මේ දෙකටම පැරාමීටර් කියා කිව්වත් ඒ දෙකේ වෙනස පෙන්වීමට අවශ්‍ය වෙනවා. එනිසා 15211 ලෙස ඇති (එනම් "නියම දත්තය" ලෙස ඇති) විට, ඊට actual parameter හෙවත් argument කියා කියනවා. ඒ කියන්නේ ෆන්ක්ෂන් එක කෝල් කරන විට ලබා දෙන දත්තය ඇක්චුවල් පැරාමීටර් හෙවත් ආර්ග්‍යුමන්ට් කියා කියනවා. ෆන්ක්ෂන් එක ඩිෆයින් කරන විට තිබෙන පැරාමීටරය formal parameter හෝ නිකංම පැරාමීටරය ලෙස හඳුන්වනවා.

අප දැන් main() ගැන විමසා බලමු. ඇත්තෙන්ම එයද ෆන්ක්ෂන් එකකි. එහි විශේෂත්ව කිහිපයක් තිබේ. එකක් නම්, මෙම ෆන්ක්ෂන් එකේ ෆන්ක්ෂන් නේම් එක හැමවිටම main ලෙස ලිවිය යුතුමයි. එහි රිටර්න් ටයිප් එක int වේ. එහෙත් අවශ්‍ය නම් එය void ලෙසත් ලිවිය හැකියි (එවිට වෝර්නිං එකකුත් ලැබේවි). අපට එරර් හෝ වෝර්නිං අවශ්‍ය නැති නිසා void නොදා int ලෙසම ලියන්නට පුරුදු වෙමු. සාමාන්‍යයෙන් අපට පුලුවන් පැරාමීටර්ස් නොලියා නිකංම () ලෙස තබන්න. මෙම විස්තරය අනුව ඔබට දැන් තේරෙනවා මේන් ෆන්ක්ෂන් එක පහත ආකාරයට තැබිය යුතුයි කියා.

int main()
{ }

මේන් ෆන්ක්ෂන් එක යනු සී ප්‍රෝග්‍රෑම් එකක අනිවාර්යෙන්ම තිබිය යුතු එකකි. එමනිසාමයි ඊට main යනුවෙන් නම් තබා තිබෙන්නෙත් (main යනු "ප්‍රධාන" යන තේරුම දෙන ඉංග්‍රීසි වචනයකි). මීට පෙරත් සඳහන් කළ ලෙසම, සෑම සී ප්‍රෝග්‍රෑම් එකක්ම රන් වන්නට පටන් ගන්නේ main ෆන්ක්ෂන් එකෙන්ය.

සාමාන්‍යයෙන් මේන් ෆන්ක්ෂන් එක අවසාන කරන්නේ return(0); හෝ return 0; යන කමාන්ඩ් එකෙනි. මේන් ෆන්ක්ෂන් එකේ හෙඩර් එකේ int රිටර්න් ටයිප් එක ලියන බව ඉහතදී පැවසුවා. ඉතිං මේන් ෆන්ක්ෂන් එක අවසානයේ int දත්ත වර්ගය ගැලපෙන අගයක් රිටර්න් කළ යුතුයි. ඔබට ඕන ඕන අගයක් මෙහි රිටර්න් නොකළ යුතුය. ප්‍රෝග්‍රෑම් එක සාර්ථකව රන් වී අවසන් වූ බව මෙහෙයුම් පද්ධතියට දන්වන්නේ මේන් ෆන්ක්ෂන් එක අවසන් වන විට 0 යන අගය රිටර්න් කිරීමෙනි. එහෙත් ඔබ මේන් එකේ රිටර්න් ටයිප් එක ලෙස void යෙදුවා නම්, මේන් එකේ අවසානයේ මෙවැනි return ස්ටේට්මන්ට් එකක් ලියන්නට බැහැ.

සටහන
ඔබේ ප්‍රෝග්‍රෑම් එක සාර්ථකව අවසන් වූවාද නැද්ද කියා ප්‍රෝග්‍රැමර් වශයෙන් ඔබ පමණක් නොව පරිගනකය මත සියලුම ප්‍රෝග්‍රෑම් රන් කරන මෙහෙයුම් පද්ධතියත් එය දැන ගත යුතුයි. ඉතිං මේන් ෆන්ක්ෂන් එකෙන් 0 අගය රිටර්න් වූ විට ඉන් සංඥා කරනවා මෙම ප්‍රෝග්‍රෑම් එක සාර්ථකව වැඩ නිම කළා කියා. සාමාන්‍යයෙන් මෙම return(0); ස්ටෙට්මන්ට් එක තිබෙන්නේ මේන් ෆන්ක්ෂන් එකේ අවසානයේය. ප්‍රෝග්‍රෑම් එක මෙම අවසාන ස්ටේට්මන්ට් එක දක්වා රන් වූවා යැයි කියන්නේම එය සාර්ථකව රන් වූවා කියන එකනෙ. මීට පෙර යම් තැනකදී ප්‍රශ්න මතු වූයේ නම්, මෙම අවසන් ස්ටේට්මන්ට් එක දක්වා ඊට රන් වීටම ඉඩ ලැබෙන්නේ නැහැනෙ. එනිසා ඇත්තටම මෙය හොඳ ක්‍රමයක් නේද ප්‍රෝග්‍රෑම් එක සාර්ථකව රන් වූවා කියා මෙහෙයුම් පද්ධතියට දන්වන?

දැන් ඔබට සී ප්‍රෝග්‍රෑම් එකක් සෑදීමට අවශ්‍ය මූලික දැනුම සියල්ල ලබා දී ඇත. සාමාන්‍යයෙන් සී ප්‍රෝග්‍රෑම් එකක් පහත පොදු ආකාරයෙන් (ෆෝමැට් එක) තමයි පවතින්නේ.

/* මෙම කොටසෙහි #include වැනි ඩිරෙක්ටිව්ස් ලියන්න */
#include <stdio.h>
#include < ……….>
………

/* මෙම කොටසෙහි අවශ්‍ය නම් ෆන්ක්ෂන් ප්‍රොටෝටයිප් ලියන්න */
int func1();
void func2();
………

/* මෙම කොටසෙහි අවශ්‍ය නම් වේරියබල් ආදිය ඩිෆයින් කරන්න */
long var1;
char var2;
………

/* මෙතැන මේන් ෆන්ක්ෂන් එක ඇත */
int main()
{
/* මේන් ෆන්ක්ෂන් එකේ අන්තර්ගතය */
.....…
return 0;
}

/* මෙම කොටසෙහි අවශ්‍ය නම් ෆන්ක්ෂන් ඩිෆයින් කරන්න */
int func1()
{
…..
}

void func2()
{
…..
}

/* ප්‍රෝග්‍රෑම් එකේ අවසානය */





c c++ programming (සී ප්‍රෝග්‍රැමිං)
Read More »

Thursday, June 9, 2016

c හා c++ ප්‍රෝග්‍රැමිං - 9

0

මී ළඟට අප ඉගෙන ගන්නට යන්නේ ප්‍රෝග්‍රැමිංවල ඉතාම වැදගත් මාතෘකාවක් වන ෆන්ක්ෂන් ගැනයි. ෆන්ක්ෂන් ගැන ඉගෙන ගත් පසුව සෑම සී ප්‍රෝග්‍රෑම් එකකම දක්නට ලැබෙන main() ගැනත් අපට හොඳින් වටහ ගත හැකියි. පළමුවෙන්ම පහත දැක්වෙන ප්‍රෝග්‍රෑම් එක රන් කර බලන්න. මෙම ප්‍රෝග්‍රෑම් එකේ එකම කෝඩිං කොටසක් 4 සැරයක් ලියා තිබෙනවා නේද?

/* C program without using functions */

#include <stdio.h>

int main()
     {

     int num1, num2;

     /* first run */
     printf("Enter 2 integers\n");
     scanf("%d\n%d",&num1,&num2);
     printf("The sum of 2 integers is: %d\n",num1+num2);
     /* second run */
     printf("Enter 2 integers\n");
     scanf("%d\n%d",&num1,&num2);
     printf("The sum of 2 integers is: %d\n",num1+num2);

     /* third run */
     printf("Enter 2 integers\n");
     scanf("%d\n%d",&num1,&num2);
     printf("The sum of 2 integers is: %d\n",num1+num2);

     /* fourth run */
     printf("Enter 2 integers\n");
     scanf("%d\n%d",&num1,&num2);
     printf("The sum of 2 integers is: %d\n",num1+num2);

     return 0;

     }

දැන් ඔබට අවශ්‍ය වුවොත් 4 සැරයක් වෙනුවට 100 සැරයක් හෝ 1000 එම කෝඩිං කොටස නැවත නැවත සැරයක් ලියන්නට? ඔබ සිතාවි කිසි ප්‍රශ්නයක් නැතිව එය කළ හැකියිනෙ කියා. එකම කෝඩිං කොටස තමන්ට අවශ්‍ය තරම් ටයිප් කළ හැකියි. එහෙමත් නැතිනම් copy-paste කළ හැකියි. එහෙත් මෙය ඊට වඩා කාර්යක්ෂම හා පහසුවෙන් කළ හැකි ආකාරයක්ද ප්‍රෝග්‍රැමිංවල තිබේ. ඒ තමයි ෆන්ක්ෂන් (function). ෆන්ක්ෂන් ගැන පැහැදිලි කිරීමට පෙර ඉහත ප්‍රෝග්‍රෑම් එකම ෆන්ක්ෂන් යොදා ගෙන සාදා ගන්නා අන්දම බලමු.

/* C program using functions */

#include <stdio.h>

/* function definition */
void AddNumbers()
     {
     int num1, num2;
     printf("Enter 2 integers\n");
     scanf("%d\n%d",&num1,&num2);
     printf("The sum of 2 integers is: %d\n",num1+num2);
     }

int main()
     {

     /* function calls 4 times */
     AddNumbers();
     AddNumbers();
     AddNumbers();
     AddNumbers();
     return 0;

     }

බැලූ බැල්මට එක් වෙනසක් පැහැදිලිවම පෙනේ. එනම්, ෆන්ක්ෂන් යොදා ගත් ප්‍රෝග්‍රෑම් එක අනෙකට වඩා කුඩා වේ. මෙම කුඩා බව සෝස්කෝඩ් එකේ පමණක් නොව, කම්පයිල් කළාට පසුව ලැබෙන බයිනරි ෆයිල් එකෙත් සිදු වේ. ෆන්ක්ෂන්වල ඇති ප්‍රධාන වාසියකි ප්‍රෝග්‍රෑම් කුඩාවීම. ඉහත උදාහරණවල නම් එකම කෝඩිං කොටස 4 සැරයක් පමණයි නැවත නැවත රන් වන්නේ. එහෙත් සියදහස් සැරයක් එය සිදුවන අවස්ථාවලදී ෆන්ක්ෂන් යොදා ගන්නා විට ඉන් ෆයිල් එක කුඩා වීම කැපී පෙනෙන ලෙසම සිදු වේ. තවද, ඉහත උදාහරණයේ නැවත නැවත රන් වන කෝඩිං කොටසේ තිබුණේ පේලි 3ක් (හෙවත් කමාන්ඩ් 3ක්) පමණි. එහෙත් ප්‍රායෝගිකව කමාන්ඩ් දුසිම් ගණනාවක් එලෙස නැවත නැවත රන් වන අවස්ථා තමයි හමු වන්නේ. ඒ කියන්නේ නැවත නැවත රන් වන කොටසේ ඇති කමාන්ඩ්/පේලි ගණන වැඩි වන තරමට, ෆන්ක්ෂන් යොදා ගැනීමේ වැදගත්කම තව තවත් ඉස් මතු වේ.

කුමක්ද ෆන්ක්ෂන් එකකින් ඇත්තටම සිදු වූයේ? නැවත නැවත රන් වන කෝඩිං කොටස වෙනම ගෙන, අප ඊට නමක් (ෆන්ක්ෂන් නේම් - function name) ලබා දෙනවා. ඉන්පසු ප්‍රෝග්‍රෑම් එකට එම කෝඩිං කොටස රන් කිරීමට අවශ්‍ය හැම අවස්ථාවකදීම ෆන්ක්ෂන් නේම් එක ලිවීම ප්‍රමාණවත් (සම්පූර්ණ කෝඩිං කොටසම නොලියා). බලන්න එය කොතරම් පහසුද කියා. නැවත නැවත රන් වන ප්‍රෝග්‍රැමිං කොටස වෙනම ගෙන ඊට නමක් ලබා දීම function definition (ෆන්ක්ෂන් එකක් සෑදීම) ලෙස හැඳින්වෙනවා.

ඉන්පසු එම ෆන්ක්ෂන් එක ක්‍රියාත්මක වීමට අවශ්‍ය තැන්වල එම ෆන්ක්ෂන් නේම් එක ලිවීම function calling (හෝ calling a function) හෙවත් function invoking/invocation ලෙස හැඳින්වෙනවා. ඇත්තටම සී හිදී ෆන්ක්ෂන් එකක් නිවැරදිව සාදා ගන්නා විදිය (ඒ කියන්නේ ෆන්ක්ෂන් එකක් ඩිෆයින් කරන අයුරු) ගැනත්, ෆන්ක්ෂන් එකක් කෝල් කරන විදිය ගැනත් දැනගත යුතු කරුණු කිහිපයක් ඇත. ඒ ගැන දැන් විමසා බලමු.

ඉහත උදාහරණයේ තිබූ ෆන්ක්ෂන් එක මා නැවත පහත ලියන්නම්. ෆන්ක්ෂන් එකක් කෝල් කරන විට රන් වන කෝඩිං කොටස (එනම් නැවත නැවත රන් වන කෝඩිං කොටස) { } යන සඟල වරහන් තුල ලිවිය යුතුය. එලෙස සඟල වරහන තුල ඇති කොටස function body (හෝ body of the function) කියා හැඳින්වෙනවා. ඇත්තටම ෆන්ක්ෂන් බොඩි එක තමයි ෆන්ක්ෂන් එකේ රාජකාරිය ඉටු කරන්නේ. පේලි දෙක තුනක කුඩා පේලි ගණනක සිට පේලි සියදහස් ගණනක් දක්වා විශාල ෆන්ක්ෂන් බොඩි දක්නට ලැබෙනවා.

void AddNumbers()
     {
     int num1, num2;
     printf("Enter 2 integers\n");
     scanf("%d\n%d",&num1,&num2);
     printf("The sum of 2 integers is: %d\n",num1+num2);
     }

ඇත්තටම සාමාන්‍යයෙන් ෆන්ක්ෂන් බොඩි එකක අච්චර පේලි ගණනක් (කමාන්ඩ් ගණනක්) තිබිය යුතුයි කියා නීතියක් නැත. එහෙත් එය අතිවිශාල නොවිය යුතුය. එක් පිටුවක් හෝ පිටු භාගයක් පිරෙන තරමට උපරිම පේලි ගණනක් තිබීම ඉතා හිතකරයි (හොඳ ප්‍රෝග්‍රැමිං පුරුද්දක්).
සාමාන්‍යයෙන් ෆන්ක්ෂන් බොඩි එක පිටු ගණන් පිරෙන තරමට විශාල වේ නම්, ඊට ප්‍රධාන හේතුව එක් ෆන්ක්ෂන් එකකින් විශාල රාජකාරි/කටයුතු ප්‍රමාණයක් සිදු කිරීමට උත්සහ කිරීමයි. එය හොඳ පුරුද්දක් නොවේ. එක් ෆන්ක්ෂන් එකකින් එක් රාජකාරියක් සිදු කරන්න. ඔබට ඕනෑ තරම් ෆන්ක්ෂන් ප්‍රමාණයක් ලිවිය හැකියි. ඉතිං එක් එක් රාජකාරියට වෙනම වෙනම ෆන්ක්ෂන් ලිවිය හැකියිනෙ.

තවද, එක් ෆන්ක්ෂන් එකක් තුළ රාජකාරි ගණනාවක් සිදු කර ගතහොත් ෆන්ක්ෂන්වල තිබෙන ප්‍රයෝජනවත් බවද අඩු විය හැකියි. "එක් රාජකාරියක් පමණක් කරන ෆන්ක්ෂන්" විශාල ප්‍රමාණයක් තිබීම "රාජකාරි කිහිපය බැගින් ඇතුලත් කොට ඇති ෆන්ක්ෂන්" කුඩා ප්‍රමාණයක් තිබීම යන අවස්ථා දෙකෙන් ඉතා ප්‍රයෝජනවත් වන්නේ පළමු අවස්ථාව වේ. දෙවැනි අවස්ථාව හරියට බස් කොන්දොස්තර කෙනෙකු ගාව මාරු කාසි නැතිව ලොකු මුදල් නෝට්ටු තිබෙනවා වාගේ වේවි. උදාහරණයක් ලෙස සිතමු ඔබ ගාව සාදා තිබෙනවා (ඩිෆයින් කර තිබෙනවා) යම් ෆන්ක්ෂන් එකක් ඉලක්කම් දෙකක් අඩු කිරීම හා එකතු කිරීම යන රාජකාරි දෙකම එකවර සිදු කරන. එවිට ඔබට එම ෆන්ක්ෂන් එක කෝල් කර එම ෆන්ක්ෂන් එකේ ක්‍රියාකාරිත්වය ලබා ගත හැකියි (එනම්, එකතු කිරීම හා අඩු කිරීම යන ක්‍රියාවන් දෙකම). එහෙත් දැන් ප්‍රෝග්‍රෑම් එකේ යම් අවස්ථාවක ඔබට අවශ්‍ය වුවොත් එකතු කිරීම පමණක් සිදු කිරීමට ඔබට එම ෆන්ක්ෂන් එක ප්‍රයෝජනයට ගන්නට බැහැ නේද මොකද ඉන් අඩු කිරීමත් සිදු කරන නිසා? එලෙසමයි ඔබට අඩු කිරීම පමණක් ක්‍රියාත්මක වීමට අවශ්‍ය තැන්වලදීත් එම ෆන්ක්ෂන් එක කෝල් කරන්නට බැහැ. එහෙත් ඔබ එම ෆන්ක්ෂන් එක වෙනුවට එකතු කිරීම පමණක් සිදු කරන හා අඩු කිරීම පමණක් සිදු කරන ෆන්ක්ෂන් දෙකක් ඩිෆයින් කළා නම්, අපට මේ සියලු අවස්ථාවලදී පහසුවෙනුත් කාර්යක්ෂම ලෙසත් එම ෆන්ක්ෂන් භාවිතා කළ හැකියි දැන්.

ෆන්ක්ෂන් බොඩි එක පටන් ගන්නා { ට පෙර ලියා තිබෙන කොටසත් ඉතාම වැදගත්. එම පේලියේ තමයි ෆන්ක්ෂන් නේම් (ෆන්ක්ෂන් එකේ නම) හා ඊට අදාල තවත් වැදගත් කොටස් කිහිපයක් තිබෙන්නේ. මෙම පේලිය function header කියා හැඳින්වෙනවා. ඉහත උදාහරණයේ void AddNumbers() ලෙස ඇත්තේ එම ෆන්ක්ෂන් එකේ හෙඩර් එකයි. හෙඩර් එක සෑදී තිබෙන්නේ කොටස් 3කින්ය.

එහි AddNumber වැනි ෆන්ක්ෂන් නේම් එකක් තිබෙනවා. ඔබට කැමති නමක් ලබා දිය හැකියි. මීට පෙර වේරියබල් නේම් ගැන කතා කරන විට මතකද identifier ගැනත් කතා කළා? ෆන්ක්ෂන් නේම් එකද අයිඩෙන්ටිෆයර් එකකි. එනිසා අයිඩෙන්ටිෆයර් සෑදීමේදී බලපාන රීති මීටත් වලංගු වේ. ෆන්ක්ෂන් නේම් එකක් ලිවීමේදී හොඳ පුරුදු (good programming practices) ඇත. කැමල් නොටේෂන් එක භාවිතා කරන්න; එහෙත් මෙහිදී සුලු වෙනසක් තිබෙනවා මොකද පළමු වචනයේ පළමු අකුරත් කැපිටල් කරනවා (සාමාන්‍යයෙන් පළමු වචනයේ පළමු අකුර කැමල් නොටේෂන්වලදී සිම්පල්වලින්නෙ තබන්නේ). තවද, ෆන්ක්ෂන් එකෙන් කරන රාජකාරිය පිළිබිඹු වන ආකාරයේ කෙටි නමක් ලබා දෙන්න. මෙහිදී ඉහත පැහැදිලි කළ ලෙසටම ෆන්ක්ෂන් එකෙන් කරන්නේ එක් රාජකාරියක් නම් මෙවැනි කෙටි නමක් ලබාදීම පහසු වේ; රාජකාරි කිහිපයක් කරන විට, ඉතා දිගු නම් ලිවීමට සිදු වේවි (රාජකාරි එකක් පමණක් සිදු කිරීමේ තවත් වාසියක් මෙය). ෆන්ක්ෂන් එකකින් යම් රාජකාරියක් සිදු කරන නිසා, ෆන්ක්ෂන් නේම් එක සාමාන්‍යයෙන් පටන් ගන්නේ ක්‍රියාපදයකිනි (එයත් ඉතා හොඳ පුරුද්දක් මිස රීතියක් නොවේ). ඉහත උදාහරණයේ AddNumbers යන්නෙහි Add යන ක්‍රියාපදයෙන් ආරම්භ වී තිබේ (මොකද මෙම ෆන්ක්ෂන් එකෙන් කරන්නේ සංඛ්‍යා දෙකක් එකතු කිරීම නිසා එම නම ඉතා උචිතය). ක්‍රියාපදය පමණක් මදි වගේ දැනෙනවා නම් ඊට පසුව නාමපදයක් ලිවිය හැකියි (Add ට පසුව Numbers යන්න මා ලියා ඇත ඉහත උදාහරණයේ).

ෆන්ක්ෂන් නේම් එකට ඉදිරියෙන් යම් කීවර්ඩ් එකක් ඇත. අප මීට පෙර ඉගෙන ගත් ඩේටා ටයිප් එකක් තමයි මෙහි ලියන්නේ. මෙම කොටස return type ලෙස හැඳින්වෙනවා. රිටර්න් ටයිප් එක ලෙස short, long, int, float, double, char, void වැනි කීවර්ඩ් ඔබ නිතරම දකිවී. අපේ උදාහරණයේ තිබෙන්නේ void යන්නයි. මෙම කොටසින් සිදු කරන්නේ කුමක්ද? සාමාන්‍යයෙන් දෙයාකාරයක ෆන්ක්ෂන් ඇත. එක් වර්ගයකදී ෆන්ක්ෂන් බොඩි එක තුළ යම් ක්‍රියාකාරිත්වයක් සිදු කර නිකංම ෆන්ක්ෂන් එක අවසන් වෙනවා. ඒ කියන්නේ ෆන්ක්ෂන් එකෙන් කිසිදු අගයක්/දත්තයක් පිට කරන්නේ නැහැ. දෙවැනි වර්ගයේදී අර කියූ විදියට යම් ක්‍රියාකාරිත්වයක් සිදු කර, අවසානයේදී යම් අගයක්/දත්තයක් පිට කරනවා. මේ පිට කරන දත්තය short, long, int, char, float, double ආදී ඩේටා ටයිප් එකකට අයත් විය යුතුය. කිසිදු දත්තයක් පිට කරන්නේ නැතිනම් void ලෙස ලිවිය යුතුය. ඉහතදී ගත් උදාහරණයේදී ෆන්ක්ෂන් එක තුල යම් රාජකාරියක් සිදු කළද අවසානයේ දත්තයක් පිට නොකරන නිසා void යන්න ලියා ඇත. පහත කෝඩිං බලන්න.

int AddNum(int num1, int num2)
    {
    int sum;
    sum = num1 + num2;
    return(sum);
    }

ඉහත ෆන්ක්ෂන් ඩෙෆිනිෂන් එකෙන් සිදු කරන්නේ ඊට පිටතින් ලබා දෙන සංඛ්‍යා දෙකක් එකතු කිරීමයි. එම එකතු කිරීම sum = num1 + num2; යන ස්ටේට්මන්ට් එකෙන් සිදු වෙන බව පේනවා. දැන් sum යන වේරියබල් එකේ තමයි එකතුව ගබඩා වී තිබෙන්නේ. එම දත්තය දැන් ෆන්ක්ෂන් එකේ අවසානයේදී ෆන්ක්ෂන් එකෙන් පිටතට ලබා දිය යුතුයි. එය සිදු කරන්නේ return() නම් කමාන්ඩ් එකෙන්. එම කමාන්ඩ් එකේ () යන වරහන් තුල තිබෙන්නේ පිටකළ යුතු දත්තයයි. මෙම උදාහරණයේ මෙලෙස පිට කරන්නේ int යන දත්ත වර්ගයක් නිසා (එනම් sum යනු int වර්ගයේ දත්තයකි) තමයි ෆන්ක්ෂන් හෙඩර් එකේ int AddNumber ලෙස ලියා තිබෙන්නේ. දැක්කද ෆන්ක්ෂන් හෙඩර් එක හා return ස්ටේට්මන්ට් එක අතර තිබෙන සම්බන්ධය? රිටර්න් කරන දත්තයේ දත්ත වර්ගයට ගැලපෙන දත්ත වර්ගය තමයි අනිවාර්යෙන්ම හෙඩර් එකේ රිටර්න් ටයිප් සඳහා ලියන්නේ. ඔබට අවශ්‍ය නම්, අමුතුවෙන් sum යන විචල්‍යයක් භාවිතා නොකර කෙලින්ම return(num1 + num2); කියාද ලිවිය හැකිව තිබුණා. එවිට එය පහත ආකාරයට ලිවිය යුතුයි.

int AddNum(int num1, int num2)
    {
    return(num1+num2);
    }

මෙහිදී return ස්ටේට්මන්ට් එක තුලම විචල්‍ය දෙක එකතු කිරීම සිදු කර, එහි ප්‍රතිපලය කෙලින්ම රිටර්න් කරනවා. ඇත්තටම යම් කමාන්ඩ් එකකට පසුව ඇති වරහන් තුල මෙලෙස කුඩා ගණනය කිරීම් සිදු කරන අවස්ථා නිතරම ප්‍රෝග්‍රැමිංවල හමු වෙනවා. මතක තබා ගන්න, මෙහිදී කුඩා ගණනය කිරීම් තමයි සාමාන්‍යයෙන් වරහන් තුළ සිදු කරන්නේ. ගණනය කිරීම විශාල නම්, පෙර කෝඩිං කොටසේදී මෙන්, එම ගණනය කිරීම වෙනමම සිදු කර, එහි ප්‍රතිපලය තවත් විචල්‍යයක ගබඩා කර, ඉන්පසු එම විචල්‍ය තමයි වරහන තුල ලියන්නේ. එලෙස සිදු කිරීම නිසා සෝස්කෝඩ් එක කියවා තේරුම් ගැනීමට පහසුව ලැබේ.

මේ අනුව, යම් ෆන්ක්ෂන් බොඩි එකක අවසානයට return() ස්ටේට්මන්ට් එකක් නැතිනම්, ඉන් අදහස් වන්නේ එම ෆන්ක්ෂන් එකෙන් යම් දත්තයක් පිටතට ලබා දෙන්නේ (රිටර්න් කරන්නේ) නැති බවයි. එවිට void යන කීවර්ඩ් එක ෆන්ක්ෂන් හෙඩර් එකේ තිබිය යුතුයි. සමහර ප්‍රෝග්‍රැමිං භාෂාවල නම්, මෙම දෙයාකාරයේ ෆන්ක්ෂන් සලකන්නේ වෙනස් වෙනස් ජාතියේ දෙකක් ලෙසයි. එහෙත් සීවලදී ඒ දෙවර්ගයම එකම ජාතියේ එකක් (එනම් ෆන්ක්ෂන් එකක්) ලෙස සලකනවා. මෙවිට ඒ දෙකෙහි වෙනස පෙන්වන්නේ පෙර ඉගෙන ගත් පරිදි void හෝ වෙනත් ඩේටා ටයිප් එකක් ලිවීමෙනි. සී වල ෆන්ක්ෂන් කියා ඉගෙන ගන්නා දේම වෙනත් භාෂාවලදී function, subroutine (sub), procedure, subprogram වැනි නම්වලින් හැඳින්විය හැකියි.

හෙඩර් එකේ ෆන්ක්ෂන් නේම් එකට පසුව වරහන් අනිවාර්යෙන්ම තිබිය යුතුය. සමහරවිට හිස් වරහන් තිබේවි (ඒ කියන්නේ වරහන් තුල කිසිවක් නොලියා නිකංම () ලෙස තිබේවි). තවත් අවස්ථාවල වරහන් තුල යම් යම් දේවල් තිබෙනු පෙනේවි. මෙම වරහන් කොටස parameter list (හෝ parameters) ලෙස හැඳින්වෙනවා. බොහෝ අවස්ථාවලදී ෆන්ක්ෂන් එක ක්‍රියාත්මක වීමේදී ඊට පිටතින් යම් යම් දත්ත එකක් හෝ කිහිපයක් ලබා දිය යුතුය. ෆන්ක්ෂන් එකක් කෝල් කරන කොට, එලෙස දත්ත ලබා දෙන ක්‍රමය තමයි මෙම පැරාමීටර් ලිස්ට් එක. ඉහත උදාහරණය නැවත බලමු.

int AddNum(int num1, int num2)
    {
    int sum;
    sum = num1 + num2;
    return(sum);
    }

මෙම ෆන්ක්ෂන් එකෙන් කරන්නේ සංඛ්‍යා දෙකක් එකතු කර එම එකතුව රිටර්න් කරන එකනෙ. ඉතිං එකතු කිරීමට දැන් සංඛ්‍යා දෙකක් (එනම් දත්ත දෙකක්) අවශ්‍යයි. එය ලබා ගත හැකි ආකාර කිහිපයක් තිබේ. ඉන් එක් ක්‍රමයක් තමයි පැරාමීටර් ලිස්ට් එක. මෙම AddNum යන ෆන්ක්ෂන් එක කෝල් කරන විට ඒ එක්කම මෙම සංඛ්‍යා/දත්ත දෙක ලබා දිය යුතුය (එය ලබා දෙන ආකාරය මොහොතකින් පෙන්වන්නම්). ෆන්ක්ෂන් කෝල් එක සිදු කරන මොහොතේ ලබා දුන් එම දත්ත ගබඩා කර ගන්නේ වරහන් තුල තිබෙන පැරාමීටර් ලිස්ට් එකේය. ඉහත උදාහරණයේදී අපට සංඛ්‍යා දෙකකුයි පිටතින් අවශ්‍ය වූයේ. ඉතිං එම සංඛ්‍යා දෙක දැන් පැරාමීටර් ලිස්ට් එකේ තිබෙනවා num1, num2 ලෙස. ඉන්පසු ඔබට පෙනෙන පරිදි එම අගයන් දෙක එකතු කර sum නම් තවත් විචල්‍යයකට ගබඩා කර අවසානයේ රිටර්න් කෙරෙනවා.

පැරාමීටර් ලිස්ට් එකේ තිබෙන්නේ parameters (පරාමිතීන්) වේ. පැරාමීටර් කිසිවක් නොමැති විට නිකංම () ලෙස තැබිය යුතුය. පැරාමීටර් තිබෙන විට, එම පැරාමීටර් සියල්ල () තුළ සටහන් කළ යුතුය. ඇත්තටම පැරාමීටර් එකක් යනු අමුතු දෙයක් නොවේ; පැරාමීටර් යනු වේරියබල් වේ. වේරියබල් එකකින් සිදු කරන්නේ යම් දත්තයක් ගබඩා කර තබා ගැනීමනෙ. පැරමීටරයකින් සිදු කරන්නේද එයයි. මෙහිදී පැරාමීටර් යනුවෙන් වෙනමම නමක් ලබා දී තිබෙන්නේ පහසුව තකාය මොකද පැරාමීටර් යන නම ඇසෙන විටම අපට තේරෙනවා මේ කතා කරන්නේ ෆන්ක්ෂන්වලදී වරහන් තුළ ඩෙක්ලෙයාර් කර ඇති වේරියබල් ගැන කියා. සාමාන්‍යයෙන් වේරියබල් එකක් ඩෙක්ලෙයාර් කරන විදියට (එනම්, "variable_type variable_name” ආකාරයට) වරහන තුළ ඒවා ලිවිය යුතුයි. පැරාමීටර් කිහිපයක් ඇති විට කොමා යොදා ඒවා ඉහත උදාහරණයේ පෙන්වා ඇති පරිදි ඩෙක්ලෙයාර් කරන්න. පහත දැක්වෙන්නේ විවිධාකාරයේ පැරාමීටර් සහිත ෆන්ක්ෂන් හෙඩර් කිහිපයකි.

int func1();
short fun2(int para1);
long func3(short para1, short p2);
void fn4(int abc, short p2, float fl1);

ෆන්ක්ෂන් බොඩි එක තුළදී පැරාමීටර් ලිස්ට් එකේ තිබූ පැරාමීටර්ස් (එනම් වේරියබල්) සාමාන්‍ය වේරියබල් මෙන්ම භාවිතා කළ හැකි බව ඉහතදී ඔබ දුටුවා. තවද, ෆන්ක්ෂන් එකේ රාජකාරිය සිදු කිරීමට ඊට අවශ්‍ය නම් තවත් වේරියබල්, ඔබට පුලුවන් සාමාන්‍ය පරිදිම අතිරේක වේරියබල් ෆන්ක්ෂන් බොඩි එක තුල ඩෙක්ලෙයාර් කරන්නට. ඉහත උදාහරණයේදී int sum; ලෙස අප කර ඇත්තේ එය තමයි.

දැන් අපි බලමු ෆන්ක්ෂන් එකක් කෝල් කරන විදිය. එය ඉතාම සරලයි. ෆන්ක්ෂන් එක කිසිදු පැරාමීටරයක් නොගන්නේ නම් (එනම් ෆන්ක්ෂන් නේම් එකට පසුව නිකංම () ලෙස පවතී නම්), ඔබට කරන්නට තිබෙන්නේ ෆන්ක්ෂන් නේම් එක හා () ලිවීම පමණයි. එහෙත්, යම් ෆන්ක්ෂන් එකක් පැරාමීටර් එකක් හෝ කිහිපයක් ලබා ගන්නේ නම්, ඔබ එම ෆන්ක්ෂන් එක කෝල් කරන විට, ෆන්ක්ෂන් නේම් එක ලියා වරහනක් තුළ පැරාමීටර් ගණනට සමාන දත්ත ලිවිය යුතුයි (දත්ත කිහිපයක් ඇති විට කොමා යොදා වෙන් කළ යුතුයි). පහත දැක්වෙන්නේ ඉහතදී දක්වපු එක් එක් ෆන්ක්ෂන් එකක් කෝල් කරන අයුරුය.

func1();
fun2(53);
func3(12, 42);
fn4(23, 12, 24.43);

ඉහත එක් එක් ෆන්ක්ෂන් කෝල් එක ගැන කෙටියෙන් බලමු. func1 යන්නෙහි කිසිදු දත්තයක් නැත. ඊට හේතුව එම ෆන්ක්ෂන් එක ඩිෆයින් කරපු (සාදන) මොහොතේ කිසිදු පැරාමීටරයක් නොගන්නා ලෙසයි එය සකස් කර තිබෙන්නේ. එනිසා කිසිම හේතුවක් නිසාවත් එම ෆන්ක්ෂන් කෝල් එකේ වරහන් තුළ කිසිදු දත්තයක් ලිවිය නොහැකියි. එනිසා func1(23); හෝ func2(5, 44.32); වැනි ආකාරයකට එය ලිවිය නොහැකියි. fun2 යන ෆන්ක්ෂන් එක කෝල් කරන විට, ඊට 53 යන දත්තයද ඒ සමගම ඇතුලු කෙරේ. ඊට හේතුව එම ෆන්ක්ෂන් එක ඩිෆයින් කරන මොහොතේ int වර්ගයේ දත්තයක් ලබා ගත හැකි ලෙස එය ඩිෆයින් කර තිබීමයි. එනිසා එම ෆන්ක්ෂන් කෝල් එක fun2(); හෝ fun2(234.22, 54); වැනි ආකාරයකට කිසිසේත් ලිවිය නොහැකියි. func3 යන ෆන්ක්ෂන් එක කෝල් කරන විට ඊට 12 හා 42 යන දත්ත දෙක ඇතුලු කර ඇත. එලෙසම අවසාන fn4 යන ෆන්ක්ෂන් කෝල් එකේදී 23, 12, 24.43 යන දත්ත 3ක් ඒ සමග ඇතුලු කරනු ඇත. ෆන්ක්ෂන් එක ඩිසයින් කර තිබෙන්නේ පළමුව int වර්ගයේද දෙවනුව short වර්ගයේද තෙවනුව float වර්ගයේද දත්ත වර්ග 3ක් ඇතුලු කළ යුතු ආකාරයටයි. ඉතිං එම ෆන්ක්ෂන් එක කෝල් කරන විට, ෆන්ක්ෂන් ඩෙෆිනිෂන් එකේ එම පැරාමීටර් තිබෙන අනුපිලිවෙලටම සුදුසු අගයන් ලිවිය යුතුයි ෆන්ක්ෂන් කෝල් එකේදී.

ෆන්ක්ෂන් කෝල් කරන විට තවත් කරුණක් වැදගත් වේ. එනම් කෝල් කරන ෆන්ක්ෂන් එකෙන් යම් දත්තයක් රිටර්න් කරනවාද නැද්ද යන්නයි. දැන් ඒ ගැන සොයා බලමු. උදාහරණයක් ලෙස පහත කොඩිං කොටස බලන්න. එහි කිසිදු දත්තයක් රිටර්න් කරන්නේ නැති බව ෆන්ක්ෂන් හෙඩර් එකේ void යන්න දුටු ගමන් ඔබට වැටහෙනවානෙ. ෆන්ක්ෂන් හෙඩර් එකේ void ලියා, ෆන්ක්ෂන් බොඩි එකේ අවසානයේ return කමාන්ඩ් එකක් යෙදීම තහනම් වන අතර, ෆන්ක්ෂන් හෙඩර් එකේ int, long ආදී දත්ත වර්ගයක් රිටර්න් වන බව කියා, ෆන්ක්ෂන් බොඩි එකේ ඊට ගැලපෙන return කමාන්ඩ් එකක් නොලියා සිටීමද තහනම්ය.

/* A simple function to write “hello world” */
void PrintHello()
{
printf(“Hello world\n”);
}

මෙම ෆන්ක්ෂන් එක ඉතාම සරලයි. ඉන් කරන එකම රාජකාරිය hello world කියා ස්ක්‍රීන් එකේ පෙන්වීම පමණි. කිසිදු අගයක් return කමාන්ඩ් එකක් යොදා පිටතට ලබා දෙන්නේ නැත. එනිසාම void යන කීවර්ඩ් එක යොදා තිබෙන අයුරු බලන්න. ඉහත ෆන්ක්ෂන් එක දැන් අපට ප්‍රෝග්‍රෑම් එකේ යම් තැනක සිට කෝල් කිරීමට අවශ්‍ය නම්, කරන්නට තිබෙන්නේ පහත ආකාරයට කමාන්ඩ් එක ලිවීම පමණි.

PrintHello();

පැරාමීටර්ස් නොගන්නා නිසා () යන්න තුල කිසිත් ලියන්නේ නැත. කිසිත් නැතැයි කියා () කොටස නොලියා සිටීමටද බැරිය. ඇත්තටම ඔබ මේ දක්වා උදාහරණවලදී යොදාගත් printf() යනුද ෆන්ක්ෂන් එකක් බව පෙර අවස්ථාවකදී මා පැවසුවා. printf() යනු තරමක් සංකීර්ණ ෆන්ක්ෂන් එකකි. එය ඔබ සාදපු එකක් නොව, කම්පයිලරය සමගම පැමිණෙන ෆන්ක්ෂන් එකකි (ඒ කියන්නේ කම්පයිලරය සාදපු අයමයි එය සාදා (ඩිෆයින් කර) තිබෙන්නේ). printf(“Hello World”); ආදී ලෙස ඔබ සාදපු ප්‍රෝග්‍රෑම්වල ලිව්වා නේද? ඇත්තෙන්ම එහිදී ඔබ කර තිබෙන්නේ printf යන ෆන්ක්ෂන් එක කෝල් කිරීම තමයි. එහිදී වරහන තුළ ඔබ ලියන්නේ පැරාමීටරයයි.

සටහන
ඉහත පැහැදිලි කළ විස්තරය ප්‍රායෝගිකව සිදු කර බැලීමට අවශ්‍ය නම්, එම ෆන්ක්ෂන් එකම සහිත පහත ප්‍රෝග්‍රෑම් එක රන් කර බැලිය හැකියි.

#include <stdio.h>

/* A simple function to write “hello world” */
void PrintHello()
    {

     printf("Hello World\n");

    }

int main()
     {
     PrintHello(); /* function call */
     return 0;
     }

ඉහත පෙන්නුවේ කිසිදු දත්තයක් රිටර්න් නොකරන ෆන්ක්ෂන් කෝල් කරන අයුරුය. යම් දත්තයක් රිටර්න් කරන ෆන්ක්ෂන් එකක් වුවද ඒ ආකාරයටම කෝල් කළ හැකියි. එනම්, ප්‍රෝග්‍රෑම් එකේ යම් තැනක ෆන්ක්ෂන් එකේ නම (හා පැරාමීටර්ස් තිබේ නම්, ඒවාද සමග) ලිවිය හැකියි. එහෙත් යම් දත්තයක් රිටර්න් කරන ෆන්ක්ෂන් සාමාන්‍යයෙන් කෝල් කරන්නේ එසේ නොවේ. උදාහරණයක් ලෙස පහත කෝඩිං බලන්න.

/* A simple function to multiply 2 numbers */
int MultiplyNumbers(int a, int b)
    {
    int result;
    result = a * b;
    return(result);
    }

මෙම ෆන්ක්ෂන් එක int වර්ගයේ දත්තයක් රිටර්න් කරයි. යම් ෆන්ක්ෂන් එකකින් යම් දත්තයක් රිටර්න් කරන්නේ ඇයි? එය අවශ්‍ය නිසානෙ. උදාහරණයක් ලෙස, ඉහත ෆන්ක්ෂන් එකෙන් ඊට ඇතුලු කරන ඕනෑම නිඛිල සංඛ්‍යා දෙකක ගුණිතය පිටතට ලබා දෙනවා. මෙම ෆන්ක්ෂන් එකේ රාජකාරිය එයයි. ඒ ෆන්ක්ෂන් එක කෝල් කළ විට එම රාජකාරිය සිදු කර, එහි ලැබෙන ප්‍රතිපලය තමයි ගුණිතය. උදාහරණයක් ලෙස, මෙම ෆන්ක්ෂන් එක කෝල් කරන විට ඔබ ඇතුලු කළේ 10 හා 20 යන සංඛ්‍යා දෙක නම්, ඒ දෙකේ ගුණිතය වන 200 ඉන් පිට කෙරේ. මෙම අගය සාමාන්‍යයෙන් ඔබ තවත් වේරියබල් එකක තමයි ගබඩා කර ගන්නේ. එනිසා වේරියබල් එකකට අගයක් ගබඩා කරන "ස්ටයිල් එක" තමයි මෙවිටත් යොදා ගන්නේ. එලෙස ෆන්ක්ෂන් කෝල් කරන අයුරු පහත දැක්වේ.

int result2;
result2 = MultiplyNumbers(20, 10);

ඉහත පේලි දෙක රන් වන්නේ මෙසේය. පළමුව result2 යන නමින් int වර්ගයේ වේරියබල් එකක් ඩික්ලෙයාර් කෙරේ. දෙවැනි පේලිය කොටස් දෙකක් ලෙස සලකා විස්තර කරන්නම්. එහි = ට දකුණුපස කොටස යනු ෆන්ක්ෂන් කෝල් එකයි. බලන්න ෆන්ක්ෂන් නේම් එක ලියා () තුල සුදුසු පැරාමීටර් දත්ත දෙක ලියා ඇත. එය කෝල් කරන විට, එම ෆන්ක්ෂන් එක ක්‍රියාත්මක වී එම ඇතුලු කරපු අගයන් දෙක එකිනෙකට ගුණ කර එම ගුණිතය රිටර්න් කරයි. මෙන්න මෙම අගය තමයි දැන් = ට වම්පස ඇති වේරියබල් එකේ ගබඩා වන්නේ. ඒ කියන්නේ result2 නම් වේරියබල් එකට නම්, = ට දකුණු පස පෙනෙන්නේ හරියට 200 වැනි අගයක් ලියා තිබෙනවා වගේය. ඇත්තටම එම වේරියබල් එකට වැඩක් නැහැ කොහොමද = ට දකුණු පස අගය ලැබෙන්නේ කියා. එයාට ගැලපෙන දත්තයක් කුමන හෝ ක්‍රමයකින් එතැනට ලැබෙනවා නම් එයාට වැදගත් එච්චරයි. මෙහිදී වැදගත් වන්නේ ෆන්ක්ෂන් එකේ රිටර්න් ඩේටා ටයිප් එක හා එය ගබඩා කරනා වේරියබල් එකේ ඩේටා ටයිප් එක සමාන වීමයි. (ඉහත උදාහරණයේ ෆන්ක්ෂන් එක රිටර්න් කරන්නේත් result2 නම් වේරියබල් එක ඩික්ලෙයාර් කර තිබෙන්නේත් int යන එකම වර්ගය බව පේනවා නේද?)

සටහන
ඉහත විස්තරය ප්‍රායෝගිකව කර බැලීමට පහත ප්‍රෝග්‍රෑම් එක කම්පයිල් කර රන් කර බලන්න. මෙම ප්‍රෝග්‍රෑම් එකේ ෆන්ක්ෂන් කෝලිං එක result2 = MultiplyNumbers(20, 10); වෙනුවට MultiplyNumbers(20, 10); ලෙස වෙනස් කර නැවත කම්පයිල් කර රන් කර බලන්න. ෆන්ක්ෂන් එක විසින් ගුණ කිරීම සිදු කළත්, එය කෝල් කරන විට, එය විසින් රිටර්න් කරපු දත්තය අප ලබා ගත්තේ නැත. එනිසා එහි ප්‍රතිපලය අපතේ ගොස් ඇති බව ඔබට තේරෙනවා නේද?

#include <stdio.h>

/* A simple function to multiply 2 numbers */
int MultiplyNumbers(int a, int b)
     {
     int result;
     result = a * b;
     return(result);
     }

int main()
     {
     int result2;
     result2 = MultiplyNumbers(20, 10);
     printf("the result2 has %d\n",result2); /* displays the result2 */
     return 0;
     }



සී ප්‍රෝග්‍රැමිං (C programming) ...
Read More »