计算机二级C语言复习

第一章 C 语言基本知识

  • C 程序

    • 源程序文件后缀为 .c
    • 编译后生成目标文件,后缀为 .obj
    • 连接库函数后生成可执行文件,后缀为 .exe
    • 三种基本结构:顺序结构、选择结构、循环结构
  • main 函数

    • C 程序的入口,有且仅有一个
    • 示例:
      1
      2
      3
      int main() {
      return 0;
      }
  • 数据的存储形式

    • 数据以二进制形式存储,1 Byte = 8 bit
    • 进制转换:
      • 二进制、八进制、十六进制转十进制使用乘法
      • 十进制转其他进制使用除法
    • 数据地址即数据的存放位置
  • 注释

    • 格式:/* 注释内容 */,不可嵌套
  • 书写格式

    • 每条语句后加分号 ;
    • 示例:x = 1; y = 2;
  • 标识符

    • 命名规则:由字母、数字、下划线组成,首字符必须为字母或下划线,区分大小写
    • 三类:
      • 关键字,例如 int
      • 预定义标识符,例如 define
      • 用户自定义标识符
  • 常量与变量

    • 常量:值不可变
      • 整型:5
      • 实型:3.14
      • 字符:'a'
      • 字符串:"abc"
      • 符号常量:#define PI 3.14
    • 变量:值可变,C 语言无字符串变量,字符串使用字符数组存储
  • 整型数据

    • 表示形式:
      • 十进制:10
      • 八进制:012
      • 十六进制:0xA
      • 注意:整形数据没有二进制形式!
    • 类型:
      • int (4 字节)
      • short(2 字节)
      • long (8 字节)
      • unsigned(4 字节)
  • 实型数据

    • 表示形式:
      • 小数形式:3.14
      • 指数形式:1.23e-4
    • 类型:
      • float (4 字节)
      • double
  • 算术运算

    • 运算符:+, -, *, /, %
    • 示例:5 / 2 = 2(整型运算舍去小数部分)
  • 强制类型转换

    • 格式:(类型)表达式
    • 示例:(float)5 / 2 = 2.5
  • 赋值

    • 运算符:=
    • 复合赋值:+= 等价于 n = n + 100
  • 自加自减运算

    • 运算符:++, --
    • 示例:
      • j = i++ 表示 j = i; i = i + 1
      • j = ++i 表示 i = i + 1; j = i
  • 逗号运算

    • 优先级最低
    • 示例:a = 1, b = 2

第二章 顺序结构

  • 运算符、表达式与语句

    • 表达式:a + b
    • 语句:a = b + 1;
  • 运算符优先级

    • 从高到低:初等运算 > 单目运算 > 算术运算 > 关系运算 > 逻辑运算 > 赋值运算 > 逗号运算
  • printf 函数

    • 格式:printf("%d", 123)
  • 格式说明

    格式符 完整名称 数据类型
    %d integer 整型
    %f float 单精度浮点型
    %lf long float 双精度浮点型
    %c character 字符
    %s string 字符串
  • scanf 函数

    • 输入项需加取地址符 &,分隔符可以是空格、制表符或回车
    • 示例:scanf("%d", &x)
  • 交换变量

    • 示例:
      1
      2
      3
      t = x;
      x = y;
      y = t;

第三章 选择结构

  • 关系运算

    • 非 0 表示真,0 表示假
    • 运算符:>>===
  • 逻辑运算

    • 运算符:&&(与)、||(或)、!(非)
    • 短路求值示例:a++ || b++(若 a 非 0,则 b++ 不执行)
  • if 语句

    • 嵌套时,else 与最近的 if 匹配
    • 示例:
      1
      2
      3
      4
      if (x > 0)
      y = 1;
      else
      y = 0;
  • 条件运算

    • 格式:x > 0 ? 1 : 0
  • switch 语句

    • switch 表达式不可为实型,case 后不可接变量
    • 示例:
      1
      2
      3
      4
      switch (x) {
      case 1:
      break;
      }

