拆解 C 语言数组核心:字符数组操作 + 二维数组,附实战案例与避坑指南
一、一维字符型数组
在C语言用来存放字符串的类型
1.定义
数据类型 数组名[元素个数];
例:char str[32];
注意:元素个数必须为常量;
元素个数大于要存储的字符串的字符个数;
2.元素的访问
数组名[元素下标]
例:str[0] //第一个元素
注意:元素下标为:0~元素个数 - 1(超出范围访问为越界访问)
3.字符数组初始化
初始化 != 赋值
(1)全部初始化
char str[6] = {'h','a','p'.'p','y'};
char str[6] = {"happy"};
char str[6] = "happy";
(2)局部初始化
char str[6] = {'h','a','p'};
char str[6] = "hap";
注意:没有给定初值的元素为0值,即为 '\0'
(3)默认初始化
char str[ ] = {'h','a','p'.'p','y'}; //5个字符
char str[] = {"happy"}; //6个字符
注意:由给定的初始化决定元素的个数(不建议写这种形式)
4.字符型数组的存储
(1)空间大小
字符型数组所占空间大小 == 数组元素的个数
元素个数 == sizeof(a) / sizeof(a[0])
(2)存储特性
连续性:数组存放元素空间连续;
有序性:数组存放元素的顺序有序;
单一性:元素类型保持一致;
5.字符串的打印
(1)printf
printf("%s"\n,str); //%s的特性是将字符串从第一个字符到 \0 中间的内容打印出来;
(2)puts
puts(str);
6.字符串的接收
(1)scanf
scanf("%s",str);
(2)gets
gets(str);
接收到的字符会依次存放在str[0]、str[1]、str[2] ...中
练习:计算字符串的长度
#include<stdio.h>
int main(void)
{
char str[32] = {0};
int i = 0;
gets(str);
for(i = 0; i < 32; i++)
{
if(0 == str[i])
{
break;
}
}
printf("该字符串的长度为:%d\n",i);
}
结果为:

7.字符串常用的函数
用这些函数都需要加上以下头文件!
#include<string.h>
(1)strlen
功能:获得字符串的长度(不包含‘\0’)
这里注意与我们前面用到的sizeof区分:
sizeof(str);//获得str在内存中所占的字节数
strlen(str); //获得str字符串的长度
(2)strcpy
strcpy(目的空间,源字符串)
功能:将源字符串拷贝到目的空间
示例: char str[32] = {0};
char str[32] = {0};
strcpy(str,"happy");
strcpy(dst,str);
注意:目的空间一定要能够存放的下源字符串!
(3)strcat
功能:将两个字符串拼接
示例:char str[32] = {"happy "};
strcat(str,"birthday!");
拼接为:happy birthday!
(4)strcmp
功能:进行字符串的比较;
规则:若第一个字符串大于第二个字符串,则返回大于0的值;
若第一个字符串等于第二个字符串,则返回0值;
若第一个字符串小于第二个字符串,则返回小于0的值;
实质上是两个字符串从左依次开始比较,不相等的字符对应的ASCII码值大的该字符串就大
练习:接收字符串,并逆序打印出
#include<stdio.h>
#include<string.h>
int main(void)
{
char str[32] = {0};
int i = 0;
int len = 0;
char tmp = 0;
gets(str);
len = strlen(str);
for(i = 0; i < len / 2; i++)
{
tmp = str[i];
str[i] = str[len-1-i];
str[len-1-i] = tmp;
}
printf("%s\n",str);
return 0;
}
结果为:

