ตัวชี้ฟังก์ชั่นในการเขียนโปรแกรม C พร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

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

  • 🔗 ประกาศ: ตัวชี้ฟังก์ชันใช้รูปแบบ return_type (*name)(arguments); วงเล็บรอบชื่อนั้นจำเป็นต้องมี
  • 🔄 แลกเปลี่ยนตามที่อยู่: การส่งที่อยู่ของตัวแปรไปยังพารามิเตอร์แบบพอยเตอร์ทำให้ฟังก์ชันสามารถเปลี่ยนแปลงค่าเริ่มต้นของผู้เรียกได้ ดังเช่นในตัวอย่างการสลับค่า
  • 📦 อาร์เรย์: ชื่อของอาร์เรย์เป็นตัวชี้อยู่แล้ว ดังนั้นฟังก์ชันจึงสามารถรับอาร์เรย์หรือส่งคืนตัวชี้ไปยังอาร์เรย์แบบคงที่ได้
  • 🎛️ ตารางการจัดส่ง: อาร์เรย์ของตัวชี้ฟังก์ชันจะแทนที่การใช้คำสั่ง switch หรือ if ที่ยาวๆ โดยการเข้าถึงการดำเนินการที่เลือกโดยตรงผ่านดัชนี
  • 🧊 ตัวชี้ว่างเปล่า: พารามิเตอร์หรือประเภทการส่งคืนแบบ void * ยอมรับประเภทใดก็ได้ ซึ่งฟังก์ชันจะแปลงกลับเป็นประเภทนั้นก่อนใช้งาน
  • 📞 โทรกลับ: การส่งพอยเตอร์ฟังก์ชันเป็นอาร์กิวเมนต์ช่วยให้สามารถใช้งานฟังก์ชันเรียกกลับ (callback) ได้ เช่น ฟังก์ชันเปรียบเทียบ qsort
  • 🤖 ความช่วยเหลือจากเอไอ: GitHub Copilot และผู้ช่วย AI จะสร้างโครงร่างไวยากรณ์ตัวชี้ฟังก์ชัน, typedefs และลายเซ็นการเรียกกลับ จากนั้นจะแจ้งเตือนเมื่อพารามิเตอร์ไม่ตรงกัน

ตัวชี้ฟังก์ชันในภาษาซี

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

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

ตัวอย่างพอยน์เตอร์ฟังก์ชัน

ตัวอย่างเช่น โปรแกรมถัดไปจะสลับค่าสองค่าจากสองค่า:

void swap (int *a, int *b);
int main() {
  int m = 25;
  int n = 100;
  printf("m is %d, n is %d\n", m, n);
  swap(&m, &n);
  printf("m is %d, n is %d\n", m, n);
  return 0;}
void swap (int *a, int *b) {
  int temp;
  temp = *a;
  *a = *b;
  *b = temp;}
}

Output:

m is 25, n is 100
m is 100, n is 25

ตัวอย่างพอยน์เตอร์ฟังก์ชัน

โปรแกรมจะสลับค่าตัวแปรจริงเนื่องจากฟังก์ชันเข้าถึงโดยใช้ที่อยู่ ตัวชี้- ที่นี่เราจะหารือเกี่ยวกับกระบวนการของโปรแกรม:

  1. เราประกาศฟังก์ชันที่รับผิดชอบในการแลกเปลี่ยนping ฟังก์ชันนี้รับพอยเตอร์จำนวนเต็มสองตัวเป็นพารามิเตอร์ และส่งคืนค่าใดๆ ก็ได้เมื่อถูกเรียกใช้
  2. ในฟังก์ชันหลัก เราประกาศและเริ่มต้นตัวแปรจำนวนเต็มสองตัว ('m' และ 'n') จากนั้นเราจะพิมพ์ค่าตามลำดับ
  3. เราเรียกฟังก์ชัน swap() โดยส่งที่อยู่ของตัวแปรทั้งสองเป็นอาร์กิวเมนต์โดยใช้สัญลักษณ์แอมเพอร์แซนด์ หลังจากนั้น เราจะพิมพ์ค่าที่สลับใหม่ของตัวแปร
  4. ที่นี่เราจะกำหนดเนื้อหาของฟังก์ชัน swap() ซึ่งรับที่อยู่ตัวแปรจำนวนเต็มสองตัวเป็นพารามิเตอร์ และประกาศตัวแปรจำนวนเต็มชั่วคราวที่ใช้เป็นกล่องจัดเก็บข้อมูลที่สามเพื่อบันทึกตัวแปรค่าตัวหนึ่งที่จะใส่ไว้ในตัวแปรที่สอง
  5. บันทึกเนื้อหาของตัวแปรแรกที่ชี้โดย 'a' ในตัวแปรชั่วคราว
  6. เก็บตัวแปรตัวที่สองที่ชี้โดย b ไว้ในตัวแปรตัวแรกที่ชี้โดย a
  7. อัพเดตตัวแปรตัวที่สอง (ชี้โดย b) ด้วยค่าของตัวแปรตัวแรกที่บันทึกไว้ในตัวแปรชั่วคราว

