มาโครในภาษา C (Macros in C)
ภาพรวม
มาโครในการเขียนโปรแกรม C เรียกว่าชิ้นส่วนของโค้ดที่กำหนดโดยใช้คำสั่ง #define มาโครในภาษาซีมีประโยชน์มากในหลาย ๆ ที่เพื่อแทนที่โค้ดด้วยค่ามาโครเพียงค่าเดียว มาโครมีหลายประเภทและมีมาโครที่กำหนดไว้ล่วงหน้าด้วยเช่นกัน
ขอบเขตของบทความ
- บทความนี้จะช่วยให้คุณเข้าใจแนวคิดพื้นฐานของมาโครพร้อมตัวอย่างต่างๆ
- คุณจะได้รู้จักกับการทำงานของพรีโปรเซสเซอร์และการใช้คำสั่ง #define
- บทความนี้จะแนะนำคุณเกี่ยวกับมาโครประเภทต่างๆ ที่โปรแกรมเมอร์ใช้
- บทความนี้ประกอบด้วยรายการมาโครที่กำหนดไว้ล่วงหน้าในภาษา C พร้อมตัวอย่างและคำอธิบาย
ความรู้เบื้องต้นเกี่ยวกับมาโครในภาษาซี
สมมติว่าเรากำลังทำงานกับแอปพลิเคชันในภาษา C และมีค่าหนึ่งค่าหรือวัตถุหรือส่วนของรหัสที่เราต้องการหลายครั้งในรหัสของเรา จากนั้นด้วยความช่วยเหลือของมาโคร เราสามารถกำหนดครั้งเดียวและใช้งานได้หลายครั้ง
มาโครเป็นวิธีที่สะดวกในการเขียนโค้ดที่มีประสิทธิภาพและสามารถปรับขนาดได้
ในบทความนี้ เราจะมาศึกษาการใช้มาโครในภาษาซี ประเภทต่าง ๆ และกรณีการใช้งาน
Macros ในภาษา C คืออะไร?
มาโครในภาษาซีเรียกว่าชิ้นส่วนของโค้ดซึ่งสามารถแทนที่ด้วยค่ามาโครได้ มาโครถูกกำหนดด้วยความช่วยเหลือของ #define คำสั่งตัวประมวลผลล่วงหน้าและมาโครไม่ได้ลงท้ายด้วยเครื่องหมายอัฒภาค (;) มาโครเป็นเพียงชื่อที่กำหนดให้กับค่าหรือนิพจน์บางอย่าง ซึ่งไม่ได้ชี้ไปยังตำแหน่งหน่วยความจำใดๆ
เมื่อใดก็ตามที่คอมไพเลอร์พบมาโคร คอมไพเลอร์จะแทนที่ชื่อมาโครด้วยค่ามาโคร มาโครสองตัวไม่สามารถมีชื่อเดียวกันได้
ไวยากรณ์ของมาโครดังแสดงในรูปต่อไปนี้ ที่นี่เราจะมีสามองค์ประกอบ:
- #define – คำสั่งพรีโปรเซสเซอร์
- PI – ชื่อมาโคร
- 3.14 – ค่ามาโคร

เราจะเจาะลึกลงไปว่าคำสั่งของตัวประมวลผลล่วงหน้าคืออะไรในตอนหลังของบทความนี้ แต่ก่อนอื่น เรามาทำความเข้าใจมาโครด้วยความช่วยเหลือของโค้ดตัวอย่างกันก่อน
โค้ด:
#include <stdio.h>
// This is macro definition
#define PI 3.14
int main()
{
// declaration and initialization of radius
int radius = 5;
// declaration and calculating the area
float area = PI * (radius * radius);
// Printing the area of circle
printf("Area of circle is %f", area);
return 0;
}

ในตัวอย่างโค้ดข้างต้น เราเขียนโปรแกรมเพื่อคำนวณพื้นที่ของวงกลมโดยใช้รัศมีที่กำหนด
เรากำหนดค่าคงที่ PI เป็นมาโครที่มีค่า 3.14
ที่นี่ชื่อมาโคร PI ที่บรรทัดที่ 11 ถูกแทนที่ด้วยค่ามาโคร 3.14 ตามที่เราเห็นในคำจำกัดความ และเราได้พื้นที่ของวงกลมเป็นผลลัพธ์
ตอนนี้ การแทนที่ค่านี้เกิดขึ้นเนื่องจากตัวประมวลผลล่วงหน้าและคำสั่งตัวประมวลผลล่วงหน้า #define
Preprocessor และ Preprocessor Directive ในการเขียนโปรแกรม C คืออะไร?
เมื่อใดก็ตามที่เราเขียนโค้ดในภาษา C มันจะต้องผ่านกระบวนการคอมไพล์ ซึ่งจะถูกแปลงจากซอร์สโค้ดเป็นโค้ดที่เครื่องเข้าใจได้
แต่ก่อนกระบวนการคอมไพล์ ซอร์สโค้ดจะต้องผ่านการประมวลผลล่วงหน้า ซึ่งทำโดยตัวประมวลผลล่วงหน้า

