ฟังก์ชัน

ฟังก์ชันเป็นส่วนหรือกลุ่มของคำสั่งเพื่อทำงานบางอย่าง แนวคิดของฟังก์ชันคือการรวบรวมโค้ดที่ใช้บ่อยๆ และซ้ำๆ กลับมาใช้ใหม่

เมื่อคุณสร้างฟังก์ชันมันสามารถถูกเรียกใช้ได้จากทุกจุดของโปรแกรม บางครั้งขึ้นกับขอบเขตของมัน รูปแบบในการเขียนฟังก์ชันในภาษา C++ คือ:

type name ( parameter1, parameter2, ... ) {
statements
}

- type เป็นประเภทของฟังก์ชันสำหรับการส่งค่ากลับ ประเภทของฟังก์ชันนั้นจะเป็นเหมือนประเภทของตัวแปร เช่น integer, floating, double หรือแบบอ็อบเจ็ค ประเภทแบบ voidหมายความว่าฟังก์ชันไม่มีค่าที่ต้องส่งกลับ

- name นั้นเป็นชื่อของฟังก์ชันที่เราสร้างขึ้น มันมีวิธีการตั้งคือโดยการใช้กฏแบบเดียวกันกับการตั้งชื่อตัวแปร มันสามารถประกอบไปด้วยตัวอักษร ตัวเลข และ underscore (_) แต่ไม่สามารถเริ่มต้นด้วยตัวเลข

- Parameters เป็นเซ็ตของตัวแปรที่ถูกส่งเข้ามายังฟังก์ชัน ฟังก์ชันสามารถมีหรือไม่มีพารามีเตอร์ก็ได้ ขึ้นกับวัตถุประสงค์ของมัน

- Statement คือโค้ดของโปรแกรมที่จะทำงานและให้ค่าผลลัพธ์ของฟังก์ชัน

การประกาศฟังก์ชัน

เพื่อประกาศฟังก์ชันในภาษา C++ คุณจำเป็นต้องทำตามรูปแบบของมัน มาดูตัวอย่าง

#include <iostream>
using namespace std;

int sum (int x, int y)
{
int z = x + y;
return z;
}

int main ()
{
int a = 3;
int b = 5;
cout << "a + b = " << sum(a, b);
return 0;
}

ในตัวอย่าง เราได้สร้างฟังก์ชันเพื่อหาผลรวมของตัวแปร 2 ตัว โดยประเภทของฟังก์ชันนั้นจะเป็น int นั่นหมายความว่าฟังก์ชันจะส่งค่ากลับเป็นข้อมูลแบบ integer และชื่อของฟังก์ชันคือ sum และมีพารามิเตอร์สองตัว ดังนั้น เราสามารถเรียกใช้ฟังก์ชัน โดยการใช้ชื่อของมัน และส่งพารามิเตอร์ไปเหมือนที่เราได้ประกาศในฟังก์ชัน เมื่อฟังก์ชันถูกเรียกใช้ มันจะประมวลผลคำสั่งในฟังก์ชัน และจะใช้คำสั่ง return เพื่อส่งค่ากลับมายังจุดเรียกฟังก์ชัน

ในโปรแกรมของเรา จะต้องได้ 8 เป็นค่าส่งกลับ ข้างล่างนี้เป็นผลลัพธ์ของโปรแกรม

a + b = 8

Function parameters

เหมือนที่กล่าวไว้ก่อนหน้า ฟังก์ชันพารามิเตอร์เป็นเซ็ตของตัวแปรหรืออ็อบเจ็คที่ส่งไปยังฟังก์ชัน ประเภทของพารามิเตอร์นั้นเป็นตัวแปรหรือออบเจ็ค และฟังก์ชันสามารถมีหรือไม่มีพารามิเตอร์ก็ได้ มาดูตัวอย่างของการใช้ฟังก์ชันพารามิเตอร์

// Function without parameter
float getPI ()
{
return 3.14;
}

// Function with three parameters
int findVolume(float width, float long, float height)
{
float volume = width * long * height;
return volume;
}

// Function with difference parameter types
void printData(string name, int age)
{
cout << "Hi, " << name << endl;
cout << "Your age is " << age << endl;
}

