การเขียนฟังก์ชันเบื้องต้น
ตัวอย่างโปรแกรม
#include <iostream>
#include <vector>
using namespace std;
int main_old() {
double weight, height;
cout << "enter weight and height: ";
cin >> weight >> height;
double bmi = weight / (height * height);
cout << "BMI = " << bmi << endl;
vector<string> category{"Obese L4", "Obese L3", "Obese L2", "Obese L1", "Normal", "Low"};
double v[]{40, 35, 30, 25, 18.5, 0};
for (int i = 0; i < category.size(); ++i) {
if (bmi > v[i]) {
cout << "BMI category: " << category[i] << endl;
break;
}
}
return 0;
}
double bodyMassIndex(double weight, double height) {
return weight / (height * height);
}
string bmiCategory(double bmi) {
vector<string> category{"Obese L4", "Obese L3", "Obese L2", "Obese L1", "Normal", "Low"};
double v[]{40, 35, 30, 25, 18.5, 0};
for (int i = 0; i < category.size(); ++i) {
if (bmi > v[i]) {
return category[i];
}
}
}
int main() {
double weight, height;
cout << "enter weight and height: ";
cin >> weight >> height;
double bmi = bodyMassIndex(weight, height);
cout << "BMI = " << bmi << endl;
cout << "Category " << bmiCategory(bmi) << endl;
return 0;
}
========================================================================
ฟังก์ชัน
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
ด้วย และตัวที่สองจะต้องเป็น int
เช่นกันการส่งค่ากลับ 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
ว่าได้ทำการเดาไปแล้วกี่ครั้ง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);
###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
****************************************************************************************************************************************************************************************************
การทำงานของฟังก์ชันจะสิ้นสุดที่คำสั่ง return เสมอ คือ สมมติว่าฟังก์ชันเรามีคำสั่ง return หลายๆที่ ถ้าฟังก์ชันของเราพบคำสั่ง return ที่ไหนมันจะทำการการ return ค่าแล้วออกจากฟังก์ชันทันที เช่น
****************************************************************************************************************************************************************************************************
เราสามารถแบ่งฟังก์ชันใน C++ ได้เป็น 2 ประเภทได้แก่
1. ฟังก์ชันที่อยู่ใน standard library ของ C++ เราจะเรียกฟังก์ชันพวกนี้ว่า built-in function
2. ฟังก์ชันที่เราสร้างขึ้นมาเพื่อที่จะใช้งานเอง เราจะเรียกฟังก์ชันพวกนี้ว่า user defined function
สำหรับพวก built-in function นั้นเราสามารถเรียกใช้ได้โดยการ import library ที่มีฟังก์ชันนั้นๆเขามาในโปรแกรมของเรา ตัวอย่างเช่น ถ้าเราต้องการใช้ฟังก์ชันทางคณิตศาสตร์ เช่นพวก sin, cos, tan, exponential, log ซึ่งฟังก์ชันเหล่านี้อยู่ใน library ที่ชื่อว่า cmath ใน C++ เราสามารถเขียนคำสั่งได้ดังตัวอย่างนี้
สำหรับฟังก์ชันทางคณิตศาสตร์ทั้งหมดที่อยู่ใน C++ เราสามารถดูได้ที่ http://www.cplusplus.com/reference/clibrary/cmath/
ส่วนฟังก์ชันประเภท user defined function มีโครงสร้างการเขียนแบบนี้ครับ
ชนิดข้อมูลของข้อมูลที่ต้องการ return ชื่อฟังก์ชัน (ตัวแปร input)
{
ชุดคำสั่งต่างๆภายในฟังก์ชัน
}
เช่นสมมติว่าเราต้องการสร้างฟังก์ชันที่ เมื่อใส่ตัวเลขลงไปจะให้ผลลัพธ์เป็นกำลังสองของตัวเลขที่เราจะใส่ไป เราสามารถเขียนโค้ดได้ดังนี้
การทำงานของฟังก์ชันจะสิ้นสุดที่คำสั่ง return เสมอ คือ สมมติว่าฟังก์ชันเรามีคำสั่ง return หลายๆที่ ถ้าฟังก์ชันของเราพบคำสั่ง return ที่ไหนมันจะทำการการ return ค่าแล้วออกจากฟังก์ชันทันที เช่น
ขอให้สังเกตว่าเมื่อเราใส่เลข 12 ลงไป มันจะเข้าเงื่อนไขของ if แล้วก็จะเจอคำสั่ง return 10; พอเจอคำสั่ง return ปุ๊บ มันจะทำการ return ค่า พร้อมออกจากฟังก์ชันทันที
ตัวแปรที่ต่างๆที่อยู่ในฟังก์ชัน เป็น local varible นะครับ ไม่สามารถเรียกใช้ภายในฟังก์ชันได้ ถ้าเราใช้ตัวแปรในฟังก์ชันซ้ำกับตัวแปรภายนอกฟังก์ชัน ก็ไม่มีผลกระทบใดๆต่อตัวแปรภายนอกฟังก์ชันทั้งสิ้น เช่น
สังเกตนะครับว่า การเปลี่ยนแปลงของค่า x ภายในฟังก์ชัน square ไม่ส่งผลใดๆกับตัวแปร x ที่อยู่ภายนอกฟังก์ชันทั้งสิ้น
ทีนี้สมมติว่าเราต้องการให้การเปลี่ยนแปลงมีผลกับตัวแปร x ภายนอกด้วย ใน C++ ก็อนุญาตให้เราทำได้ด้วยครับ โดยการใส่เครื่องหมาย & หน้าตัวแปรที่เราต้องการให้มีผล เช่น ถ้าเราเปลี่ยนแปลงบรรทัดที่ 5 เป็นดังนี้
ทีนี้ในบางครั้งเราอาจจะต้องการสร้างฟังก์ชันซึ่งมีลักษณะที่ว่า เมื่อฟังก์ชันจบการทำงานแล้ว ไม่ต้องให้มัน return ค่าใดๆกลับมา เราสามารถทำได้โดยการเขียนคำว่า void นำหน้าฟังก์ชันดังตัวอย่างต่อไปนี้ครับ
ต่อไปจะเป็นตัวอย่างสุดท้ายของ blog นี้นะครับ สมมติว่าเราต้องการสร้างฟังก์ชันเพื่อทำการสลับค่าตัวแปร 2 ตัว สมมติว่าเราเขียนโค้ดแบบนี้
เมื่อทำการรันเราจะเห็นว่า a และ b มันสลับค่าเฉพาะในฟังก์ชันเท่านั้นดังรูป
ถ้าเราต้องการให้มันสลับที่กันภายนอกด้วยเราจะเปลี่ยนแปลงบรรทัดที่ 5 ดังนี้
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++