ฟังก์ชั่นที่มีพารามิเตอร์อาร์เรย์

ในภาษา C เราไม่สามารถส่งอาร์เรย์ตามค่าไปยังฟังก์ชันได้ ในขณะที่ชื่ออาร์เรย์คือตัวชี้ (ที่อยู่) ดังนั้นเราจึงส่งชื่ออาร์เรย์ไปยังฟังก์ชันซึ่งหมายถึงการส่งผ่านตัวชี้ไปยังอาร์เรย์

ตัวอย่างเช่น เราพิจารณาโปรแกรมต่อไปนี้:

int add_array (int *a, int num_elements);
int main() {
  int Tab[5] = {100, 220, 37, 16, 98};
  printf("Total summation is %d\n", add_array(Tab, 5)); 
  return 0;}
int add_array (int *p, int size) {
  int total = 0;
  int k;
  for (k = 0; k < size; k++) {
    total += p[k];  /* it is equivalent to total +=*p ;p++; */}
 return (total);}

Output:

 Total summation is 471

ที่นี่เราจะอธิบายโค้ดโปรแกรมพร้อมรายละเอียด

ฟังก์ชั่นที่มีพารามิเตอร์อาร์เรย์

  1. เราประกาศและกำหนดฟังก์ชัน add_array() ซึ่งรับที่อยู่อาร์เรย์ (ตัวชี้) พร้อมด้วยหมายเลของค์ประกอบเป็นพารามิเตอร์ และส่งคืนผลรวมสะสมขององค์ประกอบเหล่านี้ ตัวชี้ใช้เพื่อวนซ้ำองค์ประกอบอาร์เรย์ (โดยใช้สัญลักษณ์ p[k]) และเราสะสมผลรวมในตัวแปรท้องถิ่นซึ่งจะถูกส่งกลับหลังจากการวนซ้ำอาร์เรย์องค์ประกอบทั้งหมด
  2. เราประกาศและเริ่มต้นอาร์เรย์จำนวนเต็มด้วยองค์ประกอบจำนวนเต็มห้าองค์ประกอบ เราพิมพ์ผลรวมทั้งหมดโดยส่งชื่ออาร์เรย์ (ซึ่งทำหน้าที่เป็นที่อยู่) และขนาดอาร์เรย์ไปที่ add_array()เรียกว่าฟังก์ชันเป็นอาร์กิวเมนต์

ฟังก์ชั่นที่ส่งกลับอาร์เรย์

ใน C เราสามารถส่งคืนตัวชี้ไปยังอาร์เรย์ได้ เช่นเดียวกับในโปรแกรมต่อไปนี้:

#include <stdio.h>
int * build_array();
int main() {
  int *a;
  a = build_array(); /* get first 5 even numbers */
  for (k = 0; k < 5; k++)
    printf("%d\n", a[k]);
  return 0;}
int * build_array() {
  static int Tab[5]={1,2,3,4,5};
   return (Tab);}

Output:

1
2
3
4
5

และที่นี่เราจะมาพูดถึงรายละเอียดของโปรแกรม

ฟังก์ชั่นที่ส่งกลับอาร์เรย์

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

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

