1. 预processing指令
1.1 what is 预processing指令
预processing指令 is in 编译之 before 由预processing器processing 指令, 它们以井号 (#) 开头. 预processing指令用于宏定义, 条件编译, filepackage含etc.operation.
1.2 common 预processing指令
#define: 定义宏#include: package含头file#ifdef,#ifndef,#endif: 条件编译#if,#elif,#else: 条件编译#undef: 取消宏定义#pragma: 编译器specific 指令#error: 产生errorinformation#warning: 产生warninginformation
1.3 宏定义
宏定义用于creation符号常量 or 宏function, improvingcode readable 性 and 可maintenance性.
// 定义符号常量
#define PI 3.14159
#define MAX_SIZE 100
// 定义宏function
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
int main() {
int a = 10, b = 20;
printf("PI = %f\n", PI);
printf("MIN(%d, %d) = %d\n", a, b, MIN(a, b));
printf("MAX(%d, %d) = %d\n", a, b, MAX(a, b));
printf("SQUARE(%d) = %d\n", a, SQUARE(a));
return 0;
}
1.4 条件编译
条件编译用于根据条件选择性地编译code, 常用于跨平台Development and debug.
#include <stdio.h>
#define DEBUG 1
#define PLATFORM "Windows"
int main() {
printf("Hello, World!\n");
#ifdef DEBUG
printf("Debug mode is enabled\n");
#endif
#ifndef NDEBUG
printf("Not in release mode\n");
#endif
#if defined(PLATFORM) && PLATFORM == "Windows"
printf("Running on Windows\n");
#elif defined(PLATFORM) && PLATFORM == "Linux"
printf("Running on Linux\n");
#else
printf("Running on unknown platform\n");
#endif
return 0;
}
1.5 filepackage含
filepackage含用于将otherfile in 容package含 to 当 before filein, 通常用于package含头file.
// package含标准library头file
#include <stdio.h>
#include <stdlib.h>
// package含user定义 头file
#include "myheader.h"
int main() {
// code
return 0;
}
2. 位运算
2.1 位运算符
位运算符用于 for 整数 二进制位foroperation, including按位 and , 按位 or , 按位异 or , 按位取反, left 移 and right 移etc..
| 运算符 | describes | example |
|---|---|---|
| & | 按位 and | 10 & 3 = 2 (1010 & 0011 = 0010) |
| | | 按位 or | 10 | 3 = 11 (1010 | 0011 = 1011) |
| ^ | 按位异 or | 10 ^ 3 = 9 (1010 ^ 0011 = 1001) |
| ~ | 按位取反 | ~10 = -11 (按位取反1010得 to 0101, 再按补码规则得 to -11) |
| << | left 移 | 10 << 2 = 40 (1010 << 2 = 101000) |
| >> | right 移 | 10 >> 2 = 2 (1010 >> 2 = 10) |
2.2 位运算 application
位运算 in 以 under 场景in非常 has 用:
- 位掩码: 用于标志位operation
- 位字段: 用于节省memory
- 位operationoptimization: improvingcodeefficiency
- encryption and 哈希algorithms: using位运算fordataprocessing
- 硬件programming: and 硬件寄存器for交互
// 位掩码example
#include <stdio.h>
// 定义标志位
#define FLAG_A 0x01 // 0001
#define FLAG_B 0x02 // 0010
#define FLAG_C 0x04 // 0100
#define FLAG_D 0x08 // 1000
int main() {
int flags = 0;
// 设置标志位
flags |= FLAG_A;
flags |= FLAG_C;
printf("Flags: 0x%x\n", flags); // 输出: Flags: 0x5
// check标志位
if (flags & FLAG_A) {
printf("Flag A is set\n");
}
if (flags & FLAG_B) {
printf("Flag B is set\n");
} else {
printf("Flag B is not set\n");
}
// 清除标志位
flags &= ~FLAG_A;
printf("Flags after clearing A: 0x%x\n", flags); // 输出: Flags after clearing A: 0x4
return 0;
}
3. many fileprogramming
3.1 for whatusing many fileprogramming
in big 型projectin, 将code分散 to many 个filein可以improvingcode 可maintenance性, readable 性 and reusability. many fileprogramming 优点including:
- module化: 将functions相关 code组织 in 一起
- 可maintenance性: 便于modify and debugspecificfunctions
- reusability: 可以 in many 个projectinusing相同 module
- 编译速度: 只需要重 new 编译modify过 file
- 团队协作: many 个Development者可以同时工作 in 不同 file on
3.2 many fileprogramming basicstructure
一个典型 Clanguageproject通常package含以 under class型 file:
- .h file (头file) : package含function声明, 宏定义, class型定义etc.
- .c file (sourcesfile) : package含functionimplementation
3.2.1 头file
// mymath.h #ifndef MYMATH_H #define MYMATH_H // function声明 double add(double a, double b); double subtract(double a, double b); double multiply(double a, double b); double divide(double a, double b); #endif // MYMATH_H
3.2.2 sourcesfile
// mymath.c
#include "mymath.h"
// functionimplementation
double add(double a, double b) {
return a + b;
}
double subtract(double a, double b) {
return a - b;
}
double multiply(double a, double b) {
return a * b;
}
double divide(double a, double b) {
if (b != 0) {
return a / b;
}
return 0; // 简化processing, practical应processing除零error
}
3.2.3 主file
// main.c
#include <stdio.h>
#include "mymath.h"
int main() {
double a = 10.0, b = 5.0;
printf("%f + %f = %f\n", a, b, add(a, b));
printf("%f - %f = %f\n", a, b, subtract(a, b));
printf("%f * %f = %f\n", a, b, multiply(a, b));
printf("%f / %f = %f\n", a, b, divide(a, b));
return 0;
}
3.3 编译 and 链接 many fileproject
for 于 many fileproject, 可以using以 under commands编译 and 链接:
// 分别编译每个sourcesfile gcc -c main.c gcc -c mymath.c // 链接目标file gcc main.o mymath.o -o program // or 者一步completion编译 and 链接 gcc main.c mymath.c -o program
4. C标准library
4.1 常用 标准library头file
<stdio.h>: 标准输入输出function<stdlib.h>: commontoolfunction (memory分配, 随机数etc.)<string.h>: stringprocessingfunction<math.h>: 数学function<time.h>: 时间 and 日期function<ctype.h>: 字符processingfunction<stdint.h>: 整数class型定义<stdbool.h>: booleanclass型定义<stdarg.h>: 可变parameterprocessing<assert.h>: assertionfunction
4.2 标准libraryfunctionexample
// 标准libraryfunctionexample
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
int main() {
// stdio.h
printf("Hello, World!\n");
// stdlib.h
int *ptr = (int *)malloc(5 * sizeof(int));
if (ptr != NULL) {
for (int i = 0; i < 5; i++) {
ptr[i] = i + 1;
}
free(ptr);
}
// string.h
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);
printf("strcat: %s\n", str1);
// math.h
double x = 2.0;
printf("sqrt(%.2f) = %.2f\n", x, sqrt(x));
printf("pow(%.2f, 3) = %.2f\n", x, pow(x, 3));
// time.h
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
printf("Current time: %02d:%02d:%02d\n",
tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
// ctype.h
char c = 'A';
printf("%c is uppercase: %d\n", c, isupper(c));
printf("%c to lowercase: %c\n", c, tolower(c));
return 0;
}
5. advanceddatastructure
5.1 链表 advancedimplementation
链表 is a常用 动态datastructure, in Clanguagein可以throughstructure体 and 指针implementation.
// 双向链表implementation
#include <stdio.h>
#include <stdlib.h>
// 双向链表nodestructure体
typedef struct Node {
int data;
struct Node *prev;
struct Node *next;
} Node;
// creation new node
Node *createNode(int data) {
Node *newNode = (Node *)malloc(sizeof(Node));
if (newNode != NULL) {
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
}
return newNode;
}
// in 链表末尾添加node
void append(Node **head, int data) {
Node *newNode = createNode(data);
if (newNode == NULL) {
return;
}
if (*head == NULL) {
*head = newNode;
return;
}
Node *temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
// 显示链表
void display(Node *head) {
if (head == NULL) {
printf("链表 for 空\n");
return;
}
Node *temp = head;
printf("链表 in 容: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
// 释放链表
void freeList(Node *head) {
Node *temp;
while (head != NULL) {
temp = head;
head = head->next;
free(temp);
}
}
int main() {
Node *head = NULL;
// 添加node
append(&head, 10);
append(&head, 20);
append(&head, 30);
append(&head, 40);
append(&head, 50);
// 显示链表
display(head);
// 释放链表
freeList(head);
return 0;
}
5.2 treestructure
tree is a important 非线性datastructure, in Clanguagein可以throughstructure体 and 指针implementation.
// 二叉treeimplementation
#include <stdio.h>
#include <stdlib.h>
// 二叉treenodestructure体
typedef struct TreeNode {
int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
// creation new node
TreeNode *createTreeNode(int data) {
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
if (newNode != NULL) {
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
// 插入node (二叉搜索tree)
TreeNode *insert(TreeNode *root, int data) {
if (root == NULL) {
return createTreeNode(data);
}
if (data < root->data) {
root->left = insert(root->left, data);
} else if (data > root->data) {
root->right = insert(root->right, data);
}
return root;
}
// in序遍历
void inorderTraversal(TreeNode *root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d ", root->data);
inorderTraversal(root->right);
}
}
// 释放tree
void freeTree(TreeNode *root) {
if (root != NULL) {
freeTree(root->left);
freeTree(root->right);
free(root);
}
}
int main() {
TreeNode *root = NULL;
// 插入node
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 70);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 60);
root = insert(root, 80);
// in序遍历
printf("in序遍历: ");
inorderTraversal(root);
printf("\n");
// 释放tree
freeTree(root);
return 0;
}
6. performanceoptimizationtechniques
6.1 codeoptimization
- reducingfunction调用开销: for 于频繁调用 small function, 可以考虑using in 联function (inline)
- reducingmemory访问: using局部variable, 避免频繁访问全局variable
- 循环optimization: reducing循环 in 计算, using循环unfoldtechniques
- 条件branchoptimization: 将最可能 条件放 in before 面, using查表代替 complex 条件判断
- algorithmsoptimization: 选择时间complexity更 low algorithms
6.2 memoryoptimization
- reducingmemory分配次数: 预分配足够 memory, 避免频繁 动态memory分配
- using合适 datastructure: 选择空间complexity low datastructure
- memory for 齐: 合理安排structure体成员 顺序, reducingmemory padding
- memory池: for 于频繁分配 and 释放 small memory, usingmemory池
6.3 编译器optimization
big many 数现代编译器都providing了 many 种optimization选项, 可以根据需要选择合适 optimization级别:
// 编译optimization选项 gcc -O0 -o program source.c // 无optimization gcc -O1 -o program source.c // basicoptimization gcc -O2 -o program source.c // 更 many optimization gcc -O3 -o program source.c // 最advancedoptimization gcc -Os -o program source.c // optimizationcode big small
6.4 performanceanalysis
usingperformanceanalysistool可以helping识别codein performance瓶颈:
- gprof: GNU performanceanalysistool
- Valgrind: memoryanalysis and performanceanalysistool
- perf: Linux performance计数器tool
实践case: many fileprojectDevelopment
writing一个Clanguage many fileproject, implementation一个 simple 学生informationmanagementsystem, package含以 under functions:
requirementsanalysis
- 添加学生information
- 显示学生information
- 根据学号find学生
- 根据成绩sort学生
- 保存学生information to file
- from file加载学生information
projectstructure
student.h: 学生structure体定义 and function声明student.c: 学生相关functionimplementationdatabase.h: datalibraryoperationfunction声明database.c: datalibraryoperationfunctionimplementationmain.c: 主function
referencecode
// student.h
#ifndef STUDENT_H
#define STUDENT_H
#define MAX_NAME_LEN 50
// 学生structure体
typedef struct {
int id;
char name[MAX_NAME_LEN];
float score;
} Student;
// 学生相关function
void initStudent(Student *student, int id, const char *name, float score);
void printStudent(const Student *student);
#endif // STUDENT_H
// student.c
#include <stdio.h>
#include "student.h"
void initStudent(Student *student, int id, const char *name, float score) {
student->id = id;
snprintf(student->name, MAX_NAME_LEN, "%s", name);
student->score = score;
}
void printStudent(const Student *student) {
printf("ID: %d, Name: %s, Score: %.2f\n",
student->id, student->name, student->score);
}
// database.h
#ifndef DATABASE_H
#define DATABASE_H
#include "student.h"
#define MAX_STUDENTS 100
// datalibrarystructure体
typedef struct {
Student students[MAX_STUDENTS];
int count;
} Database;
// datalibraryoperationfunction
void initDatabase(Database *db);
int addStudent(Database *db, const Student *student);
void printAllStudents(const Database *db);
Student *findStudentById(Database *db, int id);
void sortStudentsByScore(Database *db);
int saveDatabase(const Database *db, const char *filename);
int loadDatabase(Database *db, const char *filename);
#endif // DATABASE_H
// database.c
#include <stdio.h>
#include "database.h"
void initDatabase(Database *db) {
db->count = 0;
}
int addStudent(Database *db, const Student *student) {
if (db->count >= MAX_STUDENTS) {
return 0; // datalibrary已满
}
db->students[db->count] = *student;
db->count++;
return 1; // 添加成功
}
void printAllStudents(const Database *db) {
printf("\n=== Student List ===\n");
for (int i = 0; i < db->count; i++) {
printStudent(&db->students[i]);
}
printf("====================\n");
}
Student *findStudentById(Database *db, int id) {
for (int i = 0; i < db->count; i++) {
if (db->students[i].id == id) {
return &db->students[i];
}
}
return NULL; // 未找 to
}
void sortStudentsByScore(Database *db) {
for (int i = 0; i < db->count - 1; i++) {
for (int j = 0; j < db->count - i - 1; j++) {
if (db->students[j].score < db->students[j + 1].score) {
// 交换
Student temp = db->students[j];
db->students[j] = db->students[j + 1];
db->students[j + 1] = temp;
}
}
}
}
int saveDatabase(const Database *db, const char *filename) {
FILE *file = fopen(filename, "wb");
if (file == NULL) {
return 0; // file打开失败
}
fwrite(&db->count, sizeof(int), 1, file);
fwrite(db->students, sizeof(Student), db->count, file);
fclose(file);
return 1; // 保存成功
}
int loadDatabase(Database *db, const char *filename) {
FILE *file = fopen(filename, "rb");
if (file == NULL) {
return 0; // file打开失败
}
fread(&db->count, sizeof(int), 1, file);
if (db->count > MAX_STUDENTS) {
db->count = MAX_STUDENTS;
}
fread(db->students, sizeof(Student), db->count, file);
fclose(file);
return 1; // 加载成功
}
// main.c
#include <stdio.h>
#include "student.h"
#include "database.h"
int main() {
Database db;
initDatabase(&db);
// 添加学生
Student s1, s2, s3;
initStudent(&s1, 1, "Alice", 95.5);
initStudent(&s2, 2, "Bob", 88.0);
initStudent(&s3, 3, "Charlie", 92.5);
addStudent(&db, &s1);
addStudent(&db, &s2);
addStudent(&db, &s3);
// 显示所 has 学生
printAllStudents(&db);
// find学生
int searchId = 2;
Student *found = findStudentById(&db, searchId);
if (found != NULL) {
printf("\nFound student with ID %d: ", searchId);
printStudent(found);
} else {
printf("\nStudent with ID %d not found\n", searchId);
}
// sort学生
sortStudentsByScore(&db);
printf("\nStudents sorted by score: ");
printAllStudents(&db);
// 保存 to file
const char *filename = "students.dat";
if (saveDatabase(&db, filename)) {
printf("\nDatabase saved to %s\n", filename);
} else {
printf("\nFailed to save database\n");
}
// 加载 from file
Database db2;
initDatabase(&db2);
if (loadDatabase(&db2, filename)) {
printf("\nDatabase loaded from %s\n", filename);
printAllStudents(&db2);
} else {
printf("\nFailed to load database\n");
}
return 0;
}
互动练习
练习1: writing一个C程序, using位运算implementation一个 simple 位graph (bitmap) datastructure, 用于store整数collection.
要求: implementation添加, delete, find and 清空operation.
练习2: writing一个C程序, using预processing指令implementation一个跨平台 logsystem.
要求: in 不同平台 on using不同 log输出方式, support不同 log级别.
练习3: writing一个C程序, implementation一个 simple 哈希表datastructure.
要求: implementation插入, find and deleteoperation, processing哈希conflict.
练习4: writing一个C程序, usingmemory池techniquesoptimization频繁 memory分配 and 释放operation.
要求: implementationmemory池 初始化, 分配, 释放 and 销毁operation.