C语言篇:语法进阶

1. 引言

在掌握了 C 语言的基础语法之后,我们进入语法进阶阶段。这一阶段将帮助你深入理解 C 语言的核心机制,包括指针、内存管理、结构体、文件操作等高级主题。这些知识是编写高效、健壮、可维护 C 程序的关键。

2. 指针深入

2.1 指针与数组

指针和数组在 C 语言中关系密切。数组名在大多数表达式中会退化为指向首元素的指针。

c 复制代码
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;  // p 指向 arr[0]

// 以下两种写法等价
printf("%d\n", arr[2]);
printf("%d\n", *(p + 2));

2.2 指针算术

指针支持加减运算,移动的单位是所指向类型的大小。

c 复制代码
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;

p++;        // 指向 arr[1]
p += 2;     // 指向 arr[3]
printf("%d\n", *p);  // 输出 40

2.3 多级指针

指向指针的指针,常用于二维数组、字符串数组或需要在函数中修改指针本身。

c 复制代码
int value = 42;
int *p = &value;
int **pp = &p;

printf("%d\n", **pp);  // 输出 42

2.4 指针与函数

指针作为函数参数

通过指针传递,可以在函数内部修改调用者的变量。

c 复制代码
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 3, y = 5;
    swap(&x, &y);
    printf("x=%d, y=%d\n", x, y);  // x=5, y=3
    return 0;
}
函数指针

函数指针可以指向函数,用于回调、策略模式等场景。

c 复制代码
#include <stdio.h>

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int main() {
    int (*op)(int, int) = add;
    printf("%d\n", op(5, 3));  // 8

    op = sub;
    printf("%d\n", op(5, 3));  // 2
    return 0;
}

3. 动态内存管理

3.1 malloc 与 free

动态分配堆内存,使用完毕后必须释放,否则造成内存泄漏。

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = (int *)malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    for (int i = 0; i < 5; i++) {
        arr[i] = i * i;
    }

    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);
    return 0;
}

3.2 calloc 与 realloc

  • calloc:分配并初始化为 0。
  • realloc:调整已分配内存的大小。
c 复制代码
int *arr = (int *)calloc(5, sizeof(int));  // 全部初始化为 0

arr = (int *)realloc(arr, 10 * sizeof(int));  // 扩容到 10 个

3.3 常见内存错误

  • 忘记释放内存 → 内存泄漏。
  • 释放后继续使用 → 悬空指针。
  • 越界访问 → 未定义行为。
  • 重复释放 → 崩溃。

4. 结构体与联合体

4.1 结构体定义与使用

c 复制代码
#include <stdio.h>
#include <string.h>

struct Student {
    char name[50];
    int age;
    float score;
};

int main() {
    struct Student s1;
    strcpy(s1.name, "张三");
    s1.age = 20;
    s1.score = 88.5;

    printf("姓名: %s, 年龄: %d, 成绩: %.1f\n", s1.name, s1.age, s1.score);
    return 0;
}

4.2 typedef 简化类型名

c 复制代码
typedef struct {
    char name[50];
    int age;
} Person;

Person p = {"李四", 25};

4.3 结构体指针

c 复制代码
Person p = {"王五", 30};
Person *pp = &p;

printf("%s\n", pp->name);  // 使用 -> 访问成员

4.4 联合体

联合体所有成员共享同一块内存,大小取最大成员。

c 复制代码
union Data {
    int i;
    float f;
    char str[20];
};

union Data data;
data.i = 10;
printf("%d\n", data.i);

data.f = 3.14;
printf("%f\n", data.f);  // 此时 i 的值已被覆盖

5. 文件操作

5.1 打开与关闭文件

c 复制代码
#include <stdio.h>

int main() {
    FILE *fp = fopen("test.txt", "w");
    if (fp == NULL) {
        printf("文件打开失败\n");
        return 1;
    }

    fprintf(fp, "Hello, C Language!\n");
    fclose(fp);
    return 0;
}

5.2 读写文件

c 复制代码
// 写入
FILE *fp = fopen("data.txt", "w");
fprintf(fp, "姓名: %s, 年龄: %d\n", "赵六", 28);
fclose(fp);

// 读取
fp = fopen("data.txt", "r");
char buffer[100];
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
    printf("%s", buffer);
}
fclose(fp);

5.3 二进制文件

c 复制代码
typedef struct {
    int id;
    char name[50];
} Record;

// 写入二进制
Record r = {1, "Alice"};
FILE *fp = fopen("record.dat", "wb");
fwrite(&r, sizeof(Record), 1, fp);
fclose(fp);

// 读取二进制
Record r2;
fp = fopen("record.dat", "rb");
fread(&r2, sizeof(Record), 1, fp);
fclose(fp);
printf("ID: %d, Name: %s\n", r2.id, r2.name);

6. 预处理指令

6.1 宏定义

c 复制代码
#define PI 3.14159
#define SQUARE(x) ((x) * (x))

printf("%.2f\n", PI);          // 3.14
printf("%d\n", SQUARE(5));     // 25

6.2 条件编译

c 复制代码
#define DEBUG

#ifdef DEBUG
    printf("调试模式\n");
#else
    printf("发布模式\n");
#endif

6.3 头文件保护

c 复制代码
#ifndef MY_HEADER_H
#define MY_HEADER_H

// 头文件内容

#endif

7. 总结

语法进阶是 C 语言学习的分水岭。掌握指针、动态内存、结构体和文件操作后,你就具备了编写真实项目的能力。建议通过大量编码练习巩固这些概念,并注意内存安全与代码规范。

相关推荐
Doubbbbbbble云2 小时前
基于流处理框架的实时算法实现策略4
算法
2601_962885722 小时前
如何用 Python 计算 ROC 变动率指标做动量分析?
开发语言·python·算法
Logic1012 小时前
C语言/数据结构动态规划题解:爬楼梯(含坏台阶)——避开障碍物的路径计数
c语言·数据结构·动态规划·时间复杂度·空间复杂度·算法题·爬楼梯
胡家伟++2 小时前
我用 48 轮 AI 思维链做了一次研究战略推演:从“验证信号危机“到“验证栈“统一框架
人工智能·算法
山下梅子酒2252 小时前
洛谷-入门-B2081
c语言
朝朝辞暮i2 小时前
C++ 第 39 章: 阶段性总复习——类、对象、构造、继承、this、指针与智能指针
开发语言·c++·算法·ros2
wuminyu3 小时前
Virtual Thread重投递至ForkJoinPool任务队列过程解析
java·linux·c语言·jvm·c++
垆边人似月.3 小时前
华为题:污染水域
算法
All for pursuit.3 小时前
【回溯-6】79.单词搜索
数据结构·c++·算法·leetcode