程序设计的本质是对现实问题的抽象和逻辑表达。C语言作为结构化编程语言的典范,其控制结构构成了程序逻辑的骨架。
三大基本结构构成所有程序的逻辑基础:
顺序结构:代码的自然执行顺序
选择结构:if/else语句实现分支判断
循环结构:for/while实现重复操作
if (condition) {
// 代码块
}
编译后的汇编代码示例:
cmp eax, 10 ; 比较操作
jle .L2 ; 条件跳转
; if代码块
.L2:
; 后续代码
switch (表达式) {
case 常量1:
// 代码
break;
case 常量2:
// 代码
break;
default:
// 默认处理
}
编译器处理策略:
跳转表实现(case值连续时)
二分查找优化(case值分散时)
for (初始化; 条件; 增量) {
// 循环体
}
等效while形式:
初始化;
while (条件) {
// 循环体
增量;
}
原始循环:
for (int i = 0; i < 100; i++) {
sum += array[i];
}
手动展开:
for (int i = 0; i < 100; i += 4) {
sum += array[i];
sum += array[i+1];
sum += array[i+2];
sum += array[i+3];
}
int func() {
FILE *fp = fopen("file.txt", "r");
if (!fp) goto ERROR;
if (process_failed) goto CLOSE_FILE;
CLOSE_FILE:
fclose(fp);
ERROR:
return err_code;
}
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (j % 16 == 0)
goto CACHE_OPTIMIZED;
continue;
CACHE_OPTIMIZED:
// 缓存优化计算
}
}
enum State { START, READING, PROCESSING, END };
enum State current = START;
while (1) {
switch (current) {
case START:
if (get_input()) current = READING;
break;
case READING:
if (buffer_full()) current = PROCESSING;
break;
case PROCESSING:
process_data();
if (eof_reached()) current = END;
else current = START;
break;
case END:
goto EXIT;
}
}
EXIT:
// 清理资源
// 快速排序优化版本
void quicksort_opt(int arr[], int low, int high) {
while (low < high) {
int pi = partition(arr, low, high);
if (pi - low < high - pi) {
quicksort_opt(arr, low, pi - 1);
low = pi + 1;
} else {
quicksort_opt(arr, pi + 1, high);
high = pi - 1;
}
}
}
if (a > 5)
if (b < 3)
printf("Case 1");
else
printf("Case 2");
正确写法:
if (a > 5) {
if (b < 3) {
printf("Case 1");
}
} else {
printf("Case 2");
}
// 正确写法
for (int i = 0; i < 10; i++) {
arr[i] = 0;
}
#define print_type(x) _Generic((x), \
int: "integer", \
float: "float", \
default: "other")
int arr[] = {1,2,3,4,5};
foreach (int i : arr) {
printf("%d ", i);
}
#define unlikely(x) __builtin_expect(!!(x), 0)
if (unlikely(unlikely_condition)) {
// 处理罕见情况
}
int len = strlen(s);
for (int i = 0; i < len; i++) {
// 处理字符
}
单一出口原则
圈复杂度控制(建议不超过15)
防御性编程
可测试性设计
void schedule(void) {
struct task_struct *prev, *next;
prev = current;
next = pick_next_task(rq);
if (likely(prev != next)) {
context_switch(rq, prev, next);
} else {
__schedule(false);
}
if (need_resched())
preempt_schedule_irq();
}
掌握控制结构需要结合:
编译原理
计算机体系结构
算法复杂度分析
软件工程实践