ตัวชี้ฟังก์ชัน

ดังที่เราทราบตามคำจำกัดความว่าตัวชี้ชี้ไปยังที่อยู่ในตำแหน่งหน่วยความจำใดๆ ตัวชี้ยังสามารถชี้ไปที่จุดเริ่มต้นของโค้ดที่ปฏิบัติการได้เป็นฟังก์ชันในหน่วยความจำ
ตัวชี้ไปยังฟังก์ชันถูกประกาศด้วย * คำสั่งทั่วไปของการประกาศคือ:

return_type (*function_name)(arguments)

คุณต้องจำไว้ว่าวงเล็บรอบๆ (*function_name) มีความสำคัญ เพราะหากไม่มีวงเล็บ คอมไพลเลอร์จะคิดว่า function_name กำลังส่งคืนพอยน์เตอร์เป็น return_type
หลังจากกำหนดฟังก์ชันพอยน์เตอร์แล้ว เราต้องกำหนดค่าให้กับฟังก์ชัน ตัวอย่างเช่น โปรแกรมถัดไปจะประกาศฟังก์ชันทั่วไป กำหนดฟังก์ชันพอยน์เตอร์ กำหนดฟังก์ชันพอยน์เตอร์ให้กับฟังก์ชันทั่วไป จากนั้นจึงเรียกใช้ฟังก์ชันผ่านพอยน์เตอร์:

#include <stdio.h>
void Hi_function (int times); /* function */
int main() {
  void (*function_ptr)(int);  /* function pointer Declaration */
  function_ptr = Hi_function;  /* pointer assignment */
  function_ptr (3);  /* function call */
 return 0;}
void Hi_function (int times) {
  int k;
  for (k = 0; k < times; k++) printf("Hi\n");}

Output:

Hi
Hi
Hi

ฟังก์ชันพอยน์เตอร์ในภาษาซี

  1. เรากำหนดและประกาศฟังก์ชันมาตรฐานซึ่งจะพิมพ์ข้อความ Hi k ครั้งที่ระบุโดยพารามิเตอร์ครั้งเมื่อมีการเรียกใช้ฟังก์ชัน
  2. เรากำหนดฟังก์ชันตัวชี้ (พร้อมการประกาศพิเศษ) ซึ่งรับพารามิเตอร์จำนวนเต็มและไม่ส่งคืนอะไรเลย
  3. เราเริ่มต้นฟังก์ชันตัวชี้ของเราด้วย Hi_function ซึ่งหมายความว่าตัวชี้ชี้ไปที่ Hi_function()
  4. แทนที่จะใช้การเรียกฟังก์ชันมาตรฐานโดย taping ชื่อฟังก์ชันพร้อมอาร์กิวเมนต์ เราเรียกใช้ฟังก์ชันตัวชี้โดยส่งเลข 3 เป็นอาร์กิวเมนต์ แค่นั้นเอง!

โปรดทราบว่าชื่อฟังก์ชันชี้ไปยังที่อยู่เริ่มต้นของโค้ดที่ปฏิบัติการได้ เช่น ชื่ออาร์เรย์ที่ชี้ไปยังองค์ประกอบแรก ดังนั้นคำสั่งเช่น function_ptr = &Hi_function และ (*funptr)(3) จึงถูกต้อง
หมายเหตุ: ไม่จำเป็นต้องแทรกตัวดำเนินการที่อยู่ & และตัวดำเนินการทางอ้อม * ในระหว่างการกำหนดฟังก์ชันและการเรียกใช้ฟังก์ชัน

อาร์เรย์ของพอยน์เตอร์ฟังก์ชัน

อาร์เรย์ของพอยน์เตอร์ฟังก์ชันสามารถมีบทบาทเป็นสวิตช์หรือคำสั่ง if ในการตัดสินใจได้ ดังเช่นในโปรแกรมถัดไป:

#include <stdio.h>
int sum(int num1, int num2);
int sub(int num1, int num2);
int mult(int num1, int num2);
int div(int num1, int num2);