ดังภาพด้านบนแสดงการตรวจสอบตัวประมวล ผลล่วงหน้าสำหรับ preprocessing directives การประมวลผลล่วงหน้า ในโปรแกรม C
หากพบคำสั่งในการประมวลผลล่วงหน้า ตัวประมวลผลล่วงหน้าจะดำเนินการบางอย่างกับคำสั่งเหล่านั้น
พรีโปรเซสเซอร์ มีหลายประเภท เช่น #define , #if , #error และ #warning เป็นต้น ซึ่งทั้งหมดเริ่มต้นด้วยสัญลักษณ์ #
ในการกำหนดมาโคร เราใช้ คำสั่ง #define preprocessing ซึ่งดำเนินการเพื่อแทนที่ชื่อมาโครด้วยค่ามาโคร ณ เวลาที่ทำการประมวลผลล่วงหน้า
มาดูกันว่ามาโครประเภทต่างๆ ในภาษา C มีอะไรบ้าง
ประเภทของมาโครในภาษาซี
มาโครในภาษา C ถูกจัดประเภทตามค่าประเภทต่างๆ ที่จะมาแทนที่
มาดูมาโครประเภทต่างๆ กันทีละตัว
Object like Macros in C
object like macros ในการเขียนโปรแกรม C เป็นเพียงมาโครที่ถูกแทนที่ด้วยค่าหรือส่วนของรหัสบางอย่าง
ในตัวอย่างข้างต้น ในบทนำ เราเห็นมาโครที่มีชื่อ PI และค่า 3.14 ซึ่งเป็นตัวอย่างของ object like macros
เราสามารถกำหนดมาโครด้วยประเภทข้อมูลที่แตกต่างกันดังแสดงดังต่อไปนี้ แต่เราไม่สามารถใช้ชื่อมาโครเดียวกันสำหรับค่าที่แตกต่างกันสองค่า –
// Examples of object like macros in C language
#define MAX 100
#define MIN 1
#define GRAVITY 9.8
#define NAME "Lungmaker"
#define TRUE 1
#define FALSE 0
Function Like Macros in C
ในฟังก์ชันเช่นมาโครจะคล้ายกับฟังก์ชันจริงในการเขียนโปรแกรม C
เราสามารถส่งอาร์กิวเมนต์ด้วยชื่อมาโครและดำเนินการในส่วนโค้ดได้
ในมาโคร ไม่มีการตรวจสอบประเภทอาร์กิวเมนต์ ดังนั้นเราจึงสามารถใช้เป็นข้อได้เปรียบในการส่งผ่านประเภทข้อมูลที่แตกต่างกันในมาโครเดียวกันในภาษา C
ลองพิจารณาตัวอย่างโค้ดต่อไปนี้ ซึ่งเป็นการแก้ไขโค้ดก่อนหน้า –
โค้ด:
#include <stdio.h>
// object like macro
#define PI 3.14
// function like macro
#define Area(r) (PI * (r * r))
int main()
{
// declaration and initialization of radius
float radius = 2.5;
// declaring and assigning the value to area
float area = Area(radius);
// Printing the area of circle
printf("Area of circle is %f\n", area);
// Using radius as int data type
int radiusInt = 5;
printf("Area of circle is %f", Area(radiusInt));
return 0;
}

