在程式設計中,魔鬼數字(magic numbers)是指程式碼中直接使用的未經解釋的常量數字,這些數字通常沒有明確的含義,可能會使程式碼變得難以理解、維護或擴充套件。魔鬼數字的存在會讓人難以判斷這些數字的用途或來源,因此在程式碼中通常建議避免使用魔鬼數字,而是用具名的常量或宏來代替。
在你提供的示例程式碼中,以下幾個數字可以被認為是魔鬼數字:
魔鬼數字示例
-
3
:表示建立的執行緒數量。- 原始碼:
const int numThreads = 3;
- 解釋:這裡
3
表示程式中要建立的執行緒數量。為了使程式碼更具可讀性,可以將這個數字替換為一個具名的常量。
- 原始碼:
-
2
:用於sleep(2)
,表示執行緒要休眠2秒。- 原始碼:
sleep(2);
- 解釋:這個數字表示執行緒的休眠時間,直接使用會讓人困惑為什麼選擇2秒。可以用一個具名的常量來替代它,以解釋這段休眠的目的。
- 原始碼:
改進後的程式碼
為了消除魔鬼數字,可以將它們替換為具名常量或宏,以增強程式碼的可讀性和可維護性:
#include <iostream>
#include <pthread.h>
#include <unistd.h> // sleep 函式
// 定義具名常量
const int NUM_THREADS = 3; // 執行緒數量
const int THREAD_SLEEP_DURATION = 2; // 每個執行緒休眠的秒數
// 執行緒執行的函式
void* threadFunc(void* arg) {
int* id = static_cast<int*>(arg); // 傳入的引數型別轉換
std::cout << "Thread " << *id << " is running." << std::endl;
sleep(THREAD_SLEEP_DURATION); // 使用具名常量代替魔鬼數字
std::cout << "Thread " << *id << " has finished." << std::endl;
return nullptr;
}
int main() {
pthread_t threads[NUM_THREADS]; // 使用具名常量代替魔鬼數字
int threadArgs[NUM_THREADS];
// 建立多個執行緒
for (int i = 0; i < NUM_THREADS; ++i) {
threadArgs[i] = i + 1; // 為每個執行緒傳遞不同的引數
if (pthread_create(&threads[i], nullptr, threadFunc, &threadArgs[i]) != 0) {
std::cerr << "Error creating thread " << i + 1 << std::endl;
return 1;
}
}
// 等待所有執行緒完成
for (int i = 0; i < NUM_THREADS; ++i) {
if (pthread_join(threads[i], nullptr) != 0) {
std::cerr << "Error joining thread " << i + 1 << std::endl;
return 1;
}
std::cout << "Thread " << i + 1 << " has joined." << std::endl;
}
std::cout << "All threads have completed." << std::endl;
return 0;
}
改進的地方:
NUM_THREADS
: 代替了數字3
,表示執行緒的數量。這樣如果未來需要更改執行緒數量,只需要修改這個常量即可,增強了程式碼的可擴充套件性。THREAD_SLEEP_DURATION
: 代替了sleep(2)
中的2
,明確表示執行緒的休眠時間,這使程式碼更加清晰,並且能夠解釋為什麼執行緒需要休眠。
這樣做的好處:
- 可讀性:具名常量提供了上下文資訊,告訴程式碼的讀者這些數字的含義。
- 可維護性:如果需要更改這些常量的值,只需修改一處,減少了錯誤的可能。
- 可擴充套件性:當需要擴充套件程式碼時,使用具名常量可以讓程式碼更容易修改和理解。
避免魔鬼數字是程式設計中的一個重要實踐,可以顯著提高程式碼的質量。