二、二维整型数组
1.二维数组的定义
数据类型 数组名[行个数][列个数]
示例: int a[3][4] //三行四列的数
2.元素访问
数组名[行下标][列下标]
下标:0 ~ 个数-1
3.二维整型数组的接收和打印
使用双层for循环接收和打印(外层为行,内层为列)
示例:
#include<stdio.h>
int main(void)
{
int a[3][4] = {0};
int i = 0;
int j = 0;
for(j = 0; j < 3; j++)
{
for(i = 0; i < 4; i++)
{
scanf("%d",&a[j][i]);
}
}
for(j = 0; j < 3 ; j++)
{
for(i = 0; i < 4; i++)
{
printf("a[%d][%d] = %d\n",j,i,a[j][i]);
}
}
return 0;
}
4.元素初始化
(1)全部初始化
int a[2][3] = {1,2,3,4,5,6};
int a[2][3] = {{1,2,3},{4,5,6}};
(2)局部初始化
int a[2][3] = {1,2,3};
int a[2][3] = {{1,2,},{3}};
int a[2][3] = {0};
int a[2][3] = {{0}};
(3)默认初始化
int a[ ][3] = {1,2,3,4,5,6};
int a[ ][3] = {{1,2},{3}};
int a[ ][3] = {1,2,3};
int a[ ][3] = {1,2,3,4};
注意:行能省略,列不能省略!(最好不要使用)
5.二维数组的存储
连续性: 空间连续
数组大小 == 元素类型所占空间大小 * 行数 * 列数
有序性:逐行从左到右依次存储,例:a[0][0]、a[0][1]、a[0][2].....
6.二维数组的本质
一维数组构成,即为一维数组的数组

7.为什么“行能省略,列不能省略”?
这也是由其本质决定的:
- 列数决定了 “每个一维数组元素有多少个值”(比如int a[ ][4],列数 4 固定,每个子数组有 4 个 int);
- 行数只是 “子数组的个数”,编译器可以通过初始化的元素数量自动计算行数(比如int a[ ][4] = {1,2,3,4,5,6};,编译器会算出行数 = 2);
- 如果省略列数(比如int [3][ ]),编译器无法知道 “每个子数组有多少个元素”,因此会报错。
三、二维字符型数组
1.概念:
主要用于存放字符串数组;
字符串使用一维字符数组存储,字符串数组使用二维字符数组存储(二维数组是一维数组的数组);
2.定义
char str[行数][列数];
示例:char str[4][30];
3.元素访问
str[行下标][列下标]; //char类型元素
str[行下标]; //数组类型
4.初始化
(1)局部初始化
示例:
char str[4][30] = {"hello","how","are","you"};
char str[4][30] = {{"hello"},{"how"},{"are"},{"you"}};
char str[4][30] = {0}; //清零
注意:没有给定初值的元素都是0值,即'\0'
(2)默认初始化
示例:
char str[ ][30] = {"hello","how","are","you"}; //1行32列
char str[ ][30] = {{"hello"},{"how"},{"are"},{"you"}}; //4行32列
5.接收与打印
使用for循环,一行一行接收和打印字符串
示例:
#include<stdio.h>
int main(void)
{
char str[4][30] = {0};
int i = 0;
for(i = 0; i < 4; i++)
{
gets(str[i]);
}
for(i = 0; i < 4; i++)
{
printf("str[%d] = %s\n",i,str[i]);
}
return 0;
}
输入四个字符串打印结果为:

练习:字符串的排序
int main(void)
{
char str[4][30] = {0};
int i = 0;
int j = 0;
char tmp[30] = {0};
for(i = 0; i < 4; i++)
{
gets(str[i]);
}
for(j = 0; j < 3; j++)
{
for(i = 0; i < 3-j ; i++)
{
if(strcmp(str[i],str[i+1]) > 0)
{
strcpy(tmp,str[i]);
strcpy(str[i],str[i+1]);
strcpy(str[i+1],tmp);
}
}
}
for(i = 0; i < 4; i++)
{
printf("str[%d] = %s\n",i,str[i]);
}
return 0;
}
结果示例:

三、避坑与总结
1.字符数组:
避免下标越界,使用strcpy/strcat时务必保证目标数组空间充足;
strlen与sizeof需严格区分 —— 前者是字符串有效长度,后者是数组总存储空间。
2.二维数组:
牢记 “行可省、列不可省” 的初始化规则(最好不要省略),其本质是 “一维数组的数组” ;
双层循环操作时,注意循环边界(行数 / 列数 - 1),避免越界。
3.通用规则:
数组元素存储均具备 “连续性、有序性、单一性”,这是数组区别于其他数据结构的核心特征,也是数组高效访问的基础。
更多推荐

所有评论(0)