ดูในโค้ดด้านบน เราได้เพิ่มมาโครที่เหมือนฟังก์ชันที่บรรทัดที่ 5.
ชื่อมาโครคือ Area ซึ่งรับอาร์กิวเมนต์ r เป็นรัศมีที่เราส่งผ่านไปยังบรรทัดที่ 13 และสายที่ 20.
ในช่วงเวลาของการประมวลผลล่วงหน้า ค่า Area(radius) จะถูกแทนที่ด้วยค่ามาโครที่ประมวลผลแล้ว และถูกกำหนดให้กับตัวแปรพื้นที่
ที่บรรทัดที่ 13 เราผ่านค่ารัศมีเป็นทุ่นและที่บรรทัดที่ 20 เราผ่านค่าของรัศมีเป็น float ของชนิดจำนวนเต็ม ดังนั้นมาโครจึงทำให้เราได้เปรียบในการใช้มาโครเดียวกันสำหรับประเภทข้อมูลที่แตกต่างกัน เนื่องจากไม่มีการตรวจสอบประเภทของอาร์กิวเมนต์
Chain Like Macros in C
เมื่อเราใช้มาโครตัวหนึ่งภายในมาโครอีกตัวหนึ่ง จะเรียกว่ามาโครแบบลูกโซ่
เราได้เห็นตัวอย่างของมาโครแบบลูกโซ่แล้วในตัวอย่างโค้ดด้านบนที่เราใช้ PI ในพื้นที่ มาคุยกันหน่อยดีกว่า –
#define PI 3.14
#define Area(r) (PI*(r*r))
ในข้อมูลโค้ดด้านบนนี้ เราจะเห็นได้ว่าเราใช้อ็อบเจกต์ เช่น มาโคร PI ภายในฟังก์ชัน เช่น พื้นที่มาโคร
ที่นี่มาโครหลักแรกได้รับการขยายเช่นพื้นที่มาโครที่ใช้งานได้จากนั้นมาโครลูกจะถูกขยายเช่น PI วิธีนี้เมื่อเราใช้มาโครตัวหนึ่งภายในมาโครอีกตัวหนึ่ง จะเรียกว่ามาโครลูกโซ่
ประเภทของมาโครใน Nutshell:
Sr. No. | Macro Name | Description |
---|---|---|
1 | Object Like | ค่าหรือส่วนรหัสถูกแทนที่ด้วยชื่อมาโคร |
2 | Function Like | มาโครที่รับอาร์กิวเมนต์และทำหน้าที่เป็นฟังก์ชัน |
3 | Chain Like | มาโครภายในมาโครอื่น |
จนถึงตอนนี้ เราได้เห็นวิธีการกำหนดมาโคร ประเภท และวิธีใช้มาโครแล้ว แต่มาโครบางตัวมาพร้อมกับภาษา C และเราสามารถใช้โดยตรงในโปรแกรม C
มาโครที่กำหนดไว้ล่วงหน้าในภาษาซี
มีมาโครที่กำหนดไว้ล่วงหน้าใน C ที่เราสามารถใช้โดยตรงในโปรแกรมและไม่สามารถแก้ไขได้
เราสามารถทำงานต่างๆ ได้มากมายด้วยมาโครที่กำหนดไว้ล่วงหน้า ซึ่งไม่สามารถทำได้ในการเขียนโปรแกรม C ปกติ
มาโครเหล่านี้มีดังนี้:
มาโครที่กำหนดไว้ล่วงหน้าและคุณสมบัติ:
Sr. No. | Macro | Feature |
---|---|---|
1 | __LINE__ Macro | ประกอบด้วยหมายเลขบรรทัดปัจจุบันที่ใช้มาโครนี้ |
2 | __FILE__ Macro | ประกอบด้วยชื่อไฟล์ที่มีโปรแกรมปัจจุบันอยู่ |
3 | __DATE__ Macro | ประกอบด้วยวันที่ปัจจุบันในรูปแบบ MMM DD YYYY |
4 | __TIME__ Macro | มีเวลาปัจจุบันในรูปแบบ. HH:MM |
5 | __STDC__ Macro | ถูกกำหนดเป็น 1 เมื่อมีการคอมไพล์สำเร็จ |
มาดูการทำงานของมาโครที่กำหนดไว้ล่วงหน้าเหล่านี้โดยใช้ตัวอย่างการเข้ารหัส
โค้ด:
int main()
{
// Example of predefined macros
printf("This is line no.: %d\n", __LINE__); // 7
printf("Name of this file: %s\n", __FILE__); // macros.c
printf("Current Date: %s\n", __DATE__); // Jan 10 2022
printf("Current Time: %s\n", __TIME__); // 12:17:35
printf("Compilation success: %d\n", __STDC__); // 1
return 0;
}

บทสรุป
- มาโครคือชิ้นส่วนของรหัสหรือค่าที่ถูกแทนที่ด้วยชื่อมาโครก่อนการทำงานของโปรแกรม
- ตัวประมวลผลล่วงหน้าดำเนินการต่างๆ กับคำสั่งตัวประมวลผลล่วงหน้า และสำหรับคำจำกัดความของมาโคร เราใช้คำสั่ง #define ตัวประมวลผลล่วงหน้า
- การทำงานของ #define คือการแทนที่เนื้อความแมโครด้วยค่ามาโคร ณ เวลาที่ทำการประมวลผลล่วงหน้า
- เป็นความคิดที่ดีที่จะใช้มาโครในโค้ดตามความต้องการและใช้มาโครประเภทต่างๆ
- มาโครที่กำหนดไว้ล่วงหน้าสามารถทำได้หลายอย่าง ซึ่งไม่สามารถทำได้ในการเขียนโปรแกรม C ปกติ
credit : https://www.scaler.com/topics/c/