一维字符数组和二维数组

一、一维字符数组思维导图

在C语言中,经常使用字符数组存储字符串,""引起来的都是字符串,

C语言中的字符串以'\0'结尾,'\0'看不到打印不出来

eg: "hello" ------> 实际占用6个Byte的空间

二、一维字符数组

2.1格式

char 数组名 {长度};

2.2初始化和赋值

#include <stdio.h>
int main(int argc, const char *argv[])
{
    /**********字符数组的初始化和赋值***********/
    char str[3]={'0','9','a'};   //完全初始化
    char str1[6]="hello";     //使用字符串给字符数组初始化
    char str2[]="hello";      //会根据初始化列表给字符数组分配空间
    printf("%ld\n",sizeof(str2));  //6,因为会给'\0'分配空间
    char str3[4]={"hi"};
    /*****赋值*****/
 str[2]='A';
    printf("%c\n",str[2]);
    //str="hello"; 报错
    return 0;
}

2.3字符数组的输入和输出

一般使用字符数组都是存储字符串,所以对于字符数组的输入和输出,实际上是对字符串的输入和输出

字符数组的输入输出可以用格式符或者输入输出函数

2.3.1使用格式符输入输出

输入:

使用格式符%s完成对字符数组的输入

#include <stdio.h>
int main(int argc, const char *argv[])
{
    char str[10];
    //使用格式符完成对字符数组的输入
    scanf("%s",str); 
    printf("str=%s\n",str);
    return 0;
}

输出:

%s:用于字符串的输入输出,%s在输出时,需要字符串的首地址,从首地址开始输出字符串直到遇到'\0'结束 (如果字符数组中存储的是多个字符使用%c循环输出,如果字符数组中存储的是字符串%s直接输出字符串)

#include <stdio.h>
int main(int argc, const char *argv[])
{
    /**********字符数组的初始化和赋值***********/
    char str[3]={'0','9','a'};   //完全初始化
    char str1[6]="hello";     //使用字符串给字符数组初始化
    char str2[]="hello";      //会根据初始化列表给字符数组分配空间
    printf("%ld\n",sizeof(str2));  //6,因为会给'\0'分配空间
    char str3[4]={"hi"};

    int i;
    for(i=0;i<3;i++)
    {
        printf("%c\n",str[i]);
    }
    //printf("%s\n",str);
    //str确实字符数组的首地址,但是str中存储的不是带有'\0'的字符串,
    //不能使用%s输出,只能通过循环使用%c输出多个字符
    printf("%s\n",str1);  //str1存储的是hello字符串结尾有'\0'
    printf("str=%p\n",str);  //数组名就表示数组的首地址(第一个元素的地址)
    printf("&str[0]=%p\n",&str[0]);
    return 0;
}

2.3.2使用输入输出函数

(1)puts函数

用于输出字符串的函数

函数原型:
int puts(const char *s);
功能:从字符串的首地址开始输出字符串
参数:字符串的首地址

(2)gets函数

用于字符串的输入函数

函数原型:
char *gets(char *s);
功能:终端获取字符串
参数:字符串的首地址
要求:在使用gets完成字符串输入时,要控制终端输入的阿字符串,不能超出字符数组的长度

使用gets一定会报错,说的是函数是不安全的,因为gets不会检测字符串范围,即使输入的字符串过长也会放进字符数组中,但是会造成越界问题。

示例:

#include <stdio.h>
int main(int argc, const char *argv[])
{
    char str[10];
    gets(str);  //使用gets给字符数组str输入
    puts(str);  //需要字符串的首地址,从首地址开始输出整个字符串

    return 0;
}

三、数组越界

数组越界的错误不可预知,尽量在书写时不要出现数组越界的问题

四、字符串函数族的函数

如果要使用字符串函数族中的函数,需要导入头文件

(1)strlen函数

函数原型:
size_t strlen(const char *s);
返回值:字符串的大小
参数:字符串的首地址
功能:计算字符串不包含'\0'的长度
执行逻辑:
    获取到字符串的首地址后,从首地址开始,记录字符串的长度遇到'\0',函数停止运行。
    


#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[100];
    gets(str);
    printf("%ld\n",strlen(str));  //11字符串不包含'\0'的大小
    return 0;
}
                

自己实现strlen函数

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[100];
    gets(str);
    int len=0;
    int i=0;   //定义了一个循环变量i从0开始
    //自己实现strlen函数
    while(str[i]!='\0')
    {
    i++;  //循环字符数组中的每一个字符
    len++; //记录字符数组的长度
    }
    printf("%d\n",len);
    return 0;
}

(2)strcpy函数

注意:

使用strcpy函数时,目标数组必须足够长,容纳下源数组中的内容。

dest数组必须足够长,容纳下src数组中的内容