int main() 
{  int x, y, choice, result;
  int (*ope[4])(int, int);
  ope[0] = sum;
  ope[1] = sub;
  ope[2] = mult;
  ope[3] = div;
  printf("Enter two integer numbers: ");
  scanf("%d%d", &x, &y);
  printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");
  scanf("%d", &choice);
  result = ope[choice](x, y);
  printf("%d", result);
return 0;}

int sum(int x, int y) {return(x + y);}
int sub(int x, int y) {return(x - y);}
int mult(int x, int y) {return(x * y);}
int div(int x, int y) {if (y != 0) return (x / y); else  return 0;}
Enter two integer numbers: 13 48
Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: 2
624

เราจะมาพูดถึงรายละเอียดของโปรแกรมกันดังนี้:

อาร์เรย์ของพอยน์เตอร์ฟังก์ชัน

  1. เราประกาศและกำหนดสี่ ฟังก์ชั่น ซึ่งรับอาร์กิวเมนต์จำนวนเต็มสองตัวและส่งคืนค่าจำนวนเต็ม ฟังก์ชันเหล่านี้ได้แก่ add และ subtract, คูณและหารค่าอาร์กิวเมนต์ทั้งสองค่าที่เกี่ยวข้องกับฟังก์ชันที่ผู้ใช้เรียกใช้
  2. เราประกาศจำนวนเต็ม 4 ตัวเพื่อจัดการกับตัวดำเนินการ ประเภทการดำเนินการ และผลลัพธ์ตามลำดับ นอกจากนี้ เรายังประกาศอาร์เรย์ของตัวชี้ฟังก์ชัน XNUMX ตัว ตัวชี้ฟังก์ชันแต่ละตัวขององค์ประกอบอาร์เรย์จะรับพารามิเตอร์จำนวนเต็ม XNUMX ตัวและส่งคืนค่าจำนวนเต็ม
  3. เรากำหนดและกำหนดค่าเริ่มต้นให้กับแต่ละองค์ประกอบของอาร์เรย์ด้วยฟังก์ชันที่ประกาศไว้แล้ว ตัวอย่างเช่น องค์ประกอบที่สามซึ่งเป็นฟังก์ชันตัวชี้ที่สามจะชี้ไปที่ฟังก์ชันการดำเนินการคูณ
  4. เราค้นหาตัวดำเนินการและประเภทการดำเนินการจากผู้ใช้ที่พิมพ์ด้วยแป้นพิมพ์
  5. เราเรียกองค์ประกอบอาร์เรย์ที่เหมาะสม (ตัวชี้ฟังก์ชัน) พร้อมอาร์กิวเมนต์ และเราเก็บผลลัพธ์ที่สร้างโดยฟังก์ชันที่เหมาะสม

คำสั่ง int (*ope[4])(int, int); กำหนดอาร์เรย์ของพอยน์เตอร์ฟังก์ชัน องค์ประกอบอาร์เรย์แต่ละรายการจะต้องมีพารามิเตอร์และประเภทการส่งคืนเหมือนกัน
ผลลัพธ์ของคำสั่ง = ope[choice](x, y); รันฟังก์ชันที่เหมาะสมตามตัวเลือกที่ผู้ใช้เลือก จำนวนเต็มสองตัวที่ป้อนคืออาร์กิวเมนต์ที่ส่งผ่านไปยังฟังก์ชัน

ฟังก์ชั่นการใช้ตัวชี้โมฆะ

พอยน์เตอร์เป็นโมฆะถูกใช้ในระหว่างการประกาศฟังก์ชัน เราใช้ใบอนุญาตประเภทการคืนสินค้าเป็นโมฆะ * เพื่อคืนประเภทใดก็ได้ หากเราถือว่าพารามิเตอร์ของเราไม่เปลี่ยนแปลงเมื่อส่งผ่านไปยังฟังก์ชัน เราจะประกาศให้เป็น const
ตัวอย่างเช่น:

 void * cube (const void *);

พิจารณาโปรแกรมต่อไปนี้:

#include <stdio.h>
void* cube (const void* num);
int main() {
  int x, cube_int;
  x = 4;
  cube_int = cube (&x);
  printf("%d cubed is %d\n", x, cube_int);
  return 0;}

