一、一维字符型数组

        在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.通用规则:

        数组元素存储均具备 “连续性、有序性、单一性”,这是数组区别于其他数据结构的核心特征,也是数组高效访问的基础。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