第四章 循环结构

  • 三种循环

    • while (x < 5)
    • do { } while (x < 5);
    • for (i = 0; i < 5; i++)
  • break 与 continue

    • break:终止整个循环
    • continue:结束当前轮次,继续下一次循环
  • 循环嵌套

    • 示例:
      1
      2
      for (i = 0; i < 2; i++)
      for (j = 0; j < 3; j++)

第五章 字符型数据与位运算

  • 字符常量

    • 格式:'a'
    • ASCII 码:'0' = 48, 'A' = 65, 'a' = 97
  • 转义字符

    • 示例:'\n' 表示换行,'\101' 表示 'A',后面的数字表示 ASCII 码的偏移量,是8进制
  • 字符与整型转换

    • 示例:'A' + 32 = 'a'
  • 位运算符

    • ~(取反)、<<(左移)、>>(右移)、&(与)、^(异或)、|(或)
    • 示例:1 ^ 1 = 0
  • putchar 与 getchar

    • putchar():输出字符
    • getchar():输入字符
    • 示例:putchar('A');, x = getchar();

第六章 函数

  • 函数定义

    • 格式:
      1
      2
      3
      int func(int x) {
      return x;
      }
    • 空函数定义:void func(){};
  • 库函数

    • 示例:#include <stdio.h>
  • 函数返回值

    • 示例:return 0;
  • 函数声明

    • 示例:int func(int);
  • 参数传递

    • 传值:func(x),形参不影响实参
    • 传址:func(&x)
  • 递归调用

    • 示例:
      1
      2
      3
      4
      5
      int factorial(int n) { //阶乘
      if (n <= 1)
      return 1;
      return n * factorial(n - 1);
      }

第七章 指针

🔹 指针常见用法

声明 函数 () [] 数组 * 指针 int 类型 语义
int a - - - int a 变量 a,整型 (int type)
int a[3] - a[] - int a[] 数组 a,元素=int 变量
int *p - - *p int *p 指针 p,指向 int 变量
int *p[3] - p[] *p[] int *p[] 数组 p,元素=指向 int 变量的指针
int (*p)[3] - (*p)[] (*p) int (*p)[] 指针 p,指向数组 [],元素=int 变量
int **p - - a=*p
*(a)
int *(*p) 指针 p → 指针 a → int
int z(int) z() - - int z() 函数 z,形参=int 变量,返回=int
int (*p)(int) (*p)() - (*p) int (*p)() 指针 p,指向函数 (形参=int, 返回=int)

第八章 数组

  • 数组定义

    • 格式:int a[5];
  • 数组初始化

    • 示例:int a[] = {1, 2};
  • 二维数组

    • 左边是行数,右边是列数(行内个数)
    • 示例:int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
  • 数组名

    • 表示数组首地址,不可被赋值

第九章 字符串

  • 字符串常量

    • 格式:"ABC",末尾自动加 '\0'
  • 字符数组

    • 示例:char str[6] = "Hello";
  • 输入输出

    • 示例:gets(str);, puts(str);
  • 字符串函数

    函数名 完整名称 功能
    strcpy() string copy 复制字符串
    strlen() string length 计算字符串长度
    strcat() string cat 连接字符串
    strcmp() string compare 比较字符串
    • 注意:
      • strlen() 返回值是 int 类型,表示字符串的长度,即字符串中字符的个数,遇到’\0’之后就不再数了,即不包括 '\0'
      • strcmp() 返回值是 int 类型,表示两个字符串的比较结果,返回值小于 0 表示第一个字符串小于第二个字符串,返回值大于 0 表示第一个字符串大于第二个字符串,返回值等于 0 表示两个字符串相等。

