c语言程序设计知识点总结

99ANYc3cd6
预计阅读时长 22 分钟
位置: 首页 C语言 正文

C语言程序设计核心知识点总结

C语言是结构化、过程式的编程语言,以其高效、灵活和底层操作能力强而著称,掌握C语言需要理解其语法、思想以及与计算机底层的联系。


第一部分:基础入门

C语言概述

  • 特点:高效、灵活、底层、可移植、结构化。
  • 程序结构
    • #include <stdio.h>:包含标准输入输出库。
    • int main():程序的入口函数,程序从这里开始执行。
    • 代码块,用于组织语句。
    • return 0;:表示程序正常结束。
  • 编译与执行:源代码 (.c) -> 预处理 -> 编译 -> 汇编 -> 链接 -> 可执行文件 (.exe 或无后缀)。

数据类型

  • 基本数据类型
    • int:整型,用于存储整数。
    • char:字符型,用于存储单个字符(本质是1字节整数)。
    • float:单精度浮点型,用于存储实数(约7位有效数字)。
    • double:双精度浮点型,用于存储实数(约15位有效数字)。
  • 修饰符
    • short, long, long long:改变整型的范围。
    • signed, unsigned:指定整型是否包含负数。
  • 类型大小:使用 sizeof() 运算符可以获取数据类型或变量所占的字节数。

常量与变量

  • 变量
    • 定义:数据类型 变量名; (e.g., int age;)
    • 初始化:数据类型 变量名 = 初始值; (e.g., int age = 25;)
    • 命名规则:字母、数字、下划线组成,不能以数字开头,不能是关键字。
  • 常量
    • 字面量常量:10, 'A', 14
    • const修饰符:const int MAX = 100; (定义一个只读变量)
    • #define 宏定义:#define PI 3.14 (在预处理阶段进行文本替换)

运算符

  • 算术运算符:, , , , (取模), (自增), (自减)。

    注意: 对整数运算会截断小数部分; 只能用于整数。

  • 关系运算符>, <, >=, <=, , ,结果为 1 (真) 或 0 (假)。
  • 逻辑运算符&& (与), (或), (非),用于组合多个条件。
  • 位运算符& (按位与), (按位或), ^ (按位异或), (按位取反), << (左移), >> (右移)。
  • 赋值运算符:, , , , 等。
  • 其他运算符
    • sizeof:获取数据类型大小。
    • &:取地址运算符。
    • 指针解引用运算符。
    • 条件运算符(三元运算符)。

输入与输出

  • printf():格式化输出。
    • 格式控制符:%d (int), %c (char), %f (float), %lf (double), %s (字符串), %p (地址)。
    • 转义字符:\n (换行), \t (制表符), \0 (字符串结束符)。
  • scanf():格式化输入。
    • 关键:必须为变量提供地址,使用 & 符号 (e.g., scanf("%d", &age);)。
    • 注意:scanf 读取字符串时,遇到空格会停止,且不会自动吸收换行符。

第二部分:流程控制

选择结构

  • if-else 语句:根据条件执行不同的代码块。
    if (条件) {
        // 代码块1
    } else if (条件) {
        // 代码块2
    } else {
        // 代码块3
    }
  • switch 语句:用于多分支选择,基于一个表达式的值。
    switch (表达式) {
        case 常量1: ...; break;
        case 常量2: ...; break;
        default: ...;
    }
    • break 关键字用于跳出 switchdefault 处理所有未匹配的情况。

循环结构

  • while 循环:先判断条件,条件为真则执行循环体。
    while (条件) {
        // 循环体
    }
  • do-while 循环:先执行一次循环体,再判断条件。
    do {
        // 循环体
    } while (条件);
  • for 循环:最常用的循环,通常用于明确知道循环次数的场景。
    for (初始化表达式; 条件表达式; 更新表达式) {
        // 循环体
    }
  • 循环控制
    • break:立即终止整个循环。
    • continue:跳过本次循环的剩余语句,直接进入下一次循环。

第三部分:函数