void* cube (const void *num) {
  int result;
  result = (*(int *)num) * (*(int *)num) * (*(int *)num);
  return result;}

ผลลัพธ์:

 4 cubed is 64

ที่นี่เราจะหารือรายละเอียดของโปรแกรม:

ฟังก์ชั่นการใช้ตัวชี้โมฆะ

  1. เรากำหนดและประกาศฟังก์ชันที่ส่งคืนค่าจำนวนเต็มและรับที่อยู่ของตัวแปรที่ไม่สามารถเปลี่ยนแปลงได้โดยไม่มีประเภทข้อมูลเฉพาะ เราคำนวณค่าคิวบ์ของตัวแปรเนื้อหา (x) ชี้โดยตัวชี้ num และเนื่องจากเป็นตัวชี้เป็นโมฆะ เราจึงต้องพิมพ์เป็นชนิดข้อมูลจำนวนเต็มโดยใช้สัญกรณ์เฉพาะ (* ประเภทข้อมูล) แล้วเราจะส่งคืน ค่าคิวบ์
  2. เราประกาศตัวดำเนินการและตัวแปรผลลัพธ์ และกำหนดค่าเริ่มต้นตัวดำเนินการด้วยค่า “4”
  3. เราเรียกใช้ฟังก์ชันลูกบาศก์โดยส่งที่อยู่ตัวดำเนินการ และเราจัดการค่าที่ส่งกลับในตัวแปรผลลัพธ์

ตัวชี้ฟังก์ชันเป็นอาร์กิวเมนต์