第十章 结构体与共用体

  • 结构体

    • 结构体是一种自定义数据类型,用于组合多个不同类型的成员,每个成员占用独立内存,总大小为成员大小之和(可能因内存对齐增加)。
    • 定义格式:
      1
      2
      3
      4
      struct stu {
      char name[10]; // 字符数组,10 字节
      int age; // 整数,4 字节
      };
    • 使用时需定义变量,如 struct stu s; 或通过 typedef 简化类型名。
  • 成员引用

    • 访问结构体成员的三种方式:
      • 变量直接访问:s.name(点运算符,访问结构体变量的成员)
      • 指针访问:p->age(箭头运算符,访问指针指向的成员)
      • 间接访问:(*p).age(解引用后用点运算符)
    • 示例:
      1
      2
      3
      struct stu s = {"Alice", 20};
      struct stu *p = &s;
      printf("%s, %d\n", s.name, p->age); // 输出: Alice, 20
  • 共用体

    • 共用体也是一种自定义类型,所有成员共享同一块内存,大小为最大成员的大小(可能因内存对齐调整)。一次只能存储一个成员的值,新赋值会覆盖旧值。
    • 定义格式:
      1
      2
      3
      4
      union data {
      int i; // 4 字节
      float f; // 4 字节
      };
    • 示例:
      1
      2
      3
      4
      5
      union data d;
      d.i = 65; // 存整数
      printf("%d\n", d.i); // 输出: 65
      d.f = 3.14; // 存浮点数,覆盖 i
      printf("%f\n", d.f); // 输出: 3.14
    • 用途:节省内存或实现类型灵活性,如表示单一值的多种形式。

第十一章 文件

  • 文件指针

    • 文件指针是一个指向 FILE 类型的指针,用于操作文件。FILE 是 C 标准库中定义的一个结构体,包含了文件操作所需的信息(如文件位置、状态等)。

    • 定义格式:FILE *fp;

      • fp 是一个指针变量,必须在使用前初始化,通常通过 fopen 函数赋值。
    • 示例:

      1
      FILE *fp; // 定义文件指针
    • 注意:文件指针在使用后需要通过 fclose 关闭,以释放资源。

  • 打开文件

    • 文件的打开形式如下:FILE *fp; fp = fopen("c:\\lab.c", "rb");

      • fopen 函数用于打开文件,返回一个文件指针。
      • 参数说明:
        • 第一个参数是文件名(包含路径),如 "c:\\lab.c" 表示 Windows 系统下的路径,使用双反斜杠是因为反斜杠 \ 在字符串中需转义。
        • 第二个参数是文件打开模式,常见模式包括:
          • "r":只读模式,文件必须存在。
          • "w":只写模式,若文件不存在则创建,若存在则清空。
          • "a":追加模式,写入数据追加到文件末尾。
          • "rb":以只读二进制模式打开文件。
          • "wb":以只写二进制模式打开文件。
          • "ab":以追加二进制模式打开文件。
      • "rb" 表示以只读二进制模式打开文件,这种模式适用于读取非文本文件(如图片或可执行文件),不会对数据进行任何转换。
    • 示例:

      1
      2
      3
      4
      5
      FILE *fp;
      fp = fopen("c:\\lab.c", "rb"); // 打开文件
      if (fp == NULL) {
      printf("文件打开失败\n"); // 检查是否打开成功
      }
    • 注意:打开文件时应检查 fopen 返回值是否为 NULL,以判断文件是否成功打开。

  • 文件函数

    • C 语言提供了多种文件操作函数,分别用于字符、字符串和二进制数据的读写。
    • 字符操作函数
      • fgetc(fp):从文件中读取一个字符,返回值为 int 类型(若到文件末尾返回 EOF)。

        • 示例:

          1
          2
          3
          4
          int ch = fgetc(fp); // 读取一个字符
          if (ch != EOF) {
          putchar(ch); // 输出读取的字符
          }
      • fputc(ch, fp):将一个字符写入文件。

        • 示例:
          1
          fputc('A', fp); // 写入字符 'A'
    • 字符串操作函数
      • fgets(str, n, fp):从文件中读取一行或最多 n-1 个字符到字符串 str 中,自动在末尾添加 \0
        • 示例:
          1
          2
          3
          char str[100];
          fgets(str, 100, fp); // 读取一行
          printf("%s", str);
      • fputs("abc", fp):将字符串写入文件,不自动添加换行符。
        • 示例:
          1
          fputs("abc", fp); // 写入字符串 "abc"
    • 格式化输入输出函数
      • fscanf(fp, "%d", &x):从文件中按格式读取数据。
        • 示例:
          1
          2
          int x;
          fscanf(fp, "%d", &x); // 读取一个整数
      • fprintf(fp, "%d", x):按格式将数据写入文件。
        • 示例:
          1
          2
          int x = 123;
          fprintf(fp, "%d", x); // 写入整数 123
    • 二进制操作函数
      • fread(buf, size, count, fp):从文件中读取 count 个大小为 size 的数据块到缓冲区 buf
        • 示例:
          1
          2
          int data[5];
          fread(data, sizeof(int), 5, fp); // 读取 5 个整数
      • fwrite(buf, size, count, fp):将缓冲区 buf 中的 count 个大小为 size 的数据块写入文件。
        • 示例:
          1
          2
          int data[5] = {1, 2, 3, 4, 5};
          fwrite(data, sizeof(int), 5, fp); // 写入 5 个整数
    • 文件位置控制函数
      • fseek(fp, offset, origin):移动文件指针。
        • 参数:
          • offset:偏移量(字节数)
          • origin:起始位置(SEEK_SET 文件开头,SEEK_CUR 当前位置,SEEK_END 文件末尾)
        • 示例:
          1
          fseek(fp, 0, SEEK_SET); // 移动到文件开头
      • ftell(fp):返回文件指针当前所在位置(相对于文件开头的字节数)。
        • 示例:
          1
          long pos = ftell(fp); // 获取当前位置
      • rewind(fp):将文件指针移到文件开头。
        • 示例:
          1
          rewind(fp); // 回到文件开头
    • 文件结束判断
      • feof(fp):判断是否到达文件末尾,返回非 0 表示文件结束。
        • 示例:
          1
          2
          3
          while (!feof(fp)) {
          ch = fgetc(fp); // 循环读取字符
          }
    • 关闭文件
      • fclose(fp):关闭文件,释放资源。
        • 示例:
          1
          fclose(fp); // 关闭文件
    • 注意:文件操作函数分为文本文件和二进制文件适用的类型,使用时需根据文件模式选择合适的函数。