函数原型:
char *strcpy(char *dest, const char *src);
返回值:目标字符串的首地址
参数:dest数组的首地址,src数组的首地址
功能:将src数组中的内容跟,拷贝到dest数组中覆盖掉dest原有的内容
执行逻辑:
    从src数组的首地址开始,将每一个数组中的元素拷贝到dest数组中对应下标的位置,直到遇到'\0',将'\0'拷贝过去后,结束


#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[100]="hello";
    char str1[20]="hello world";
    strcpy(str,str1);  //使用strcpy函数,将str1字符串拷贝到str中
    puts(str);
    return 0;
}

自己实现strcpy函数

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[100]="hello";
    char str1[20]="hi";
    int i=0;
    //拷贝要保证源字符串的每一位都拷贝到目标字符串中
    //循环应该保证源字符串的每一位都进入循环
    while(str1[i]!=0)
    {
        str[i]=str1[i];
        i++;  //第i位拷贝结束后,继续拷贝第i+1位 
    }
    //退出while循环时,说明str1走到了'\0'
    //再将'\0'赋值给str的第i位
    str[i]=str1[i]; //赋结尾的'\0'
    puts(str);
    return 0;
}

(3)strcat函数

目标字符串一定要足够长容纳下strcat拼接后的结果。

函数原型:
char *strcat(char *dest, const char *src);
dest表示目标字符串,src表示源字符串
返回值:目标字符串的首地址
参数:目标字符串的首地址,源字符串的首地址
执行逻辑:
    从源字符串的首地址出发,将源字符串中的每一个字符拼接到目标字符串的后面。

如果自己实现步骤:
1、找到目标字符串'\0'的位置
2、从目标字符串'\0'的位置开始,将源字符串中的每一位拼接过去



#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[20]="hello";
    char str1[10]=" world";

    //将str1数组,拼接到str数组后面
    strcat(str,str1);
    puts(str);   //"hello world";
    return 0;
}

自己实现strcat函数

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[20]="hello";
    char str1[10]=" world";

    //自己实现strcat
    int i=0,j=0;
    //1、找到目标字符串'\0'的位置
    while(str[i]!=0)
    {
        i++;
    }
    //当退出循环时,str[i]=='\0'
    //将源字符串中的每一位,拼接到目标字符串'\0'开始的每一个位置
    while(str1[j]!='\0')
    {
        str[i]=str1[j];
        i++;
        j++;
    }
    //当第二个while循环退出时,说明源字符串也走到了'\0'
    str[i]=str1[j];
    puts(str);
    return 0;
}

(4)strcmp函数

函数原型:
int strcmp(const char *s1, const char *s2);
返回值:ASCII码差值
参数:比较的字符串

执行逻辑:
    从两个字符串的首元素开始比较,如果相同继续向后比较,直到'\0',这种情况下会返回0,如果遇到某一位不同,立刻返回ASCII码差值(s1[i]-s2[i])并结束函数。


#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[10]="hello";
    char str1[10]="hel";

    printf("%d\n",strcmp(str,str1)); //108是,'l'-'0'的值
    return 0;
}

自己实现

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    char str[10]="hello";
    char str1[10]="hel";

    int i=0;
    //判断何时两个字符串一直往下走找下一位
    //当两个字符串下标为i的位置相等,并且都不为0时
    while(str[i]==str1[i]&&str[i]!=0)   //'\0'的ascii码就是0
    {
        i++; //向后比较下一位
    }
    //如果不满足循环条件,说明两个字符串的第i位不相等
    //或者是两个字符串的第i位相等,但是都是'\0'
    int ret = str[i]-str1[i];
    printf("%d\n",ret);
    return 0;
}

(5)memset函数

用作内存置位(以字节为单位进行内存置位)

函数原型:
void *memset(void *s, int c, size_t n);
返回值:地址
参数:要置位的起始地址,要置什么数值,置多少个字节
功能:给指定地址开始的n个字节内的,数据置为c

(6)bzero函数

内存置0,以字节为单位

函数原型:
void bzero(void *s, size_t n);
返回值:地址
参数:要置位的起始地址,要置多少个字节
功能:给内存置0

五、二维字符数组

5.1格式

int arr[行数][列数];

5.2访问数组中的元素

通过行标和列标去访问
数组名[行标][列标];
行标最小为0,最大为:行数-1
列标最小为0,最大为:列数-1

二维数组中元素的个数=行数*列数

5.3二维数组的初始化和赋值

#include <stdio.h>
int main(int argc, const char *argv[])
{
    int arr[2][3]={1,2,3,4,5,6};  //类似于一维数组的完全初始化方式
    //二维数组以行为单位的初始化并且是不完全初始化,未初始化的部分默认为0
    int arr1[2][3]={
  
  {1,2},{4,9}};
    //二维数组省略行数的初始化
    int arr2[][2]={1,2,3,4,5};
    printf("%ld\n",sizeof(arr2));
    //int arr3[2][]={1,2,3,4,5};
    //error二维数组不能省略列数初始化,只能省略行数初始化
    
 arr1[0][2]=3;  //给arr1数组中第一行第三列的元素赋值为3
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值