函数基础

  • 定义返回类型 函数名(参数列表) { 函数体; }
    • 返回类型:函数返回值的类型,若无返回值则为 void
    • 参数列表:传递给函数的数据,可以没有参数或多个参数。
  • 声明返回类型 函数名(参数列表); (函数原型)

    作用:告诉编译器函数的存在及其类型,通常放在文件开头。

  • 调用函数名(实参列表);
    • 值传递:C语言中,函数参数默认是值传递,即传递的是实参的副本,在函数内部修改形参不会影响实参。
  • 递归:函数直接或间接地调用自身,必须有明确的递归终止条件。

作用域与生命周期

  • 局部变量:在函数内部定义,作用域仅限于该函数,生命周期从函数调用开始到函数结束。
  • 全局变量:在所有函数外部定义,作用域为整个程序,生命周期贯穿整个程序运行期间。
    • 注意:应尽量避免使用全局变量,因为它会增加程序的耦合度,难以维护。

第四部分:数组与字符串

一维数组

  • 定义数据类型 数组名[数组大小]; (e.g., int scores[10];)
  • 初始化
    • int arr[5] = {1, 2, 3, 4, 5};
    • int arr[] = {1, 2, 3}; // 编译器自动确定大小为3
  • 访问:通过下标,从 0 开始。arr[0] 访问第一个元素。
  • 内存布局:数组在内存中是连续存储的。

字符串

  • 本质:字符数组,以 \0 (空字符) 作为结尾。
  • 表示方式
    • 字符数组:char str[] = "Hello";char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};
    • 字符串指针:char *str = "Hello"; // 指向字符串字面量的常量指针
  • 常用函数 (需包含 <string.h>):
    • strlen(str):求字符串长度 (不包括 \0)。
    • strcpy(dest, src):字符串拷贝 (将 src 拷贝到 dest)。
    • strcat(dest, src):字符串拼接 (将 src 拼接到 dest 后面)。
    • strcmp(str1, str2):字符串比较 (返回 0, 负数, 正数)。

多维数组

  • 二维数组数据类型 数组名[行数][列数]; (e.g., int matrix[3][4];)
  • 初始化
    int matrix[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };
  • 内存布局:二维数组在内存中也是线性连续存储的,按行优先存放。

第五部分:指针 (C语言的灵魂)

指针基础

  • 定义:指针是一个变量,其存储的是另一个变量的内存地址。
    • 语法:数据类型 *指针变量名; (e.g., int *p;)
  • 核心运算符
    • & (取地址):获取变量的内存地址。p = &a;
    • (解引用/间接寻址):通过指针访问其指向的内存中的值。printf("%d", *p);
  • 指针与数组
    • 数组名 arr 通常会“衰变”为其首元素的地址。p = arr; 等价于 p = &arr[0];
    • 可以通过指针遍历数组:*(p + i) 等价于 arr[i]
  • 指针与函数
    • 指针作为参数:可以实现“地址传递”,从而在函数内部修改外部变量的值,这是C语言实现“引用传递”效果的主要方式。
    • 指针作为返回值:函数可以返回一个指针,指向某个变量或内存区域。

指针进阶

  • 指针的指针:指向指针的指针。
  • 函数指针:指向函数的指针,可以用于将函数作为参数传递给其他函数,实现回调机制。
    • 语法:返回类型 (*指针名)(参数列表); (e.g., int (*p_func)(int, int);)
  • const 与指针
    • const int *pp 可变,但 p 指向的内容(*p)不可变。
    • int *const pp 不可变,但 p 指向的内容可变。
    • const int *const pp*p 都不可变。

第六部分:内存管理

动态内存分配

  • 目的:在程序运行时根据需要动态地分配和释放内存,避免了静态数组的固定大小限制。
  • 相关函数 (需包含 <stdlib.h>):
    • malloc(size_t size):分配 size 字节的内存块,返回一个指向该内存块起始地址的指针,内存是未初始化的。
    • calloc(size_t num, size_t size):分配 num * size 字节的内存块,并将所有位初始化为0。
    • free(void *ptr):释放之前通过 malloccalloc 分配的内存块。防止内存泄漏!
    • realloc(void *ptr, size_t new_size):调整之前分配的内存块的大小。