第十二章 深入讨论

  • 编译预处理

    凡以#开头的这一行,都是编译预处理命令行,编译预处理不加分号,不占运行时间

    宏替换仅是简单的文本替换,如#define  f(x)  (x)*(x)和#define  f(x)  x*x替换f(2+2)时就有区别,前者展开为(2+2)*(2+2),后者为2+2*2+2。

    如果源文件f2.c中有#include"f1.c"可以理解为:把源文件f1.c原样包含到f2.c中,使f1.c和f2.c融合到一起成为一个C程序编译。

    所以一个C程序必有主函数,但一个C源文件未必有主函数

  • 标识符作用域

    局部变量:在函数内或复合语句内定义的变量,作用域为定义它的函数内。

    局部变量有三种类型:

    • 自动auto:自动变量随着函数的使用与否创建消失。

    • 寄存器register:寄存器变量分配在cpu中,没有内存地址。

    • 静态static:静态变量占用固定存储单元,在程序执行过程不释放,直到程序运行结束。

    全局变量:在函数外定义的变量,作用域从定义它的位置到整个源文件结束为止,生存期为整个程序运行期间。

    全局变量都是静态变量。

  • 动态存储分配

    malloc(size):创建连续size个字节存储区,返回值类型为void *型。malloc函数常用于动态创建链表结点,如int *p; p=(int *)malloc(sizeof(int));。

    calloc(n,size):创建n个同一类型的存储空间,可以理解为n个malloc。

    free(p):释放动态分配的存储单元。