)
第十天 C语言 Day10冒泡排序 · 二维数组 · 字符数组排序算法/矩阵转置/空菱形/字符串与\0系列粤嵌嵌入式培训学习笔记 (C语言篇-第10天)上一篇第九天 C语言 Day9goto语句 · 循环嵌套 · break/continue · 猜拳游戏 · 数组概述 · 一维数组环境Ubuntu 22.04 · GCC · Vim | 2026年8月7日① 概览昨天学会了用一维数组存一批数据今天解决怎么处理这批数据先是第一个排序算法——冒泡排序把乱序数列排成升/降序理解轮数容量-1、相邻比较交换然后进入二维数组数组的数组行列行优先存储用矩阵转置练手最后是字符数组存字符串搞懂\0结束标志、sizeof与strlen的区别、三种遍历方式。模块一句话冒泡排序 ⭐相邻比较交换轮数容量-1、次数容量-轮数-1两数交换用临时变量二维数组 ⭐数组的数组行列行优先存储可省略行容量、不可省列容量矩阵转置行变列、列变行arr_after[j][i] arr_before[i][j]字符数组 ⭐存字符串\0结束标志sizeofvsstrlen字符指针 vs 字符数组空菱形二维字符数组存图案遍历输出② 冒泡排序2.1 排序思想一次只把一个数排到正确位置。核心相邻两个元素比较顺序不对就交换一轮下来最大的或最小的沉到末尾。n 个元素最差需要n-1 轮每轮比较次数递减数组长度 - 轮数 - 1如果某一轮没有任何交换说明已经有序可以提前结束标志位优化2.2 两数交换必须掌握inttempa;// 用临时变量保存 aab;// 把 b 给 abtemp;// 把原来 a 的值给 b2.3 冒泡推理5,4,3,2,1 → 1,2,3,4,5轮数开始结束比较次数第⓪轮5,4,3,2,14,3,2,1,54 5-0-1第①轮4,3,2,1,53,2,1,4,53 5-1-1第②轮3,2,1,4,52,1,3,4,52 5-2-1第③轮2,1,3,4,51,2,3,4,51 5-3-1共4 轮容量5-1每轮把当前最大数沉到末尾。2.4 代码实现含升/降序切换 提前结束优化#includestdio.h#defineSORT_DESC0// 0升序非0降序intmain(){intarr[10];inti,j,temp;intlensizeof(arr)/sizeof(arr[0]);printf(请输入%d个整数,len);for(i0;ilen;i)scanf(%d,arr[i]);printf(排序前);for(i0;ilen;i)printf(%-4d,arr[i]);printf(\n);// ---------- 冒泡排序 ----------for(i0;ilen-1;i){// 外层轮数 容量-1intflag0;// 标志本轮是否有交换for(j0;jlen-i-1;j){// 内层次数 容量-轮数-1if(SORT_DESC){// 降序if(arr[j]arr[j1]){temparr[j];arr[j]arr[j1];arr[j1]temp;flag1;}}else{// 升序if(arr[j]arr[j1]){temparr[j];arr[j]arr[j1];arr[j1]temp;flag1;}}}if(!flag)break;// 无交换 → 已有序提前结束}printf(排序后);for(i0;ilen;i)printf(%-4d,arr[i]);printf(\n);return0;}衍生冒泡排序 → 鸡尾酒排序、摇床排序、搅拌排序等。③ 二维数组3.1 定义二维数组是数组的数组——每个元素是一个一维数组由行 列构成。数据类型 数组名[行容量][列容量];行容量有几个一维数组几行列容量每个一维数组有几个元素几列3.2 初始化要点可以省略行容量系统自动推断不能省略列容量支持部分初始化未初始化部分填 0分行用{}包裹intarr[][3]{{11,12,13},{21,22,23},{31,32,33}};// 省略行容量 ✓intarr[3][3]{{11,22},{21,22,23},{31}};// 部分初始化补0intarr[][3]{0};// 全0推荐intarr[][]{...};// 错误不能省列容量intarr[][3];// 错误未初始化必须写全行列3.3 内存存储行优先C 语言二维数组按行优先存储先存满第 0 行的所有列再第 1 行……行下标第一维变化慢列下标第二维变化快3.4 遍历双层 for#includestdio.hintmain(){intarr[][3]{{11},{21,22},{31,32,33}};// 计算行列容量introw_lensizeof(arr)/sizeof(arr[0]);// 行数intcol_lensizeof(arr[0])/sizeof(arr[0][0]);// 列数for(inti0;irow_len;i){// 外层行for(intj0;jcol_len;j)// 内层列printf(%-4d,arr[i][j]);printf(\n);}return0;}// 输出// 11 0 0// 21 22 0// 31 32 333.5 案例矩阵转置行变列、列变行#includestdio.h#defineROW2#defineCOL3intmain(){intbefore[ROW][COL]{11,12,13,21,22,23};intafter[COL][ROW]{0};// 行列互换intbrsizeof(before)/sizeof(before[0]);intbcsizeof(before[0])/sizeof(before[0][0]);intarsizeof(after)/sizeof(after[0]);intacsizeof(after[0])/sizeof(after[0][0]);for(inti0;ibr;i){for(intj0;jbc;j){after[j][i]before[i][j];// 转置核心行变列、列变行printf(%-4d,before[i][j]);}printf(\n);}printf(转置后\n);for(inti0;iar;i){for(intj0;jac;j)printf(%-4d,after[i][j]);printf(\n);}return0;}// 转置前 转置后// 11 12 13 11 21// 21 22 23 12 22// 13 23④ 字符数组C 语言支持字符串常量不支持字符串变量。想实现字符串变量有两种方式字符数组或字符指针。charname[]如烟大帝;// 字符数组char*name围嘴龙王;// 字符指针4.1 什么是字符数组元素类型为char的数组用来存字符串。1 个 char 1 字节8 bit。char 能存什么字符A、ASCII 码1、转义\n都可以。char 不能存什么A这是字符串、中文字符1字节装不下UTF-8 中文占 2-4 字节。4.2 字符串结束标志\0C 规定字符串常量以\0作为结束标志。编译系统自动给字符串加\0char *s Tom实际存{T,o,m,\0}\0的 ASCII 是 0不可显示、不占有效字符只用来判断字符串何时结束程序常用while(arr[i] ! \0)判断是否结束chara1[]{h,i};// 无 \0用 %s 输出会越界UB可能乱码chara2[]{h,i,\0};// 有 \0用 %s 输出 hi ✓chara3[]hi\0shuai\0;// %s 输出遇到 \0 就停 → hi4.3 字符数组初始化注意事项chararr1[2];// 局部不初始化 → 垃圾值chararr2[3]{a,b,c};// 完全初始化chararr3[3]{a};// 部分初始化剩余补 \0chararr4[3]{0};// 全补 \0推荐写法chararr5[]{b,i,u};// 省略容量由元素个数决定// char arr6[2] {l,i,u}; // 错误元素个数容量UB4.4 sizeof vs strlen必考sizeof数组占的总字节数含\0strlen第一个\0之前有效字符数不含\0需#include string.hcharname[]hello;// {h,e,l,l,o,\0}sizeof(name)6;// 含 \0strlen(name)5;// 不含 \0charn[]{h,e,\0,l,o,\0};strlen(n)2;// 到第一个 \0 为止4.5 案例输出空菱形二维字符数组二维的图形本质是二维的面用二维字符数组存放。#includestdio.hintmain(){chararr[][5]{{ , ,*, , },{ ,*, ,*, },{*, , , ,*},{ ,*, ,*, },{ , ,*, , }};introwsizeof(arr)/sizeof(arr[0]);intcolsizeof(arr[0])/sizeof(arr[0][0]);for(inti0;irow;i){for(intj0;jcol;j)printf(%c,arr[i][j]);printf(\n);}return0;}// 输出// *// * *// * *// * *// *4.6 字符串长度 ≠ 字符数组长度数组长度sizeof含\0字符串长度strlen不含\0注意字符串常量可以初始化字符数组但不能赋值给字符数组数组名是常量。chararr1[]hello;// ✓ 初始化可以chararr2[6];arr2hello;// ✗ 赋值报错数组名是常量⑤ 踩坑记录 ⭐坑1冒泡内层次数写错现象排序漏排、越界根因内层次数len - i - 1写成了len - 1解决内层for(j0; jlen-i-1; j)每轮少比较已沉底的数坑2两数交换没临时变量现象ab; ba;后两个数都变成 b 的值根因没先保存 a 的值解决tempa; ab; btemp;坑3二维数组省略列容量现象int arr[][] {...};编译报错根因系统无法推断每行几个元素解决列容量必须写行容量可省略坑4字符数组没有\0用%s输出现象输出乱码/越界崩溃根因%s靠\0判断结束没有\0会一直读到内存别处解决确保以\0结尾或用hello初始化自动加\0坑5sizeof 和 strlen 混用现象循环次数多/少了根因sizeof含\0strlen不含解决遍历字符数组用strlen有效字符算内存大小用sizeof坑6用字符串给数组赋值现象char s[10]; s hi;报错根因数组名是常量不能做左值解决初始化时写或用strcpy后续函数章学⑥ 小结今天完成冒泡排序相邻比较交换、轮数容量-1、次数容量-轮数-1、两数交换用临时变量、无交换提前结束优化→二维数组数组的数组、行列、行优先存储、可省行容量不可省列容量、遍历用双层for、矩阵转置→字符数组存字符串、\0结束标志、sizeofvsstrlen、字符串常量可初始化不可赋值、空菱形图案。下一篇进入函数——模块化编程的核心形参实参、值传递、递归、static。本文首发于 CSDN转载请注明出处。