ฟังก์ชัน

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

เมื่อคุณสร้างฟังก์ชันมันสามารถถูกเรียกใช้ได้จากทุกจุดของโปรแกรม บางครั้งขึ้นกับขอบเขตของมัน รูปแบบในการเขียนฟังก์ชันในภาษา 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 ด้วย และตัวที่สองจะต้องเป็น 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);

ในระหว่างการเล่นเกม ถ้าหากเลขที่ผู้เล่นเดานั้นไม่ถูกต้อง โปรแกรมจะทำการบอกใบ้ว่าตัวเลขที่ผู้เล่นเดานั้นมีค่าน้อยกว่าหรือมากกว่าตัวเลขลับ และจนกว่าผู้เล่นจะเดาได้ถูกต้อง โปรแกรมจะออกจาก 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