ในตัวอย่าง เป็นการประกาศฟังก์ชันพร้อมกับพารามิเตอร์ของมัน โดยฟังก์ชัน getPI () เป็นฟังก์ชันที่ไม่มีพารามิเตอร์ ฟังก์ชัน findVolume() เป็นฟังก์ชันที่มีพารามิเตอร์สามตัว และฟังก์ชัน printData() เป็นฟังก์ชันที่มีพารามิเตอร์สองตัว ฟังก์ชันเหล่านี้สามารถมีหรือไม่มีการส่งค่ากลับก็ได้ (return)

Function arguments

ฟังก์ชันอาร์กิวเมนต์คือเซ็ตของตัวแปรที่ส่งไปยังฟังก์ชัน อาร์กิวเมนต์จะต้องตรงกันกับฟังก์ชันพารามิเตอร์และเรียงไปตามลำดับที่ได้ประกาศไว้ มาดูสามตัวอย่างเกี่ยวกับฟังก์ชันอากิวเม้นต์

printData("Marcus", 14);

ฟังก์ชัน printData มีสองพารามิเตอร์ และประเภทอาร์กิวเมนต์ของมันคือ string และ int ตามลำดับ ในการที่จะส่งอาร์กิวเมนต์ไปยังฟังก์ชัน อาร์กิวเมนต์ตัวแรกจะต้องเป็น string ด้วย และตัวที่สองจะต้องเป็น integer เช่นกัน

การส่งค่ากลับ return

การส่งค่ากลับจะใช้คำสั่ง return มันเป็นผลลัพธ์ของฟังก์ชันเพื่อที่จะส่งกลับไปยังจุดเรียกเมื่อสิ้นสุดการทำงานของฟังก์ชัน ประเภทตัวแปรที่ส่งกลับจะต้องตรงกันกับประเภทของฟังก์ชัน และบางฟังก์ชันอาจจะไม่มีการส่งค่ากลับ ซึ่งเป็นฟังก์ชันที่มีการกำหนดประเภทการใช้งานเป็น void

หลังจากที่คุณได้เข้าใจในส่วนประกอบของฟังก์ชันแล้ว ต่อไปมาดูตัวอย่างการใช้ฟังก์ชันในการเขียนโปรแกรมในภาษา C++ เราจะเขียนเกมเดาตัวเลขลับ โดยในโปรแกรมของเราจะใช้ฟังก์ชันประเภทต่างๆ นีเป็นโค้ดของโปรแกรม

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

void welcomeText();
void puts(string);
int getGuessNumber();

int main () {

//initialize random seed:
srand(time(NULL));

bool is_gameover = false;
int guess, secret;
int guessed = 0;

// display welcome text
welcomeText();

// generate secret number:
secret = rand() % 10 + 1;
puts("Secret number has been chosen");

do {

guess = getGuessNumber();
guessed++;
if (secret < guess)
puts("The secret number is lower");
else if(secret > guess)
puts("The secret number is higher");

} while (secret != guess);

puts("Congratulations!");
cout << "The secret number is " << secret << endl;
cout << "You made " << guessed << " guess";
cout << (guessed != 1 ? "es" : "") << endl;

return 0;
}

void puts(string str) {
cout << str << endl;
}

void welcomeText() {
puts("###Welcome to guessing number game###");
}

int getGuessNumber() {
int guess;
cout << "Guess the number (1 to 10): ";
cin >> guess;
return guess;
}

ในตัวอย่าง เป็นโปรแกรมของเกมเดาตัวเลข ผู้เล่นต้องทำการสุ่มตัวเลขให้ถูกต้องโดยให้ได้จำนวนครั้งที่น้อยที่สุด ในตอนแรกโปรแกรมจะทำการสุ่มตัวเลขลับไว้ในตัวแปร secret และเราเรียกใช้ฟังก์ชัน welcomeText() สำหรับแสดงข้อความต้อนรับ และในฟังก์ชันนี้ได้เรียกใช้ฟังก์ชัน puts() สำหรับส่งข้อความไปแสดงผลอีกครั้ง

guess = getGuessNumber();
guessed++;

