เมื่อตรวจสอบรหัสฉันใช้กฎต่อไปนี้:
ใช้const
สำหรับพารามิเตอร์ฟังก์ชันที่ส่งผ่านโดยการอ้างอิงทุกครั้งที่ฟังก์ชันไม่แก้ไข (หรือฟรี) ข้อมูลที่ชี้ไป
int find(const int *data, size_t size, int value);
ใช้const
สำหรับค่าคงที่ที่อาจถูกกำหนดโดยใช้ #define หรือ enum เสมอ คอมไพเลอร์สามารถค้นหาข้อมูลในหน่วยความจำแบบอ่านอย่างเดียว (ROM) เป็นผลลัพธ์ (แม้ว่า linker มักจะเป็นเครื่องมือที่ดีกว่าสำหรับจุดประสงค์นี้ในระบบฝังตัว)
const double PI = 3.14;
ไม่เคยใช้ const ในฟังก์ชั่นต้นแบบสำหรับพารามิเตอร์ส่งผ่านโดย
ค่า มันไม่มีความหมายและเป็นเพียง 'เสียง'
// don't add const to 'value' or 'size'
int find(const int *data, size_t size, const int value);
ตามความเหมาะสมให้ใช้const volatile
กับสถานที่ที่โปรแกรมไม่สามารถเปลี่ยนแปลงได้ แต่อาจยังมีการเปลี่ยนแปลง การลงทะเบียนฮาร์ดแวร์เป็นกรณีการใช้งานทั่วไปที่นี่ตัวอย่างเช่นการลงทะเบียนสถานะที่สะท้อนถึงสถานะอุปกรณ์:
const volatile int32_t *DEVICE_STATUS = (int32_t*) 0x100;
การใช้งานอื่น ๆ เป็นทางเลือก ตัวอย่างเช่นพารามิเตอร์ของฟังก์ชั่นภายในการใช้งานฟังก์ชั่นสามารถทำเครื่องหมายเป็น const
// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)
{
... etc
หรือฟังก์ชั่นคืนค่าหรือการคำนวณที่ได้รับและไม่เคยเปลี่ยนแปลง:
char *repeat_str(const char *str, size_t n)
{
const size_t len = strlen(str);
const size_t buf_size = 1 + (len * n);
char *buf = malloc(buf_size);
...
การใช้const
เพียงแค่ระบุว่าคุณจะไม่เปลี่ยนตัวแปร พวกเขาจะไม่เปลี่ยนแปลงวิธีการหรือที่เก็บตัวแปร ผู้แปลสามารถทำงานได้แน่นอนว่าตัวแปรจะไม่เปลี่ยนแปลง แต่โดยการเพิ่มconst
คุณอนุญาตให้มีการบังคับใช้ สิ่งนี้สามารถช่วยผู้อ่านและเพิ่มความปลอดภัย (แม้ว่าฟังก์ชั่นของคุณจะใหญ่หรือซับซ้อนพอที่จะทำให้เกิดความแตกต่างอย่างมากคุณก็มีปัญหาอื่น ๆ ) แก้ไข - เช่น ฟังก์ชันการเข้ารหัสแบบ 200 บรรทัดที่มีลูปซ้อนกันและชื่อตัวแปรที่ยาวหรือคล้ายกันหลาย ๆ อันการรู้ว่าตัวแปรบางตัวไม่เคยเปลี่ยนอาจทำให้การเข้าใจง่ายขึ้นอย่างมีนัยสำคัญ ฟังก์ชั่นดังกล่าวได้รับการออกแบบหรือบำรุงรักษาไม่ดี
const
ปัญหาเกี่ยวกับ คุณอาจได้ยินคำว่า "พิษพิษ" สิ่งนี้เกิดขึ้นเมื่อการเพิ่มconst
พารามิเตอร์ฟังก์ชั่นทำให้ 'constness' เผยแพร่
แก้ไข - พิษ const: ตัวอย่างเช่นในฟังก์ชั่น:
int function_a(char * str, int n)
{
...
function_b(str);
...
}
ถ้าเราเปลี่ยนstr
ไปconst
แล้วเราก็ต้องให้แน่ใจว่ายังใช้fuction_b
const
และถ้าfunction_b
ส่งผ่านstr
ไปยังfunction_c
เป็นต้นอย่างที่คุณจินตนาการได้ว่ามันอาจเจ็บปวดถ้ามันแพร่กระจายไปยังไฟล์ / โมดูลแยกกันมากมาย หากมันแพร่กระจายเข้าไปในฟังก์ชั่นที่ไม่สามารถเปลี่ยนแปลงได้ (เช่นไลบรารีระบบ) การโยนนั้นจำเป็น ดังนั้นการโรย
const
โค้ดที่มีอยู่อาจจะถามถึงปัญหา ในรหัสใหม่แม้ว่าจะเป็นการดีที่สุดที่จะconst
มีคุณสมบัติอย่างสม่ำเสมอตามความเหมาะสม
ปัญหาที่ร้ายกาจกว่าconst
คือมันไม่ได้อยู่ในภาษาดั้งเดิม ในฐานะที่เป็นส่วนเสริมมันค่อนข้างไม่เหมาะสม สำหรับการเริ่มต้นมีสองความหมาย (ตามกฎข้างต้นหมายถึง "ฉันจะไม่เปลี่ยนแปลงสิ่งนี้" และ "สิ่งนี้ไม่สามารถแก้ไขได้") แต่ยิ่งไปกว่านั้นมันอาจเป็นอันตรายได้ ตัวอย่างเช่นคอมไพล์และรันโค้ดนี้และ (ขึ้นอยู่กับคอมไพเลอร์ / ตัวเลือก) มันอาจจะผิดพลาดได้เมื่อรัน:
const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '\0';
strchr
ส่งกลับไม่ได้เป็นchar*
const char*
เป็นพารามิเตอร์โทรของมันคือ
const
มันจะต้องโยนchar*
พารามิเตอร์การเรียกร้องให้ และในกรณีนี้มันได้ทิ้งคุณสมบัติการจัดเก็บข้อมูลแบบอ่านอย่างเดียวออกไป แก้ไข: - ใช้กับ vars โดยทั่วไปในหน่วยความจำแบบอ่านอย่างเดียว โดย 'ROM' ฉันหมายถึงไม่ใช่แค่ ROM จริง แต่เป็นหน่วยความจำที่มีการป้องกันการเขียนเช่นเดียวกับที่เกิดขึ้นกับส่วนรหัสของโปรแกรมที่ทำงานบนระบบปฏิบัติการทั่วไป
ฟังก์ชั่นไลบรารีมาตรฐานหลายตัวทำงานในลักษณะเดียวกันดังนั้นจงระวัง: เมื่อคุณมีค่าคงที่จริง (เช่นเก็บไว้ใน ROM) คุณจะต้องระมัดระวังไม่ให้สูญเสียความมั่นคง
Specific issues with software development
สำหรับผู้ที่ลงคะแนนให้มันถูกปิดกรุณาอธิบายว่าทำไมมันไม่ได้ตกอยู่ภายใต้หมวดหมู่ของ ฉันค่อนข้างเฉพาะเจาะจง