核心内容摘要
《QGIS快速入门ä¸�应用基础》135:æº�选项å�¡ï¼šå›¾å±‚基本信æ�¯ï¼ˆCRS/æ ¼å¼�/路径)
C语言核心知识
分函数、文件、内存管理、高级特性
函数
1 函数基础//
函数声明原型 int add(int a, int b); // 告诉编译器函数存在 void print_info(void); // 无参数 //
函数定义 int add(int a, int b) { return a b; // 返回值 } //
函数调用 int result add(10,
; // 调用函数 //
无返回值函数 void print_message(char *msg) { printf(%s\n, msg); // 没有return语句 }
2 参数传递方式//
值传递默认 void change_value(int x) { x 100; // 只修改副本 } //
地址传递指针 void change_real(int *p) { *p 100; // 修改原变量 } //
数组传递 void print_array(int arr[], int n) { // arr实际是指针 for(int i0; in; i) { printf(%d , arr[i]); } }
3 递归函数// 阶乘n! n * (n-
! int factorial(int n) { if(n
return 1; // 终止条件 return n * factorial(n-
; // 递归调用 } // 斐波那契数列 int fibonacci(int n) { if(n
return n; return fibonacci(n-
fibonacci(n-
; }
文件操作
1 文件打开关闭#include stdio.h FILE *fp; // 打开文件 fp fopen(file.txt, r); // 只读 if(fp NULL) { perror(打开失败); return; } // 文件模式 // r只读文件必须存在 // w只写创建或清空 // a追加创建或追加 // r读写文件必须存在 // w读写创建或清空 // a读写创建或追加 // b二进制模式如rb // 关闭文件 fclose(fp); fp NULL; // 避免野指针
2 文件读写函数//
字符读写 int ch; ch fgetc(fp); // 读取一个字符 fputc(A, fp); // 写入一个字符 //
字符串读写 char str[100]; fgets(str, 100, fp); // 读取一行最多99字符 fputs(Hello, fp); // 写入字符串 //
格式化读写 int num; float value; fscanf(fp, %d %f, num, value); // 格式化读取 fprintf(fp, Number: %d\n, num); // 格式化写入 //
块读写 struct Data data; fread(data, sizeof(struct Data), 1, fp); // 读取一个结构体 fwrite(data, sizeof(struct Data), 1, fp); // 写入一个结构体
3 文件定位// 获取当前位置 long pos ftell(fp); // 移动到开头 rewind(fp); // 等价于 fseek(fp, 0, SEEK_SET) // 移动文件指针 fseek(fp, 10, SEEK_SET); // 从开头移动10字节 fseek(fp, -5, SEEK_CUR); // 从当前位置回退5字节 fseek(fp, 0, SEEK_END); // 移动到文件末尾 // 检测文件结尾 while(!feof(fp)) { // 处理文件 } // 错误检测 if(ferror(fp)) { printf(文件错误\n); } clearerr(fp); // 清除错误标志
动态内存管理
1 内存分配函数#include stdlib.h //
malloc - 分配内存不初始化 int *p (int*)malloc(10 * sizeof(int)); if(p NULL) { // 分配失败处理 } //
calloc - 分配并清零 int *arr (int*)calloc(10, sizeof(int)); // 全部初始化为0 //
realloc - 重新分配 arr (int*)realloc(arr, 20 * sizeof(int)); // 扩大或缩小 //
free - 释放内存 free(p); free(arr); p NULL; // 避免悬空指针 arr NULL;
2 内存操作函数#include string.h //
memset - 内存设置 int buffer[100]; memset(buffer, 0, sizeof(buffer)); // 全部设为0 memset(buffer, 0xFF, sizeof(buffer)); // 全部设为0xFF //
memcpy - 内存复制 int src[5] {1,2,3,4,5}; int dest[5]; memcpy(dest, src, 5 * sizeof(int)); //
memmove - 安全内存移动处理重叠 memmove(dest, src, 5 * sizeof(int)); //
memcmp - 内存比较 if(memcmp(src, dest, 5 * sizeof(int))
{ printf(内存块相同\n); }
3 内存管理最佳实践//
总是检查返回值 void* safe_malloc(size_t size) { void *ptr malloc(size); if(!ptr) { fprintf(stderr, 内存分配失败\n); exit(EXIT_FAILURE); } return ptr; } //
避免内存泄漏 void process_data() { char *buffer malloc(
; if(!buffer) return; // 使用buffer... free(buffer); // 必须释放 buffer NULL; } //
防止重复释放 void safe_free(void **ptr) { if(ptr *ptr) { free(*ptr); *ptr NULL; // 设为NULL避免重复释放 } }
预处理器高级特性
1 条件编译进阶//
检测编译器 #ifdef __GNUC__ // GCC编译器特有代码 #endif #ifdef _MSC_VER // MSVC编译器特有代码 #endif //
检测平台 #ifdef __linux__ #define PLATFORM Linux #elif defined(_WIN
#define PLATFORM Windows #elif defined(__APPLE__) #define PLATFORM macOS #else #define PLATFORM Unknown #endif //
版本控制 #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #if VERSION_MAJOR 1 // 版本1以上的功能 #endif //
调试模式 #ifdef DEBUG #define DEBUG_PRINT(fmt, ...) \ fprintf(stderr, [%s:%d] fmt, __FILE__, __LINE__, ##__VA_ARGS__) #else #define DEBUG_PRINT(fmt, ...) #endif
2 宏的高级用法//
字符串化运算符 # #define STRINGIFY(x) #x char *str STRINGIFY(hello); // 变成 hello //
连接运算符 ## #define CONCAT(a,b) a##b int CONCAT(var,
10; // 变成 int var1 10; //
可变参数宏 #define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__) LOG(值: %d, 名称: %s\n, value, name); //
多语句宏使用do-while #define SWAP(a,b) do { \ typeof(a) temp a; \ a b; \ b temp; \ } while(
//
保护宏 #define MIN(a,b) ((a) (b) ? (a) : (b)) #undef MIN // 取消定义 #define MIN(a,b) ({ \ typeof(a) _a (a); \ typeof(b) _b (b); \ _a _b ? _a : _b; \ }) // 重新定义更安全
位字段与位运算
1 位字段位域// 定义位字段结构体 struct Flags { unsigned int is_readonly : 1; // 1位 unsigned int is_hidden : 1; // 1位 unsigned int is_system : 1; // 1位 unsigned int file_type : 3; // 3位
unsigned int reserved : 26; // 26位 }; // 使用位字段 struct Flags file_flags; file_flags.is_readonly 1; file_flags.is_hidden 0; file_flags.file_type 5; // 只能存储
的值 // 位字段大小 printf(位字段大小: %lu字节\n, sizeof(struct Flags));
2 位运算实用技巧//
设置位 #define SET_BIT(var, bit) ((var) | (1 (bit))) #define CLEAR_BIT(var, bit) ((var) ~(1 (bit))) #define TOGGLE_BIT(var, bit) ((var) ^ (1 (bit))) #define CHECK_BIT(var, bit) ((var) (1 (bit))) //
交换值不使用临时变量 void swap(int *a, int *b) { *a ^ *b; *b ^ *a; *a ^ *b; } //
判断奇偶 int is_odd(int n) { return n 1; // 返回1表示奇数0表示偶数 } //
乘以2的n次方 int multiply_power_of_2(int x, int n) { return x n; // x * 2^n } //
除以2的n次方 int divide_power_of_2(int x, int n) { return x n; // x / 2^n } //
取模对2的幂 int mod_power_of_2(int x, int n) { return x ((1 n) -
; // x % (2^n) }
错误处理
1 errno和错误处理#include errno.h #include string.h //
使用errno FILE *fp fopen(nonexistent.txt, r); if(fp NULL) { printf(错误号: %d\n, errno); // 错误代码 printf(错误信息: %s\n, strerror(errno)); // 错误描述 perror(fopen失败); // 自动添加错误信息 } //
常见errno值 // ENOENT: 文件不存在 // EACCES: 权限不足 // ENOMEM: 内存不足 // EINVAL: 无效参数 //
清除errno errno 0; // 清除之前的错误 //
错误处理宏 #define CHECK_ERROR(expr) \ do { \ errno 0; \ if(!(expr)) { \ fprintf(stderr, 错误[%s:%d]: %s\n, \ __FILE__, __LINE__, strerror(errno)); \ exit(EXIT_FAILURE); \ } \ } while(
0)
2 断言#include assert.h //
基本断言 void process(int *ptr, int size) { assert(ptr ! NULL); // 检查空指针 assert(size
; // 检查有效大小 // 处理逻辑 } //
调试时启用发布时禁用 // 编译时加 -DNDEBUG 禁用断言 //
自定义断言宏 #ifndef NDEBUG #define CUSTOM_ASSERT(expr, msg) \ do { \ if(!(expr)) { \ fprintf(stderr, 断言失败[%s:%d]: %s\n, \ __FILE__, __LINE__, msg); \ abort(); \ } \ } while(
#else #define CUSTOM_ASSERT(expr, msg) ((void)
#endif
编译与链接
1 编译过程源文件(.c) → 预处理(.i) → 编译(.s) → 汇编(.o) → 链接(可执行文件)
2 存储类别//
自动存储期auto- 默认 void func() { auto int x; // 等同于 int x; } // 函数结束自动销毁 //
静态存储期static // - 静态局部变量函数内保持值 // - 静态全局变量文件内可见 // - 静态函数文件内可见 //
线程存储期C11 _Thread_local int thread_var; // 每个线程有自己的副本 //
动态存储期malloc/free int *p malloc(sizeof(int)); // 手动管理生命周期
3 类型限定符//
const - 只读 const int MAX 100; // 常量 //
volatile - 易变 volatile int *hw_reg; // 硬件寄存器 //
restrict - 限制别名C99 void copy(int *restrict dest, const int *restrict src, int n); //
_Atomic - 原子类型C11 #include stdatomic.h _Atomic int atomic_counter; // 线程安全的计数器
C标准库重要函数
1 数学函数#include math.h double result; result sqrt(
16.
; // 平方根:
0 result pow(
0,
3.
; // 幂运算:
0 result sin(
14159/
; // 正弦:
0 result log(
10.
; // 自然对数 result fabs(-
5.
; // 绝对值:
5 result ceil(
3.
; // 向上取整:
0 result floor(
3.
; // 向下取整:
0 result round(
3.
; // 四舍五入:
4.
0