ในคำสั่ง do-while loop เป็นส่วนของการเล่นเกมได้เริ่มต้นขึ้น โดยเกมจะถามตัวเลขที่ผู้เล่นต้องการเดาที่มีค่าระหว่าง 1 - 10 โดยเราจะเรียกใช้ฟังก์ชัน getGuessNumber() สำหรับบอกผู้ใช้และส่งค่าเลขที่ผู้เล่นเดากลับมายังตัวแปร guess ทุกๆ ครั้งที่มีการเดาตัวเลขแล้ว เราเพิ่มค่าตัวแปร guessed ว่าได้ทำการเดาไปแล้วกี่ครั้ง

...
if (secret < guess)
puts("The secret number is lower");
else if(secret > guess)
puts("The secret number is higher");
} while (secret != guess);

ในระหว่างการเล่นเกม ถ้าหากเลขที่ผู้เล่นเดานั้นไม่ถูกต้อง โปรแกรมจะทำการบอกใบ้ว่าตัวเลขที่ผู้เล่นเดานั้นมีค่าน้อยกว่าหรือมากกว่าตัวเลขลับ และจนกว่าผู้เล่นจะเดาได้ถูกต้อง โปรแกรมจะออกจาก do-while loop และแสดงข้อความยินดีกับผู้เล่น และบอกตัวเลขลับและจำนวนท้งหมดที่ผู้เล่นได้ทำการเดาจนกว่าจะถูก และเกมของเราได้จบลง

###Welcome to guessing number game###
Secret number has been chosen
Guess the number (1 to 10): 5
The secret number is lower
Guess the number (1 to 10): 2
The secret number is higher
Guess the number (1 to 10): 4
The secret number is lower
Guess the number (1 to 10): 3
Congratulations!
The secret number is 3
You made 4 guesses

นี่เป็นผลลัพธ์การทำงานของโปรแกรม โดยเราได้เล่นเกมและทำตามการเดาตัวเลข 5, 2, 4 และ 3 ตามลำดับ ซึ่งเดาไป 4 ครั้ง

จากในตัวอย่างของโปรแกรมเดาตัวเลข คุณจะเห็นว่าเราได้ใช้ฟังก์ชันในรูปแบบต่างๆ และมีสิ่งหนึ่งที่คุณสามารถสังเกตุได้ในการประกาศฟังก์ชันคือ เราได้ทำการประกาศส่วนหัวของฟังก์ชันทั้งหมดไว้ก่อนฟังก์ชัน main() ซึ่งในการทำแบบนี้เป็นอีกทางเลือก และเป็นวิธีปฏิบัติที่ดีที่จะบอกให้คอมไพเลอร์ทราบว่าเรามีฟังก์ชันอะไรบ้าง

void welcomeText();
void puts(string);
int getGuessNumber();

และหากคุณไม่ประกาศส่วนหัวของฟังก์ชันแบบนี้ ในภาษา C++ นั้นคุณจะไม่สามารถคอมไพล์โปรแกรมของคุณได้ และในตัวอย่างเราได้ใช้ฟังก์ชันเพื่อสร้าง random seed จากเวลาในคำสั่ง srand(time(NULL)) เพื่อทำให้โปรแกรมของเราสุ่มเลขได้ดีที่สุด

Passing by reference and Passing by value

ในตัวอย่างทั้งหมดที่คุณได้เรียนไปในบทนี้นั้นเป็นการใช้งานฟังก์ชันโดยวิธี Passing by value นี่จะทำให้โปรแกรมต้องคัดลอกค่าใหม่ที่ใช้ในฟังก์ชัน ในภาษา C++ มีวิธีการเรียกใช้งานฟังก์ชันอีกแบบหนึ่งที่เรียกว่า Passing by reference สิ่งที่แตกต่างจากแบบเดิมคือเราจะส่งที่อยู่หน่วยความจำของตัวแปรไปแทน เรามักจะใช้วิธีนี้กับข้อมูลที่มีขนาดมากๆ ที่ต้องส่งไปยังฟังก์ชัน เช่น อาเรย์ หรือโปรแกรมที่ต้องการประสิทธิภาพมาก มาดูตัวอย่างของข้อแตกต่างระหว่าง Passing by reference และ Passing by value ในภาษา C++

