C語言高級編程技巧與最佳實踐 - 完整版
目錄
- 宏定義與預處理技巧
- 內存管理高級技巧
- 函數指針與回調機制
- 數據結構設計
- 并發與多線程
- 錯誤處理與異常機制
- 性能優化技巧
- 調試與測試技巧
- 跨平臺編程
- 安全編程實踐
- 綜合演示示例
宏定義與預處理技巧
1. 條件編譯與平臺檢測
/*** 平臺和編譯器檢測* 用于條件編譯和跨平臺兼容性*/
#if defined(_WIN32) || defined(_WIN64)#define PLATFORM_WINDOWS
#elif defined(__linux__)#define PLATFORM_LINUX
#elif defined(__APPLE__)#define PLATFORM_MACOS
#endif// 編譯器檢測
#if defined(__GNUC__)#define COMPILER_GCC
#elif defined(_MSC_VER)#define COMPILER_MSVC
#endif// 版本檢測
#if __STDC_VERSION__ >= 201112L#define C11_SUPPORTED
#endif
2. 強大的宏技巧
/*** 高級宏定義集合* 提供類型安全和便捷的宏工具*/// 字符串化和連接
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define CONCAT(a, b) a##b// 獲取數組長度
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))// 容器of宏(從成員指針獲取容器指針)
#define container_of(ptr, type, member) ({ \void *__mptr = (void *)(ptr); \((type *)(__mptr - offsetof(type, member))); })// 最大最小值
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))// 交換變量(不使用臨時變量)
#define SWAP(a, b) do { typeof(a) temp = a; a = b; b = temp; } while(0)// 編譯時斷言
#define STATIC_ASSERT(condition, message) \typedef char static_assertion_##message[(condition) ? 1 : -1]// 可變參數宏
#define DEBUG_PRINT(fmt, ...) \fprintf(stderr, "[DEBUG] %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
3. 現代C語言特性
/*** C11現代特性使用* 利用新標準提高代碼質量*/// 泛型選擇
#define generic_max(a, b) _Generic((a), \int: max_int, \float: max_float, \double: max_double \
)(a, b)// 靜態斷言(C11)
_Static_assert(sizeof(int) >= 4, "int must be at least 4 bytes");// 線程局部存儲(C11)
_Thread_local int thread_var;
內存管理高級技巧
1. 內存池設計
/*** 內存池實現* 提供高效的內存分配和回收機制*/
typedef struct {void *memory;size_t size;size_t used;size_t block_size;
} memory_pool_t;memory_pool_t* create_pool(size_t size, size_t block_size) {memory_pool_t *pool = malloc(sizeof(memory_pool_t));pool->memory = malloc(size);pool->size = size;pool->used = 0;pool->block_size = block_size;return pool;
}void* pool_alloc(memory_pool_t *pool, size_t size) {if (pool->used + size > pool->size) return NULL;void *ptr = (char*)pool->memory + pool->used;pool->used += size;return ptr;
}
2. 智能指針模擬
/*** 智能指針模擬系統* 實現引用計數自動內存管理*/#include <stdatomic.h>typedef struct {void *ptr;void (*deleter)(void*);atomic_int *ref_count;
} smart_ptr_t;smart_ptr_t make_smart_ptr(void *ptr, void (*deleter)(void*)) {smart_ptr_t sp = {ptr, deleter, malloc(sizeof(atomic_int))};atomic_init(sp.ref_count, 1);return sp;
}smart_ptr_t smart_ptr_copy(smart_ptr_t sp) {atomic_fetch_add(sp.ref_count, 1);return sp;
}void smart_ptr_free(smart_ptr_t *sp) {if (atomic_fetch_sub(sp->ref_count, 1) == 1) {sp->deleter(sp->ptr);free(sp->ref_count);}
}
3. 內存對齊
/*** 內存對齊工具* 確保數據結構在內存中的正確對齊*/// C11對齊
_Alignas(16) char aligned_buffer[256];// 手動對齊
#define ALIGN_UP(x, align) (((x) + (align) - 1) & ~((align) - 1))
#define IS_ALIGNED(x, align) (((x) & ((align) - 1)) == 0)void* aligned_malloc(size_t size, size_t alignment) {void *ptr = malloc(size + alignment - 1 + sizeof(void*));if (!ptr) return NULL;void **aligned_ptr = (void**)(((uintptr_t)ptr + sizeof(void*) + alignment - 1) & ~(alignment - 1));aligned_ptr[-1] = ptr;return aligned_ptr;
}
函數指針與回調機制
1. 面向對象風格編程
/*** 虛函數表模擬* 實現C語言中的面向對象編程*/// 虛函數表模擬
typedef struct {void (*destroy)(void *self);void (*print)(void *self);int (*compare)(void *self, void *other);
} vtable_t;typedef struct {vtable_t *vtable;// 具體數據
} object_t;// 多態調用
#define CALL_METHOD(obj, method, ...) \((obj)->vtable->method((obj), ##__VA_ARGS__))
2. 狀態機實現
/*** 狀態機實現* 提供靈活的狀態管理機制*/typedef enum {STATE_IDLE,STATE_RUNNING,STATE_PAUSED,STATE_STOPPED
} state_t;typedef struct {state_t current_state;int (*handlers[4])(void *context, int event);
} state_machine_t;int handle_idle(void *context, int event) {switch (event) {case EVENT_START:return STATE_RUNNING;default:return STATE_IDLE;}
}
3. 插件系統設計
/*** 插件系統設計* 支持動態加載和擴展功能*/typedef struct {const char *name;int version;int (*init)(void);void (*cleanup)(void);void* (*create_instance)(void);
} plugin_interface_t;// 動態加載插件
#ifdef _WIN32#include <windows.h>#define LOAD_PLUGIN(name) LoadLibrary(name)#define GET_SYMBOL(handle, name) GetProcAddress(handle, name)
#else#include <dlfcn.h>#define LOAD_PLUGIN(name) dlopen(name, RTLD_LAZY)#define GET_SYMBOL(handle, name) dlsym(handle, name)
#endif
數據結構設計
1. 鏈表實現
/*** 雙向鏈表實現* 提供高效的插入和刪除操作*/typedef struct list_node {void *data;struct list_node *next;struct list_node *prev;
} list_node_t;typedef struct {list_node_t head;size_t size;void (*destructor)(void*);
} list_t;// 雙向鏈表操作
void list_insert_after(list_t *list, list_node_t *node, void *data) {list_node_t *new_node = malloc(sizeof(list_node_t));new_node->data = data;new_node->next = node->next;new_node->prev = node;if (node->next) node->next->prev = new_node;node->next = new_node;list->size++;
}
2. 哈希表實現
/*** 哈希表實現* 提供快速的鍵值對存儲和檢索*/typedef struct hash_entry {char *key;void *value;struct hash_entry *next;
} hash_entry_t;typedef struct {hash_entry_t **buckets;size_t bucket_count;size_t size;unsigned int (*hash_func)(const char*);
} hash_table_t;unsigned int djb2_hash(const char *str) {unsigned int hash = 5381;int c;while ((c = *str++)) hash = ((hash << 5) + hash) + c;return hash;
}
3. 環形緩沖區
/*** 環形緩沖區實現* 適用于生產者-消費者模式*/typedef struct {char *buffer;size_t size;size_t read_pos;size_t write_pos;int full;
} ring_buffer_t;int ring_buffer_write(ring_buffer_t *rb, const char *data, size_t len) {size_t available = rb->size - ring_buffer_size(rb);if (len > available) return -1;for (size_t i = 0; i < len; i++) {rb->buffer[rb->write_pos] = data[i];rb->write_pos = (rb->write_pos + 1) % rb->size;if (rb->write_pos == rb->read_pos) rb->full = 1;}return len;
}
并發與多線程
1. 線程安全的數據結構
/*** 線程安全計數器* 提供原子操作和條件等待*/#include <pthread.h>typedef struct {int value;pthread_mutex_t mutex;pthread_cond_t cond;
} thread_safe_counter_t;void counter_increment(thread_safe_counter_t *counter) {pthread_mutex_lock(&counter->mutex);counter->value++;pthread_cond_signal(&counter->cond);pthread_mutex_unlock(&counter->mutex);
}int counter_wait_for(thread_safe_counter_t *counter, int target) {pthread_mutex_lock(&counter->mutex);while (counter->value < target) {pthread_cond_wait(&counter->cond, &counter->mutex);}pthread_mutex_unlock(&counter->mutex);return counter->value;
}
2. 讀寫鎖實現
/*** 讀寫鎖實現* 支持多讀單寫的并發控制*/typedef struct {pthread_mutex_t mutex;pthread_cond_t read_cond;pthread_cond_t write_cond;int readers;int writers;int waiting_writers;
} rwlock_t;void rwlock_rdlock(rwlock_t *rwlock) {pthread_mutex_lock(&rwlock->mutex);while (rwlock->writers > 0 || rwlock->waiting_writers > 0) {pthread_cond_wait(&rwlock->read_cond, &rwlock->mutex);}rwlock->readers++;pthread_mutex_unlock(&rwlock->mutex);
}
3. 無鎖編程
/*** 無鎖編程工具* 使用原子操作實現高性能并發*/#include <stdatomic.h>typedef struct {atomic_int value;
} atomic_counter_t;void atomic_counter_increment(atomic_counter_t *counter) {atomic_fetch_add(&counter->value, 1);
}int atomic_counter_get(atomic_counter_t *counter) {return atomic_load(&counter->value);
}
錯誤處理與異常機制
1. 錯誤碼系統
/*** 錯誤碼系統* 提供結構化的錯誤處理機制*/typedef enum {ERROR_SUCCESS = 0,ERROR_INVALID_PARAM = -1,ERROR_OUT_OF_MEMORY = -2,ERROR_FILE_NOT_FOUND = -3,ERROR_PERMISSION_DENIED = -4
} error_code_t;#define RETURN_ON_ERROR(expr) do { \error_code_t err = (expr); \if (err != ERROR_SUCCESS) return err; \
} while(0)// 帶上下文的錯誤處理
typedef struct {error_code_t code;const char *message;const char *file;int line;
} error_context_t;
2. 異常模擬機制
/*** 異常模擬機制* 使用setjmp/longjmp實現異常處理*/#include <setjmp.h>typedef struct {jmp_buf jump_buffer;int error_code;const char *error_message;
} exception_context_t;static __thread exception_context_t *current_exception = NULL;#define TRY \do { \exception_context_t __exception_ctx; \__exception_ctx.error_code = 0; \if (setjmp(__exception_ctx.jump_buffer) == 0) { \current_exception = &__exception_ctx;#define CATCH(error_var) \} else { \error_var = current_exception->error_code;#define END_TRY \} \current_exception = NULL; \} while(0);#define THROW(code, message) \do { \if (current_exception) { \current_exception->error_code = code; \current_exception->error_message = message; \longjmp(current_exception->jump_buffer, 1); \} \} while(0)
3. 資源管理RAII
/*** RAII資源管理* 確保資源的自動釋放*/typedef struct {void *resource;void (*cleanup)(void*);
} raii_guard_t;#define RAII_VAR(type, name, init, cleanup_func) \type name = init; \raii_guard_t __guard_##name = {&name, (void(*)(void*))cleanup_func}; \__attribute__((cleanup(raii_cleanup))) raii_guard_t *__raii_##name = &__guard_##name;static void raii_cleanup(raii_guard_t **guard) {if ((*guard)->resource && (*guard)->cleanup) {(*guard)->cleanup((*guard)->resource);}
}
性能優化技巧
1. 緩存友好的數據結構
/*** 緩存友好的數據結構* 優化內存布局提高緩存命中率*/// 結構體打包優化
struct __attribute__((packed)) packed_struct {char a;int b;short c;
};// 緩存行對齊
#define CACHE_LINE_SIZE 64
struct __attribute__((aligned(CACHE_LINE_SIZE))) cache_aligned_struct {int data[16];
};
2. 分支預測優化
/*** 分支預測優化* 使用編譯器提示提高執行效率*/// 靜態分支預測
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)void optimized_function(int *array, size_t size) {if (unlikely(size == 0)) return;for (size_t i = 0; likely(i < size); i++) {process_element(array[i]);}
}
3. 內聯匯編優化
/*** 內聯匯編優化* 直接使用CPU指令提高性能*/// 獲取時間戳計數器
static inline uint64_t rdtsc(void) {uint32_t lo, hi;__asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));return ((uint64_t)hi << 32) | lo;
}// 內存屏障
#define MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory")
4. SIMD優化
/*** SIMD優化* 利用向量指令并行處理數據*/#ifdef __SSE2__
#include <emmintrin.h>void vector_add(float *a, float *b, float *result, size_t n) {size_t i = 0;for (; i + 4 <= n; i += 4) {__m128 va = _mm_load_ps(&a[i]);__m128 vb = _mm_load_ps(&b[i]);__m128 vr = _mm_add_ps(va, vb);_mm_store_ps(&result[i], vr);}// 處理剩余元素for (; i < n; i++) {result[i] = a[i] + b[i];}
}
#endif
調試與測試技巧
1. 調試宏
/*** 調試工具宏* 提供便捷的調試和性能分析功能*/#ifdef DEBUG#define DBG_PRINT(fmt, ...) \fprintf(stderr, "[DEBUG] %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)#define ASSERT(condition) \do { \if (!(condition)) { \fprintf(stderr, "Assertion failed: %s at %s:%d\n", \#condition, __FILE__, __LINE__); \abort(); \} \} while(0)
#else#define DBG_PRINT(fmt, ...) do {} while(0)#define ASSERT(condition) do {} while(0)
#endif// 性能計時
#define TIME_IT(code, result_var) \do { \clock_t start = clock(); \code; \result_var = ((double)(clock() - start)) / CLOCKS_PER_SEC; \} while(0)
2. 單元測試框架
/*** 單元測試框架* 提供結構化的測試支持*/typedef struct {const char *name;void (*test_func)(void);int passed;int failed;
} test_case_t;#define TEST_CASE(name) \static void test_##name(void); \static test_case_t test_case_##name = {#name, test_##name, 0, 0}; \static void test_##name(void)#define ASSERT_EQ(expected, actual) \do { \if ((expected) != (actual)) { \fprintf(stderr, "Assertion failed: %s != %s at %s:%d\n", \#expected, #actual, __FILE__, __LINE__); \current_test->failed++; \} else { \current_test->passed++; \} \} while(0)
3. 內存泄漏檢測
/*** 內存泄漏檢測* 跟蹤內存分配和釋放*/#ifdef DEBUG_MEMORY
static size_t total_allocated = 0;
static size_t allocation_count = 0;void* debug_malloc(size_t size, const char *file, int line) {void *ptr = malloc(size + sizeof(size_t));if (ptr) {*(size_t*)ptr = size;total_allocated += size;allocation_count++;printf("ALLOC: %zu bytes at %s:%d\n", size, file, line);return (char*)ptr + sizeof(size_t);}return NULL;
}void debug_free(void *ptr, const char *file, int line) {if (ptr) {size_t *size_ptr = (size_t*)((char*)ptr - sizeof(size_t));total_allocated -= *size_ptr;allocation_count--;printf("FREE: %zu bytes at %s:%d\n", *size_ptr, file, line);free(size_ptr);}
}#define malloc(size) debug_malloc(size, __FILE__, __LINE__)
#define free(ptr) debug_free(ptr, __FILE__, __LINE__)
#endif
跨平臺編程
1. 平臺抽象層
/*** 平臺抽象層* 提供統一的跨平臺接口*/// 線程抽象
#ifdef _WIN32#include <windows.h>typedef HANDLE thread_t;typedef CRITICAL_SECTION mutex_t;#define THREAD_CREATE(thread, func, arg) \(thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL))#define THREAD_JOIN(thread) WaitForSingleObject(thread, INFINITE)#define MUTEX_INIT(mutex) InitializeCriticalSection(mutex)#define MUTEX_LOCK(mutex) EnterCriticalSection(mutex)#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(mutex)
#else#include <pthread.h>typedef pthread_t thread_t;typedef pthread_mutex_t mutex_t;#define THREAD_CREATE(thread, func, arg) pthread_create(&thread, NULL, func, arg)#define THREAD_JOIN(thread) pthread_join(thread, NULL)#define MUTEX_INIT(mutex) pthread_mutex_init(mutex, NULL)#define MUTEX_LOCK(mutex) pthread_mutex_lock(mutex)#define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex)
#endif
2. 文件路徑處理
/*** 文件路徑處理* 提供跨平臺的路徑操作*/#ifdef _WIN32#define PATH_SEPARATOR '\\'#define PATH_SEPARATOR_STR "\\"
#else#define PATH_SEPARATOR '/'#define PATH_SEPARATOR_STR "/"
#endifchar* join_path(const char *dir, const char *file) {size_t dir_len = strlen(dir);size_t file_len = strlen(file);char *result = malloc(dir_len + file_len + 2);strcpy(result, dir);if (dir[dir_len - 1] != PATH_SEPARATOR) {strcat(result, PATH_SEPARATOR_STR);}strcat(result, file);return result;
}
3. 字節序處理
/*** 字節序處理* 確保數據在網絡傳輸中的正確性*/// 網絡字節序轉換
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__#define IS_BIG_ENDIAN 1
#else#define IS_BIG_ENDIAN 0
#endifstatic inline uint32_t swap_endian_32(uint32_t val) {return ((val & 0x000000FF) << 24) |((val & 0x0000FF00) << 8) |((val & 0x00FF0000) >> 8) |((val & 0xFF000000) >> 24);
}#define hton32(x) (IS_BIG_ENDIAN ? (x) : swap_endian_32(x))
#define ntoh32(x) hton32(x)
安全編程實踐
1. 緩沖區溢出防護
/*** 緩沖區溢出防護* 提供安全的字符串操作函數*/// 安全字符串操作
size_t safe_strncpy(char *dest, size_t dest_size, const char *src, size_t count) {if (dest_size == 0) return 0;size_t copy_len = (count < dest_size - 1) ? count : dest_size - 1;memcpy(dest, src, copy_len);dest[copy_len] = '\0';return copy_len;
}// 格式化字符串安全檢查
#define SAFE_PRINTF(buffer, size, format, ...) \do { \int __result = snprintf(buffer, size, format, ##__VA_ARGS__); \if (__result < 0 || (size_t)__result >= size) { \/* 處理溢出 */ \buffer[size - 1] = '\0'; \} \} while(0)
2. 輸入驗證
/*** 輸入驗證* 防止惡意輸入導致的安全問題*/// 整數溢出檢查
static inline int safe_add(int a, int b, int *result) {if ((b > 0 && a > INT_MAX - b) || (b < 0 && a < INT_MIN - b)) {return -1; // 溢出}*result = a + b;return 0;
}// 指針驗證
#define VALIDATE_PTR(ptr) \do { \if (!(ptr)) { \return ERROR_INVALID_PARAM; \} \} while(0)
3. 安全隨機數
/*** 安全隨機數生成* 提供密碼學安全的隨機數*/#include <time.h>
#include <stdlib.h>// 密碼學安全隨機數(需要平臺支持)
#ifdef __linux__#include <sys/random.h>int secure_random_bytes(void *buf, size_t len) {return getrandom(buf, len, 0) == (ssize_t)len ? 0 : -1;}
#else// 簡單的偽隨機數生成器static unsigned long long rand_state = 1;void srand64(unsigned long long seed) {rand_state = seed;}unsigned long long rand64(void) {rand_state = rand_state * 6364136223846793005ULL + 1;return rand_state;}
#endif
綜合演示示例
事件驅動架構演示
/*** 事件驅動架構 - 事件類型定義* 用于構建靈活的事件處理系統*/
typedef enum {EVENT_NONE = 0,EVENT_TIMER,EVENT_NETWORK,EVENT_USER,EVENT_SYSTEM
} event_type_t;/*** 事件結構體* 包含事件類型、時間戳和用戶數據*/
typedef struct {event_type_t type;uint64_t timestamp;void *data;size_t data_size;
} event_t;/*** 事件處理器函數指針類型* @param event 事件指針* @param context 用戶上下文* @return 處理結果*/
typedef int (*event_handler_t)(event_t *event, void *context);/*** 事件監聽器結構體* 存儲事件類型和對應的處理器*/
typedef struct {event_type_t type;event_handler_t handler;void *context;int priority; // 處理優先級
} event_listener_t;/*** 事件循環結構體* 管理事件隊列和監聽器*/
typedef struct {event_listener_t *listeners;size_t listener_count;size_t listener_capacity;event_t *event_queue;size_t queue_head;size_t queue_tail;size_t queue_size;size_t queue_capacity;int running;pthread_mutex_t mutex;pthread_cond_t cond;
} event_loop_t;/*** 創建事件循環* @param queue_capacity 事件隊列容量* @return 事件循環指針*/
event_loop_t* event_loop_create(size_t queue_capacity) {event_loop_t *loop = calloc(1, sizeof(event_loop_t));if (!loop) return NULL;loop->queue_capacity = queue_capacity;loop->event_queue = calloc(queue_capacity, sizeof(event_t));if (!loop->event_queue) {free(loop);return NULL;}loop->listeners = calloc(16, sizeof(event_listener_t)); // 初始監聽器容量loop->listener_capacity = 16;pthread_mutex_init(&loop->mutex, NULL);pthread_cond_init(&loop->cond, NULL);return loop;
}/*** 添加事件監聽器* @param loop 事件循環* @param type 事件類型* @param handler 事件處理器* @param context 用戶上下文* @param priority 處理優先級* @return 0成功,-1失敗*/
int event_loop_add_listener(event_loop_t *loop, event_type_t type,event_handler_t handler, void *context, int priority) {if (!loop || !handler) return -1;pthread_mutex_lock(&loop->mutex);// 擴展監聽器數組if (loop->listener_count >= loop->listener_capacity) {size_t new_capacity = loop->listener_capacity * 2;event_listener_t *new_listeners = realloc(loop->listeners, new_capacity * sizeof(event_listener_t));if (!new_listeners) {pthread_mutex_unlock(&loop->mutex);return -1;}loop->listeners = new_listeners;loop->listener_capacity = new_capacity;}// 添加新監聽器event_listener_t *listener = &loop->listeners[loop->listener_count++];listener->type = type;listener->handler = handler;listener->context = context;listener->priority = priority;pthread_mutex_unlock(&loop->mutex);return 0;
}/*** 發布事件* @param loop 事件循環* @param event 事件指針* @return 0成功,-1失敗*/
int event_loop_post(event_loop_t *loop, event_t *event) {if (!loop || !event) return -1;pthread_mutex_lock(&loop->mutex);// 檢查隊列是否已滿if ((loop->queue_tail + 1) % loop->queue_capacity == loop->queue_head) {pthread_mutex_unlock(&loop->mutex);return -1; // 隊列已滿}// 復制事件到隊列event_t *queue_event = &loop->event_queue[loop->queue_tail];queue_event->type = event->type;queue_event->timestamp = event->timestamp;if (event->data && event->data_size > 0) {queue_event->data = malloc(event->data_size);if (queue_event->data) {memcpy(queue_event->data, event->data, event->data_size);queue_event->data_size = event->data_size;} else {queue_event->data_size = 0;}} else {queue_event->data = NULL;queue_event->data_size = 0;}loop->queue_tail = (loop->queue_tail + 1) % loop->queue_capacity;pthread_cond_signal(&loop->cond);pthread_mutex_unlock(&loop->mutex);return 0;
}/*** 事件循環主函數* @param loop 事件循環*/
void event_loop_run(event_loop_t *loop) {if (!loop) return;loop->running = 1;while (loop->running) {pthread_mutex_lock(&loop->mutex);// 等待事件while (loop->queue_head == loop->queue_tail && loop->running) {pthread_cond_wait(&loop->cond, &loop->mutex);}if (!loop->running) {pthread_mutex_unlock(&loop->mutex);break;}// 獲取事件event_t event = loop->event_queue[loop->queue_head];loop->queue_head = (loop->queue_head + 1) % loop->queue_capacity;pthread_mutex_unlock(&loop->mutex);// 處理事件for (size_t i = 0; i < loop->listener_count; i++) {if (loop->listeners[i].type == event.type || loop->listeners[i].type == EVENT_NONE) { // EVENT_NONE監聽所有事件loop->listeners[i].handler(&event, loop->listeners[i].context);}}// 清理事件數據if (event.data) {free(event.data);}}
}/*** 停止事件循環* @param loop 事件循環*/
void event_loop_stop(event_loop_t *loop) {if (!loop) return;pthread_mutex_lock(&loop->mutex);loop->running = 0;pthread_cond_signal(&loop->cond);pthread_mutex_unlock(&loop->mutex);
}/*** 銷毀事件循環* @param loop 事件循環*/
void event_loop_destroy(event_loop_t *loop) {if (!loop) return;event_loop_stop(loop);if (loop->listeners) {free(loop->listeners);}// 清理事件隊列中剩余的事件while (loop->queue_head != loop->queue_tail) {event_t *event = &loop->event_queue[loop->queue_head];if (event->data) {free(event->data);}loop->queue_head = (loop->queue_head + 1) % loop->queue_capacity;}if (loop->event_queue) {free(loop->event_queue);}pthread_mutex_destroy(&loop->mutex);pthread_cond_destroy(&loop->cond);free(loop);
}
無鎖隊列實現
/*** 無鎖隊列實現* 使用CAS操作實現線程安全的無鎖隊列*/#include <stdatomic.h>/*** 隊列節點結構*/
typedef struct queue_node {void *data;_Atomic(struct queue_node*) next;
} queue_node_t;/*** 無鎖隊列結構*/
typedef struct {_Atomic(queue_node_t*) head;_Atomic(queue_node_t*) tail;atomic_size_t size;
} lockfree_queue_t;/*** 創建無鎖隊列節點* @param data 節點數據* @return 節點指針*/
static queue_node_t* create_queue_node(void *data) {queue_node_t *node = malloc(sizeof(queue_node_t));if (node) {node->data = data;atomic_init(&node->next, NULL);}return node;
}/*** 創建無鎖隊列* @return 隊列指針*/
lockfree_queue_t* lockfree_queue_create() {lockfree_queue_t *queue = malloc(sizeof(lockfree_queue_t));if (!queue) return NULL;// 創建哨兵節點queue_node_t *dummy = create_queue_node(NULL);if (!dummy) {free(queue);return NULL;}atomic_init(&queue->head, dummy);atomic_init(&queue->tail, dummy);atomic_init(&queue->size, 0);return queue;
}/*** 入隊操作* @param queue 隊列* @param data 數據* @return 0成功,-1失敗*/
int lockfree_queue_enqueue(lockfree_queue_t *queue, void *data) {if (!queue) return -1;queue_node_t *node = create_queue_node(data);if (!node) return -1;queue_node_t *prev_tail = NULL;queue_node_t *prev_tail_next = NULL;while (1) {prev_tail = atomic_load(&queue->tail);prev_tail_next = atomic_load(&prev_tail->next);// 檢查tail是否一致if (prev_tail == atomic_load(&queue->tail)) {if (prev_tail_next == NULL) {// tail是最后一個節點,嘗試鏈接新節點if (atomic_compare_exchange_weak(&prev_tail->next, &prev_tail_next, node)) {break; // 成功}} else {// tail不是最后一個節點,嘗試推進tailatomic_compare_exchange_weak(&queue->tail, &prev_tail, prev_tail_next);}}}// 推進tailatomic_compare_exchange_weak(&queue->tail, &prev_tail, node);atomic_fetch_add(&queue->size, 1);return 0;
}/*** 出隊操作* @param queue 隊列* @param data 輸出參數:出隊數據* @return 0成功,-1隊列為空*/
int lockfree_queue_dequeue(lockfree_queue_t *queue, void **data) {if (!queue || !data) return -1;queue_node_t *head = NULL;queue_node_t *tail = NULL;queue_node_t *next = NULL;while (1) {head = atomic_load(&queue->head);tail = atomic_load(&queue->tail);next = atomic_load(&head->next);// 檢查head是否一致if (head == atomic_load(&queue->head)) {if (head == tail) {// 隊列為空或只有一個哨兵節點if (next == NULL) {*data = NULL;return -1; // 隊列為空}// 隊列正在變化,推進tailatomic_compare_exchange_weak(&queue->tail, &tail, next);} else {// 讀取數據*data = next->data;// 嘗試推進headif (atomic_compare_exchange_weak(&queue->head, &head, next)) {atomic_fetch_sub(&queue->size, 1);break;}}}}free(head); // 釋放舊的head節點return 0;
}/*** 獲取隊列大小* @param queue 隊列* @return 隊列大小*/
size_t lockfree_queue_size(lockfree_queue_t *queue) {return atomic_load(&queue->size);
}/*** 銷毀無鎖隊列* @param queue 隊列*/
void lockfree_queue_destroy(lockfree_queue_t *queue) {if (!queue) return;// 清空隊列void *data;while (lockfree_queue_dequeue(queue, &data) == 0) {// 數據由調用者負責釋放}// 釋放哨兵節點queue_node_t *head = atomic_load(&queue->head);if (head) {free(head);}free(queue);
}
緩存友好的數據結構
/*** 緩存友好的數據結構實現* 優化內存布局以提高緩存命中率*//*** 緩存行大小定義*/
#define CACHE_LINE_SIZE 64/*** 緩存對齊宏*/
#define CACHE_ALIGNED __attribute__((aligned(CACHE_LINE_SIZE)))/*** SoA (Structure of Arrays) 向量結構* 將相關數據分離存儲以提高緩存效率*/
typedef struct {float *x; // X坐標數組float *y; // Y坐標數組float *z; // Z坐標數組int *id; // ID數組size_t capacity; // 容量size_t size; // 當前大小char padding[CACHE_LINE_SIZE - sizeof(size_t)*2 - sizeof(char*)*4]; // 填充到緩存行邊界
} soa_vector_t;/*** AoS (Array of Structures) 向量結構* 傳統結構體數組方式*/
typedef struct {float x, y, z;int id;
} aos_point_t;typedef struct {aos_point_t *points;size_t capacity;size_t size;char padding[CACHE_LINE_SIZE - sizeof(size_t)*2 - sizeof(void*)]; // 填充
} aos_vector_t;/*** 創建SoA向量* @param initial_capacity 初始容量* @return SoA向量指針*/
soa_vector_t* soa_vector_create(size_t initial_capacity) {soa_vector_t *vec = calloc(1, sizeof(soa_vector_t));if (!vec) return NULL;vec->capacity = initial_capacity;vec->x = malloc(sizeof(float) * initial_capacity);vec->y = malloc(sizeof(float) * initial_capacity);vec->z = malloc(sizeof(float) * initial_capacity);vec->id = malloc(sizeof(int) * initial_capacity);if (!vec->x || !vec->y || !vec->z || !vec->id) {soa_vector_destroy(vec);return NULL;}return vec;
}/*** 創建AoS向量* @param initial_capacity 初始容量* @return AoS向量指針*/
aos_vector_t* aos_vector_create(size_t initial_capacity) {aos_vector_t *vec = calloc(1, sizeof(aos_vector_t));if (!vec) return NULL;vec->capacity = initial_capacity;vec->points = malloc(sizeof(aos_point_t) * initial_capacity);if (!vec->points) {free(vec);return NULL;}return vec;
}/*** SoA向量添加元素* @param vec SoA向量* @param x X坐標* @param y Y坐標* @param z Z坐標* @param id ID* @return 0成功,-1失敗*/
int soa_vector_push(soa_vector_t *vec, float x, float y, float z, int id) {if (!vec) return -1;// 檢查是否需要擴容if (vec->size >= vec->capacity) {size_t new_capacity = vec->capacity * 2;float *new_x = realloc(vec->x, sizeof(float) * new_capacity);float *new_y = realloc(vec->y, sizeof(float) * new_capacity);float *new_z = realloc(vec->z, sizeof(float) * new_capacity);int *new_id = realloc(vec->id, sizeof(int) * new_capacity);if (!new_x || !new_y || !new_z || !new_id) {return -1;}vec->x = new_x;vec->y = new_y;vec->z = new_z;vec->id = new_id;vec->capacity = new_capacity;}size_t index = vec->size++;vec->x[index] = x;vec->y[index] = y;vec->z[index] = z;vec->id[index] = id;return 0;
}/*** AoS向量添加元素* @param vec AoS向量* @param x X坐標* @param y Y坐標* @param z Z坐標* @param id ID* @return 0成功,-1失敗*/
int aos_vector_push(aos_vector_t *vec, float x, float y, float z, int id) {if (!vec) return -1;// 檢查是否需要擴容if (vec->size >= vec->capacity) {size_t new_capacity = vec->capacity * 2;aos_point_t *new_points = realloc(vec->points, sizeof(aos_point_t) * new_capacity);if (!new_points) return -1;vec->points = new_points;vec->capacity = new_capacity;}aos_point_t *point = &vec->points[vec->size++];point->x = x;point->y = y;point->z = z;point->id = id;return 0;
}/*** SoA向量批量處理(緩存友好)* @param vec SoA向量* @param processor 處理函數* @param context 用戶上下文*/
void soa_vector_process(soa_vector_t *vec, void (*processor)(float x, float y, float z, int id, void *context),void *context) {if (!vec || !processor) return;// 分別處理每個數組,提高緩存命中率for (size_t i = 0; i < vec->size; i++) {processor(vec->x[i], vec->y[i], vec->z[i], vec->id[i], context);}
}/*** AoS向量批量處理* @param vec AoS向量* @param processor 處理函數* @param context 用戶上下文*/
void aos_vector_process(aos_vector_t *vec,void (*processor)(float x, float y, float z, int id, void *context),void *context) {if (!vec || !processor) return;// 處理結構體數組for (size_t i = 0; i < vec->size; i++) {aos_point_t *point = &vec->points[i];processor(point->x, point->y, point->z, point->id, context);}
}/*** 銷毀SoA向量* @param vec SoA向量*/
void soa_vector_destroy(soa_vector_t *vec) {if (!vec) return;if (vec->x) free(vec->x);if (vec->y) free(vec->y);if (vec->z) free(vec->z);if (vec->id) free(vec->id);free(vec);
}/*** 銷毀AoS向量* @param vec AoS向量*/
void aos_vector_destroy(aos_vector_t *vec) {if (!vec) return;if (vec->points) free(vec->points);free(vec);
}/*** 性能測試結構*/
typedef struct {double soa_time;double aos_time;size_t elements_processed;
} performance_result_t;
安全字符串操作庫
/*** 安全字符串操作庫* 提供防止緩沖區溢出的安全字符串函數*/#include <string.h>
#include <stdio.h>
#include <stdarg.h>/*** 安全字符串結構* 包含長度信息以防止溢出*/
typedef struct {char *data;size_t length;size_t capacity;int is_secure; // 是否啟用安全檢查
} secure_string_t;/*** 創建安全字符串* @param initial_capacity 初始容量* @param enable_security 是否啟用安全檢查* @return 安全字符串指針*/
secure_string_t* secure_string_create(size_t initial_capacity, int enable_security) {secure_string_t *str = calloc(1, sizeof(secure_string_t));if (!str) return NULL;str->data = malloc(initial_capacity + 1); // +1 for null terminatorif (!str->data) {free(str);return NULL;}str->data[0] = '\0';str->capacity = initial_capacity;str->is_secure = enable_security;return str;
}/*** 從C字符串創建安全字符串* @param c_str C字符串* @param enable_security 是否啟用安全檢查* @return 安全字符串指針*/
secure_string_t* secure_string_from_cstr(const char *c_str, int enable_security) {if (!c_str) return NULL;size_t len = strlen(c_str);secure_string_t *str = secure_string_create(len, enable_security);if (str) {strncpy(str->data, c_str, str->capacity);str->data[str->capacity] = '\0';str->length = strlen(str->data);}return str;
}/*** 安全字符串追加* @param str 目標字符串* @param append_str 要追加的字符串* @return 0成功,-1失敗*/
int secure_string_append(secure_string_t *str, const char *append_str) {if (!str || !append_str) return -1;size_t append_len = strlen(append_str);size_t new_length = str->length + append_len;// 檢查是否需要擴容if (new_length >= str->capacity) {if (str->is_secure) {// 安全模式:拒絕超出容量的操作return -1;} else {// 非安全模式:自動擴容size_t new_capacity = (new_length + 1) * 2;char *new_data = realloc(str->data, new_capacity + 1);if (!new_data) return -1;str->data = new_data;str->capacity = new_capacity;}}// 執行追加strncat(str->data, append_str, str->capacity - str->length);str->length = strlen(str->data);return 0;
}/*** 安全格式化字符串* @param str 目標字符串* @param format 格式字符串* @param ... 可變參數* @return 寫入的字符數,-1失敗*/
int secure_string_printf(secure_string_t *str, const char *format, ...) {if (!str || !format) return -1;va_list args;va_start(args, format);// 首先計算需要的空間va_list args_copy;va_copy(args_copy, args);int needed = vsnprintf(NULL, 0, format, args_copy);va_end(args_copy);if (needed < 0) {va_end(args);return -1;}// 檢查容量if ((size_t)needed >= str->capacity - str->length) {if (str->is_secure) {va_end(args);return -1; // 容量不足} else {// 自動擴容size_t new_capacity = str->length + needed + 1;char *new_data = realloc(str->data, new_capacity + 1);if (!new_data) {va_end(args);return -1;}str->data = new_data;str->capacity = new_capacity;}}// 執行格式化int written = vsnprintf(str->data + str->length, str->capacity - str->length, format, args);if (written >= 0) {str->length += written;}va_end(args);return written;
}/*** 安全字符串比較* @param str1 字符串1* @param str2 字符串2* @return 比較結果*/
int secure_string_compare(const secure_string_t *str1, const secure_string_t *str2) {if (!str1 && !str2) return 0;if (!str1) return -1;if (!str2) return 1;return strcmp(str1->data, str2->data);
}/*** 獲取C字符串* @param str 安全字符串* @return C字符串指針*/
const char* secure_string_cstr(const secure_string_t *str) {return str ? str->data : NULL;
}/*** 獲取字符串長度* @param str 安全字符串* @return 字符串長度*/
size_t secure_string_length(const secure_string_t *str) {return str ? str->length : 0;
}/*** 清空字符串* @param str 安全字符串*/
void secure_string_clear(secure_string_t *str) {if (str && str->data) {str->data[0] = '\0';str->length = 0;}
}/*** 銷毀安全字符串* @param str 安全字符串*/
void secure_string_destroy(secure_string_t *str) {if (!str) return;if (str->data) {// 安全清除內存memset(str->data, 0, str->capacity);free(str->data);}free(str);
}/*** 安全字符串池* 管理多個安全字符串以提高性能*/
typedef struct {secure_string_t **strings;size_t count;size_t capacity;pthread_mutex_t mutex;
} string_pool_t;/*** 創建字符串池* @param initial_capacity 初始容量* @return 字符串池指針*/
string_pool_t* string_pool_create(size_t initial_capacity) {string_pool_t *pool = calloc(1, sizeof(string_pool_t));if (!pool) return NULL;pool->strings = calloc(initial_capacity, sizeof(secure_string_t*));if (!pool->strings) {free(pool);return NULL;}pool->capacity = initial_capacity;pthread_mutex_init(&pool->mutex, NULL);return pool;
}
綜合演示函數
/*** 事件驅動架構演示示例*/
void demo_event_driven_architecture() {printf("=== 事件驅動架構演示 ===\n");// 創建事件循環event_loop_t *loop = event_loop_create(100);if (!loop) {printf("Failed to create event loop\n");return;}// 添加事件監聽器event_loop_add_listener(loop, EVENT_TIMER, timer_handler, NULL, 0);event_loop_add_listener(loop, EVENT_NETWORK, network_handler, NULL, 0);event_loop_add_listener(loop, EVENT_USER, user_handler, NULL, 0);// 啟動事件循環線程pthread_t loop_thread;pthread_create(&loop_thread, NULL, (void*(*)(void*))event_loop_run, loop);// 發布一些測試事件for (int i = 0; i < 5; i++) {event_t event = {0};event.timestamp = time(NULL);// 發布不同類型的事件switch (i % 3) {case 0:event.type = EVENT_TIMER;printf("Posting timer event %d\n", i);break;case 1: {event.type = EVENT_NETWORK;const char *msg = "Hello Network!";event.data = strdup(msg);event.data_size = strlen(msg);printf("Posting network event %d\n", i);break;}case 2:event.type = EVENT_USER;event.data = malloc(sizeof(int));*(int*)event.data = i;event.data_size = sizeof(int);printf("Posting user event %d\n", i);break;}event_loop_post(loop, &event);sleep(1);}// 清理事件數據sleep(2);// 停止并銷毀事件循環event_loop_stop(loop);pthread_join(loop_thread, NULL);event_loop_destroy(loop);printf("=== 演示完成 ===\n\n");
}/*** 無鎖隊列演示示例*/
void demo_lockfree_queue() {printf("=== 無鎖隊列演示 ===\n");// 初始化queue = lockfree_queue_create();atomic_init(&items_produced, 0);atomic_init(&items_consumed, 0);if (!queue) {printf("Failed to create queue\n");return;}// 創建生產者和消費者線程pthread_t producers[NUM_PRODUCERS];pthread_t consumers[NUM_CONSUMERS];int producer_ids[NUM_PRODUCERS];int consumer_ids[NUM_CONSUMERS];// 啟動生產者線程for (int i = 0; i < NUM_PRODUCERS; i++) {producer_ids[i] = i;pthread_create(&producers[i], NULL, producer_thread, &producer_ids[i]);}// 啟動消費者線程for (int i = 0; i < NUM_CONSUMERS; i++) {consumer_ids[i] = i;pthread_create(&consumers[i], NULL, consumer_thread, &consumer_ids[i]);}// 等待所有線程完成for (int i = 0; i < NUM_PRODUCERS; i++) {pthread_join(producers[i], NULL);}for (int i = 0; i < NUM_CONSUMERS; i++) {pthread_join(consumers[i], NULL);}// 顯示結果printf("Total produced: %d\n", atomic_load(&items_produced));printf("Total consumed: %d\n", atomic_load(&items_consumed));printf("Queue size: %zu\n", lockfree_queue_size(queue));// 清理lockfree_queue_destroy(queue);printf("=== 演示完成 ===\n\n");
}/*** 緩存友好數據結構演示示例*/
void demo_cache_friendly_structures() {printf("=== 緩存友好數據結構演示 ===\n");// 測試不同規模的數據size_t test_sizes[] = {1000, 10000, 100000, 1000000};int num_tests = sizeof(test_sizes) / sizeof(test_sizes[0]);printf("%-10s %-12s %-12s %-10s\n", "Elements", "SoA Time(s)", "AoS Time(s)", "Speedup");printf("------------------------------------------------\n");for (int i = 0; i < num_tests; i++) {performance_result_t result = test_performance(test_sizes[i]);double speedup = result.aos_time / result.soa_time;printf("%-10zu %-12.6f %-12.6f %-10.2fx\n", result.elements_processed,result.soa_time,result.aos_time,speedup);}printf("=== 演示完成 ===\n\n");
}/*** 安全字符串操作演示示例*/
void demo_secure_strings() {printf("=== 安全字符串操作演示 ===\n");// 創建安全字符串(啟用安全檢查)secure_string_t *str1 = secure_string_create(20, 1); // 安全模式secure_string_t *str2 = secure_string_from_cstr("Hello", 1);if (!str1 || !str2) {printf("Failed to create secure strings\n");return;}printf("Initial strings:\n");printf("str1: '%s' (length: %zu)\n", secure_string_cstr(str1), secure_string_length(str1));printf("str2: '%s' (length: %zu)\n", secure_string_cstr(str2), secure_string_length(str2));// 安全追加if (secure_string_append(str2, " World!") == 0) {printf("After append: '%s'\n", secure_string_cstr(str2));} else {printf("Append failed (security check)\n");}// 安全格式化if (secure_string_printf(str1, "Number: %d, String: %s", 42, "test") >= 0) {printf("Formatted string: '%s'\n", secure_string_cstr(str1));} else {printf("Format failed (security check)\n");}// 嘗試超出容量的操作(在安全模式下會失敗)printf("\nTesting security checks:\n");if (secure_string_append(str1, "This is a very long string that exceeds capacity") == -1) {printf("Security check prevented buffer overflow!\n");}// 字符串比較secure_string_t *str3 = secure_string_from_cstr("Hello World!", 1);printf("Comparison result: %d\n", secure_string_compare(str2, str3));// 清理secure_string_destroy(str1);secure_string_destroy(str2);secure_string_destroy(str3);printf("=== 演示完成 ===\n\n");
}// 綜合演示函數
void run_all_demos() {printf("C語言高級編程技巧演示\n");printf("=====================\n\n");// 運行所有演示demo_event_driven_architecture();demo_lockfree_queue();demo_cache_friendly_structures();demo_secure_strings();printf("所有演示完成!\n");
}
附錄:最佳實踐總結
編碼規范
1. 命名約定:使用清晰的命名,避免縮寫
2. 注釋風格:使用Doxygen風格注釋
3. 錯誤處理:始終檢查返回值
4. 內存管理:遵循RAII原則
5. 線程安全:明確標識線程安全函數
性能優化原則
- 先測量后優化:使用性能分析工具
- 算法優先:選擇合適的數據結構和算法
- 避免過早優化:保持代碼可讀性
- 緩存友好:考慮數據局部性
- 編譯器優化:合理使用編譯器優化選項
安全編碼原則
1. 輸入驗證:永遠不要信任外部輸入
2. 邊界檢查:防止緩沖區溢出
3. 最小權限:使用最小必要權限
4. 安全函數:使用安全的字符串函數
5. 代碼審查:定期進行安全代碼審查
這份完整的C語言高級編程技巧指南涵蓋了從基礎宏定義到復雜并發編程的所有重要方面,提供了豐富的代碼示例和最佳實踐,幫助開發者編寫高質量、高性能、安全的C代碼。