第七部分:结构体、联合体与枚举

结构体

  • 定义:将不同类型的数据组合成一个单一的复合类型。
    struct Student {
        char name[50];
        int age;
        float score;
    };
  • 声明与使用
    struct Student s1; // 声明一个结构体变量
    strcpy(s1.name, "Zhang San");
    s1.age = 20;
  • 结构体指针:通过 -> 运算符访问成员。s1.age 等价于 ptr->age

联合体

  • 定义:一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。
  • 特点:所有成员共享同一块内存,大小是最大成员的大小,修改一个成员会影响其他成员。
  • 用途:当需要在不同时间以不同类型使用同一块内存时使用。

枚举

  • 定义:定义一个命名常量的集合。
    enum Weekday {MON, TUE, WED, THU, FRI, SAT, SUN};
  • 特点:默认情况下,枚举常量的值从 0 开始递增,可以手动指定值。
    • enum Weekday today = MON;

第八部分:文件操作

文件I/O

  • 文件指针:使用 FILE * 类型的指针来标识和操作文件。
  • 相关函数 (需包含 <stdio.h>):
    • fopen(const char *filename, const char *mode):打开文件,返回文件指针。
      • 模式:"r" (读), "w" (写, 覆盖), "a" (追加), "rb", "wb" (二进制模式) 等。
    • fclose(FILE *stream):关闭文件。
    • fgetc(FILE *stream):从文件中读取一个字符。
    • fputc(int c, FILE *stream):向文件中写入一个字符。
    • fgets(char *str, int n, FILE *stream):从文件中读取一行。
    • fputs(const char *str, FILE *stream):向文件中写入一行。
    • fscanf(FILE *stream, const char *format, ...):格式化读取。
    • fprintf(FILE *stream, const char *format, ...):格式化写入。
    • fread(void *ptr, size_t size, size_t count, FILE *stream):二进制读取。
    • fwrite(const void *ptr, size_t size, size_t count, FILE *stream):二进制写入。
    • fseek(FILE *stream, long offset, int origin):移动文件指针。

第九部分:预处理器与高级主题

预处理器

  • #include:包含头文件。
  • #define:宏定义,进行简单的文本替换。
    • 带参宏#define MAX(a, b) ((a) > (b) ? (a) : (b)) (注意括号)
  • 条件编译
    • #ifdef, #ifndef, #endif, #else, #elif
    • 用于根据条件选择性地编译代码,常用于跨平台开发和头文件保护。

其他重要概念

  • 命令行参数main 函数可以接收参数。
    • int main(int argc, char *argv[])
    • argc:参数计数 (包括程序名)。
    • argv:参数向量 (字符串数组)。
  • 位域:在结构体中,以位为单位来指定成员的内存长度,用于节省空间。
  • 错误处理:C语言没有内置的异常处理机制,通常通过函数返回值、全局变量 errno 或更复杂的错误码系统来处理错误。

学习建议

  1. 动手实践:编程是门手艺,光看不练是学不会的,多写代码,多调试。
  2. 理解内存:C语言的核心是操作内存,画出变量、数组、指针在内存中的布局,有助于深刻理解指针和数组。
  3. 善用调试器:学习使用 GDB (Linux) 或 Visual Studio Debugger (Windows) 来单步执行代码,观察变量变化,是排查问题的利器。
  4. 阅读优秀代码:阅读一些开源的、高质量的C语言项目(如SQLite的一部分),学习其编码风格和设计思想。
  5. 从底层向上:理解计算机是如何工作的(CPU、内存、寄存器),会让你对C语言有更本质的认识。

这份总结涵盖了C语言的绝大部分核心知识点,希望能对你的学习和复习有所帮助!

-- 展开阅读全文 --
头像
dede bshare
« 上一篇 03-29
dede option是什么?如何使用?
下一篇 » 03-29

相关文章

取消
微信二维码
支付宝二维码

目录[+]