云计算百科
云计算领域专业知识百科平台

嵌入式学习8

C语言一维字符数组与二维整型数组全面详解(知识点+坑点+实操)

前言

今天系统学习了C语言数组中两大核心内容:一维字符型数组(字符串存储载体)、二维整型数组(表格/矩阵存储)。C语言本身没有string字符串类型,所有字符串操作都依赖字符数组实现;二维数组则是处理多行多列数据的基础,本文整理核心知识点、使用规范、高频易错坑点,附带实操要点,方便复习与查阅。

一、一维字符型数组(字符串专用)

1. 核心基础概念

  • C语言无独立字符串类型,字符串必须存储在字符数组中;
  • 字符串硬性规则:末尾必须存在结束标记 \\0(ASCII值等价于数字0);
  • 字符数组 = 连续char空间,既可存单个字符,也可存完整字符串。
  • 2. 定义格式

    char 数组名[常量长度];

    • 数组长度必须是常量,不能用变量;
    • 长度预留:必须多分配1字节给末尾\\0,例如存hello至少定义char str[6]。

    3. 四种初始化方式

    // 方式1:逐个字符赋值,手动加\\0
    char str[6] = {'h','e','l','l','o','\\0'};

    // 方式2:双引号整体初始化(自动补\\0,推荐)
    char str[6] = "hello";
    char str[6] = {"hello"};

    // 方式3:局部初始化,未赋值元素自动补0(\\0)
    char str[6] = {'h','e','l'};

    // 方式4:省略长度,编译器自动计算长度(包含\\0)
    char str[] = "hello";

    区分关键:

    • '0':字符0,ASCII码48;
    • 0 / '\\0':字符串结束符,ASCII码0,打印到这里终止字符串输出。

    4. 字符串输入输出函数

    输出
  • printf("%s", str);
    从数组首地址开始打印,直到遇到\\0停止。
  • puts(str);
    自动打印字符串,末尾自带换行\\n,无需手动加换行符。
  • 输入
  • scanf("%s", str);
    • 无需加&,数组名本身代表首地址;
    • 致命缺陷:空格、回车会截断输入,无法读取带空格的句子。
  • gets(str);
    • 支持读取带空格整行输入;
    • 自动丢弃输入回车,替换为\\0;
    • 严重缺陷:无缓冲区长度校验,极易内存越界,新标准C已废弃。
  • 5. 四大字符串库函数(头文件<string.h>)

    函数功能核心注意事项
    strlen(str) 统计字符串有效字符长度(不含\\0) 只算到\\0,和sizeof完全区分
    strcpy(dst, src) 字符串拷贝 目标数组空间必须足够容纳源字符串+\\0,否则越界
    strcat(str1, str2) 字符串拼接 str1剩余空间要存下拼接后全部字符,防止溢出
    strcmp(str1, str2) 字符串逐字符比较ASCII 返回值:0相等、>0 str1更大、<0 str2更大

    6. 重点区分:strlen vs sizeof

    char str[20] = "hello";
    strlen(str); // 结果5,只统计有效字符,忽略数组总大小
    sizeof(str); // 结果20,获取整个数组占用的内存字节总数

    7. 易踩坑易错点

  • 忘记预留\\0空间
    错误:char str[5] = "hello"; 数组长度5,放不下hello+\\0,无结束符,打印乱码。
  • 混淆'0'和'\\0'
    判断字符串结束只能用\\0,不能用字符'0'。
  • scanf读取带空格字符串失效
    输入hello world只会读到hello,空格终止读取。
  • 数组越界写入
    strcpy/strcat不校验长度,源字符串过长会覆盖数组以外内存,程序崩溃。
  • 未初始化字符数组直接打印
    数组剩余空间是随机脏数据,无\\0会持续向后乱打印。
  • gets函数禁用
    无边界保护,存在严重安全漏洞,项目中禁止使用。
  • 8. 课堂实操练习考点

  • 不使用strlen,手写代码统计字符串长度;
  • 不使用strcpy,手动循环实现字符串拷贝;
  • 不使用strcat,手动拼接两个字符串;
  • 不使用strcmp,手动逐字符对比字符串;
  • 统计字符串中大写、小写、数字、空格字符数量。
  • 二、二维整型数组(矩阵/表格数据)

    1. 核心基础概念

  • 二维数组 = 数组的数组,外层一维数组的每个元素又是一维数组;
  • 存储逻辑:行、列,格式 数组名[行][列],模拟表格、矩阵;
  • 内存存储规则:行优先连续存储,同一行元素紧挨着,再存下一行。
  • 2. 定义格式

    int 数组名[行数][列数];
    // 示例:2行3列整型数组
    int a[2][3];

    强制规则:行数、列数必须是常量,不能为变量。

    3. 元素访问

    下标从0开始,数组名[行下标][列下标]

    int a[2][3];
    a[0][0] = 1; // 第一行第一列
    a[1][2] = 6; // 第二行第三列

    禁止下标越界:2行下标只能0/1,3列下标只能0/2。

    4. 三种初始化方式

    // 1. 平铺全部初始化(按行顺序填充)
    int a[2][3] = {1,2,3,4,5,6};

    // 2. 分行初始化(可读性最高,推荐)
    int a[2][3] = {{1,2,3},{4,5,6}};

    // 3. 局部初始化,未赋值元素自动补0
    int a[2][3] = {{1,2},{3}};
    // 剩余空位全部填充0

    // 4. 省略行数初始化(列数绝对不能省略)
    int a[][3] = {1,2,3,4,5,6}; // 自动识别2行

    关键限制:二维数组初始化列下标不可省略,行可以省略。

    5. 数组空间计算

    总字节 = 单个int字节数 × 行数 × 列数

    int a[2][3];
    int total = sizeof(a); // 整个数组总字节
    int row_size = sizeof(a[0]); // 单行占用字节
    int col_cnt = sizeof(a[0]) / sizeof(a[0][0]); // 列数
    int row_cnt = sizeof(a) / sizeof(a[0]); // 行数

    6. 常规遍历方式(双层for循环)

    外层循环控制行,内层循环控制列:

    #include <stdio.h>
    int main(void)
    {
    int a[2][3] = {{1,2,3},{4,5,6}};
    int i,j;
    // 遍历打印全部元素
    for(i=0; i<2; i++)
    {
    for(j=0; j<3; j++)
    {
    printf("%d ", a[i][j]);
    }
    printf("\\n");
    }
    return 0;
    }

    7. 重点注意事项

  • 存储顺序:行优先,内存连续排布,不存在分行隔离;
  • 下标从0开始,最大下标 = 定义长度-1;
  • 局部初始化空缺元素默认填充0;
  • 作为函数参数时,二维数组必须指定列大小。
  • 8. 易踩坑易错点

  • 初始化省略列数
    错误:int a[2][] = {1,2,3}; 编译器无法识别单行长度,直接报错。
  • 下标越界访问
    定义a[2][3],访问a[2][0]、a[0][3],读写未知内存,程序乱码/崩溃。
  • 单层循环遍历二维数组
    逻辑混乱,无法区分行列,标准场景必须双层循环。
  • 用变量定义行列长度
    C标准数组长度必须常量,int n=3; int a[2][n]; 标准C语法报错。
  • 混淆行列循环顺序
    外层行、内层列写反,输出表格行列颠倒。
  • 三、今日学习总结

  • 一维字符数组是C语言字符串唯一存储载体,\\0是字符串核心标识,区分strlen和sizeof是高频考点;
  • 字符串输入输出各有优劣,scanf不能读空格,gets存在安全缺陷;四大字符串库函数操作必须保证数组空间充足;
  • 二维整型数组本质是数组嵌套,行优先连续存储,初始化只能省略行数,列数不可省略;
  • 两类数组最高频Bug:下标越界、空间分配不足、混淆结束符/初始化默认值;
  • 配套练习重点:手动实现字符串库函数、双层循环遍历矩阵、字符统计、数组倒置/排序。
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » 嵌入式学习8
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!