#include <iostream>

using namespace std;

void swapByVal(int, int);
void swapByRef(int&, int&);

int main () {

int x = 1, y = 5;

cout << "Passing by value" << endl;
cout << "Before swap: x = " << x << ", y = " << y << endl;
swapByVal(x, y);
cout << "After swap: x = " << x << ", y = " << y << endl;

cout << "Passing by reference" << endl;
cout << "Before swap: x = " << x << ", y = " << y << endl;
swapByRef(x, y);
cout << "After swap: x = " << x << ", y = " << y << endl;

return 0;
}

void swapByVal(int a, int b) {
int temp = a;
a = b;
b = temp;
}

void swapByRef(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}

ในตัวอย่าง เป็นโปรแกรมในการสลับตัวเลข ซึ่งเราได้สร้างฟังก์ชันมาสองเวอร์ชันคือ ฟังก์ชัน swapByVal() เป็นฟังก์ชันที่มีพารามิเตอร์เป็นแบบ Passing by value และฟังก์ชัน swapByRef() เป็นฟังก์ชันที่มีพารามิเตอร์เป็นแบบ Passing by reference และเราทำการทดสอบเรียกใช้งานฟังก์ชันทั้งสอง

void swapByRef(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}

ในการส่งพารามิเตอร์แบบ Passing by reference นั้นเราจะต้องประกาศพารามิเตอร์ในฟังก์ชันโดย ใส่เครื่องหมาย & ที่หน้าของตัวแปร เมื่อคุณส่งค่ามายังฟังก์ชัน ตัวแปรในฟังก์ชันจะใช้ที่อยู่กับตัวแปรที่อยู่นอกฟังก์ชัน นั่นทำให้เมื่อตัวแปร a และ b ในฟังก์ชันเปลี่ยนเป็นอะไรก็ตาม ตัวแปร x และ y ก็จะเปลี่ยนเป็นค่าเหมือนกัน เพราะว่าพวกเขามีที่อยู่ของหน่วยความจำร่วมกัน

Passing by value
Before swap: x = 1, y = 5
After swap: x = 1, y = 5
Passing by reference
Before swap: x = 1, y = 5
After swap: x = 5, y = 1

นี่เป็นผลลัพธ์การทำงานของโปรแกรมในการส่งพารามิเตอร์แบบ Passing by reference เข้าไปยังฟังก์ชัน

ในการใช้งานวิธินี้มันมีประสิทธิภาพมากเพราะว่าช่วยลดเวลาในการคัดลอกข้อมูลในฟังก์ชันออกไปทำให้โปรแกรมทำงานได้เร็วมากขึ้น แต่อย่างไรก็ตามในการใช้วิธี Passing by reference นั้นก็ขึ้นกับปัญหาของคุณ ไม่ทุกโปรแกรมที่จะสามารถใช้มันได้เสมอ ยกตัวอย่างเช่น ถ้าหากคุณต้องการรักษาค่าเดิมของตัวแปร x และ y ในฟังก์ชัน main() คุณก็ไม่ควรใช้วิธีนี้

แนวคิด Passing by reference ยังถูกนำไปใช้กับการเขียนโปรแกรมเชิงวัตถุในภาษาต่างๆ นั่นคือเมื่อคุณส่งออบเจ็คไปยังฟังก์ชันนั้นจะเป็นการส่งที่อยู่ของออบเจ็คไปแทน อย่างไรก็ตามในบทนี้เราไม่ได้ครอบคลุมในเรื่องนี้

ในบทนี้ คุณได้ทำความรู้จักและเรียนรู้วิธีการสร้างและใช้งานฟังก์ชันในภาษา C++ เราได้แนะนำให้คุณรู้จักกับฟังก์ชันประเภทต่างๆ และรู้จักพารามิเตอร์และอากิวเมนต์ของฟังก์ชัน ฟังก์ชันที่มีการส่งค่าและไม่มีการส่งค่ากลับ นอกจากนี้คุณยังเข้าใจในการเรียกใช้ฟังก์ชันแบบ Passing by reference