อีกวิธีในการใช้ประโยชน์จากตัวชี้ฟังก์ชันโดยส่งผ่านเป็นอาร์กิวเมนต์ไปยังฟังก์ชันอื่นซึ่งบางครั้งเรียกว่า "ฟังก์ชันเรียกกลับ" เนื่องจากฟังก์ชันรับ "เรียกกลับ"
ในไฟล์ส่วนหัว stdlib.h ฟังก์ชัน Quicksort “qsort()” ใช้เทคนิคนี้ซึ่งเป็นอัลกอริธึมที่ใช้เพื่อจัดเรียงอาร์เรย์โดยเฉพาะ

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
  • void *base : โมฆะตัวชี้ไปยังอาร์เรย์
  • size_t num : หมายเลของค์ประกอบอาร์เรย์
  • ความกว้าง size_t ขนาดองค์ประกอบ
  • int (*compare (const void *, const void *) : ตัวชี้ฟังก์ชันประกอบด้วยสองอาร์กิวเมนต์และส่งคืนค่า 0 เมื่ออาร์กิวเมนต์มีค่าเท่ากัน <0 เมื่อ arg1 มาก่อน arg2 และ >0 เมื่อ arg1 มาก่อน arg2

โปรแกรมต่อไปนี้จะเรียงลำดับอาร์เรย์จำนวนเต็มจากตัวเลขน้อยไปหามากโดยใช้ฟังก์ชัน qsort():

#include <stdio.h>
#include <stdlib.h>
int compare (const void *, const void *); 
int main() {
  int arr[5] = {52, 14, 50, 48, 13};
  int num, width, i;
  num = sizeof(arr)/sizeof(arr[0]);
  width = sizeof(arr[0]);
  qsort((void *)arr, num, width, compare);
  for (i = 0; i < 5; i++)
    printf("%d ", arr[ i ]);
  return 0;}
int compare (const void *elem1, const void *elem2) {
  if ((*(int *)elem1) == (*(int *)elem2))  return 0;
  else if ((*(int *)elem1) < (*(int *)elem2)) return -1;
  else return 1;}

ผลลัพธ์:

 13 14 48 50 52

ที่นี่เราจะหารือรายละเอียดของโปรแกรม:

ตัวชี้ฟังก์ชันเป็นอาร์กิวเมนต์

  1. เรากำหนดฟังก์ชันการเปรียบเทียบที่ประกอบด้วยสองอาร์กิวเมนต์และส่งคืนค่า 0 เมื่ออาร์กิวเมนต์มีค่าเท่ากัน <0 เมื่อ arg1 มาก่อน arg2 และ >0 เมื่อ arg1 มาก่อน arg2 พารามิเตอร์เป็นประเภทตัวชี้โมฆะที่ส่งไปยังประเภทข้อมูลอาร์เรย์ที่เหมาะสม (จำนวนเต็ม)
  2. เรากำหนดและเริ่มต้นอาร์เรย์จำนวนเต็ม ขนาดอาร์เรย์จะถูกเก็บไว้ใน NUM ตัวแปรและขนาดของแต่ละองค์ประกอบอาร์เรย์จะถูกเก็บไว้ในตัวแปรความกว้างโดยใช้ sizeof() ที่กำหนดไว้ล่วงหน้า ตัวดำเนินการ C.
  3. เราเรียกใช้ฟังก์ชัน qsort และส่งชื่ออาร์เรย์ ขนาด ความกว้าง และฟังก์ชันเปรียบเทียบที่ผู้ใช้กำหนดไว้ก่อนหน้านี้ เพื่อเรียงลำดับอาร์เรย์ของเราจากน้อยไปมาก การเปรียบเทียบจะดำเนินการโดยการเลือกองค์ประกอบสองตัวในอาร์เรย์ในแต่ละรอบ จนกว่าอาร์เรย์ทั้งหมดจะถูกเรียงลำดับ
  4. เราพิมพ์องค์ประกอบอาร์เรย์เพื่อให้แน่ใจว่าอาร์เรย์ของเราได้รับการจัดเรียงอย่างดีโดยการวนซ้ำอาร์เรย์ทั้งหมดโดยใช้ สำหรับห่วง.

คำถามที่พบบ่อย

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

typedef ตั้งชื่อแบบย่อให้กับประเภทตัวชี้ฟังก์ชันที่ซับซ้อน การเขียน typedef int (*Operation)(int, int); ช่วยให้คุณประกาศ Operaใช้คำสั่ง tion add แทนการเขียนไวยากรณ์ตัวชี้แบบเต็มรูปแบบ ทำให้การอ่านอาร์เรย์ พารามิเตอร์ และสมาชิกของโครงสร้างทำได้ง่ายขึ้นมาก

ตัวชี้ฟังก์ชันทำหน้าที่ขับเคลื่อนการเรียกกลับ (callback), ตารางการกระโดดหรือการส่งคำสั่ง (jump or dispatch tables), ระบบปลั๊กอินและระบบที่ขับเคลื่อนด้วยเหตุการณ์ (plugin and event-driven systems), เครื่องสถานะ (state machines) และรูทีนไลบรารี เช่น qsort และ bsearch Operaระบบประมวลผลและเฟิร์มแวร์ฝังตัวอาศัยกลไกเหล่านี้ในการเลือกพฤติกรรมขณะทำงานโดยไม่ต้องใช้เงื่อนไขที่ซับซ้อนหลายขั้นตอน

ตัวชี้ข้อมูล (Data pointer) เก็บที่อยู่ของตัวแปรในหน่วยความจำ ในขณะที่ตัวชี้ฟังก์ชัน (Function pointer) เก็บที่อยู่ของโค้ดที่สามารถเรียกใช้งานได้ คุณเรียกใช้ฟังก์ชันผ่านตัวชี้ฟังก์ชัน แทนที่จะใช้การเข้าถึงค่าที่ตัวชี้ชี้อยู่ (Dereference) เพื่ออ่านหรือเขียนข้อมูล

ใช่แล้ว ตัวชี้ฟังก์ชันสามารถตั้งค่าเป็น NULL เพื่อหมายความว่าจะไม่มีการกำหนดฟังก์ชันให้ การเรียกใช้ตัวชี้ฟังก์ชันที่เป็น NULL จะทำให้เกิดพฤติกรรมที่ไม่แน่นอน ดังนั้นควรตรวจสอบเงื่อนไขด้วย if (ptr != NULL) ก่อนเรียกใช้ โดยเฉพาะอย่างยิ่งสำหรับฟังก์ชันเรียกกลับที่เป็นตัวเลือก

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

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

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

สรุปโพสต์นี้ด้วย: