5.3 字符数组&字符串

字符数组与字符串的概念

字符数组:元素为字符类型的数组
字符串:最后一个元素以'\0'或整数0(是整数0,而不是字符'0')结束的字符数组,可以用字符串函数做运算。
0标志着字符串的结束,但他不是字符串的一部分,计算字符串长度时不包含这个0.

char word[]={'H','e','l','l','o','!'};
//这就是一个字符数组,存储长度=数组长度=6,有效长度为6
char word2[]={'H','e','l','l','o','!','\0'};
//以'\0'结束则变成了一个字符串,可以以字符串的方式做计算,本质上还是数组,存储长度=数组长度=7,有效长度为6。
char word2[]={'H','e','l','l','o','!',0};
//这样也是一个字符串,但是0表示整数0,占2或4个字节,'\0'必然占一个字节  

字符数组的定义与初始化

完全初始化

char c[3]={'a','b','c'}

不完全初始化

char c[5] = {'a','b'}

其余元素会自动赋一个空字符'\0'

c[0] c[1] c[2] c[3] c[4]
'a' 'b' '\0' '\0' '\0'

其他

可以不用填写元素个数,这样编译器会自动认为这个字符数组元素个数为3个

char c[]={'a','b','c'}

虽然说字符数组不要求最后一个字符为'\0',甚至可以不包括'\0',但是我们为了能用字符串的方式操作字符数组,通常在末尾加个'\0'

特殊的字符数组初始化方式(字符串)

//char *str = "Hello"后续介绍
char words[] = {"Hello"};//编译器会自动补'\0',导致数组长度为6
char word[] = "Hello";//编译器会自动补'\0',导致数组长度为6  

等价写法:
char word[]={'H','e','l','l','o','\0'}
//等价于后边加一个'\0'的写法
char line[10] = "Hello";//编译器会自动补5个'\0'

字符数组的引用

普通引用

和普通数组一样
数组名[下标]引用

指针变量引用【重难点!!!】

指针和数组有着密切的联系,而字符串在存储上是字符数组。所以指针和字符串有着天然联系。

# include <stdio.h>
int main(void)
{
    char word[]="I love China!";
    printf("方法1: %s\n",word);//法1

    char * string1 = "I love China!"; 
    printf("方法2: %s\n",string1);//法2


    char * string2;
    string2 = word;
    printf("实验: %s\n",string2);//可以看出字符指针变量名和字符数组名性质一样

    /*
        "I love China!"是一个字符串,但本质上是一个字符数组。
        可以用数组的方式进行操作
        方法1 就是利用字符串的数组特性,通过数组名进行引用,输出字符串。

        方法2 
        字符指针变量 string1 是 char * 类型  
        表示string1可以存放的是一个 char 类型数据的地址。
        如果指向字符串,它存放的就是字符串的首地址。  
        所以这个字符指针变量的名字和数组名一样,都是存放首地址的。
        由于我们知道字符串有一个特性就是结尾是'\0'
        所以即使只存放一个首地址,指针也能指向整个字符串,因为它知道什么时候该结束!
    */

    return 0;
}

字符数组的输入输出

格式声明

单个字符输入输出: %c
以字符串格式输入输出: %s

输出示例

int main(void)
{
    char a[]={'A','P','\0','a','o'};
    int i;
    printf("%s\n",a);
    for(i=0;i<5;++i)
    {
        printf("%c",a[i]);
    }
    printf("\n");

    return 0;
}
//输出结果
AP
AP ao

注意

  1. 输出字符不包含'\0',这只是一个结束的标志或记号
  2. 以%s格式输出,中间遇到'\0'就会停止输出,不管数组有多长
  3. 多个'\0',遇到第一个就停止

输入示例

1. 一个字符串
int main(void)
{
    char a[10];
    scanf("%s",a);
    
    int i;
    
    for(i=0;i<5;++i)
    {
        printf("%c",a[i]);
    }
    printf("\n");

    return 0;
}
//运行后
输入:hello(回车后系统自动加一个'\0')
输出:hello

2. 多个字符串

int main(void)
{
    char a[10];
    char b[10];
    char c[10];
    scanf("%s%s%s",a,b,c);
    printf("%s%s%s",a,b,c);
    return 0;
}
//运行后
输入:how(空格)are(空格)you
输出:howareyou

注意:
scanf 用在输入字符串就不要加取地址符&了,因为数组的数组名本身就是数组元素的首地址

字符串

字符串的定义初始化

char *str = "Hello";
char word[] = "Hello";
char line[10] = "Hello";//占6个位置,编译器会自动补个0

字符串处理函数

1. puts——输出字符串函数

int main(void)
{
    char c[]= "China";
    printf("%s",c);
    printf("_____");
    puts(c);
    printf("_____");
    
    return 0;
}
//输出:
China_____China
_____

可见
puts 把结束的'\0'转换成了'\n'来输出,也就是说puts输出后会自动换行

2. gets——输入字符串函数

gets的作用是输入一个字符串,并返回该字符串的首地址

int main(void)
{
    char c[10];
    printf("%o\n",gets(c));   
    return 0;
}
//输出:
how
30377026

注意:
puts和gets只能输入一个字符串,不能同时输入多个

3. strcat——字符串连接函数

把字符串2 连接到字符串1 末尾

int main(void)
{
    char a[30]="How are ";
    char b[5]="you";
    strcat(a,b);
    printf("%s",a);   
    return 0;
}
//输出:
How are you

注意:
要存放连接结果的那个字符串也就是字符串1,一定要足够长。
连接前,字符串1后面后很多空的'\0',连接后全部取消,字符串2末尾的多个'\0'保留。

4. strcpy和strncapy——字符串复制函数

作用:把字符串2 的内容复制给字符串1

int main(void)
{
    char str1[10]="1111111111";
    char str2[10]="world";

    printf("复制前str1:%s",str1); 
    strcpy(str1,str2);

    printf("\n复制后str1:\n");
    int i;  
    for(i=0;i<10;++i)
    {
        printf("%c",str1[i]);
    }
    printf("\n");   
    return 0;
}
//输出:
复制前str1:1111111111
复制后str1:
world 1111

注意

一、要存放复制结果的那个字符串也就是字符串1,一定要足够长,其长度不应小于字符串2
二、字符串1的位置应该是一个数组名,字符串2 的位置可以是一个字符串常量
strcpy(str1,"hello");
三、复制字符串2时连同其结尾的一个'\0',长度记作A(A=有效字符个数+1,如上述例子就是'w','o','r','l','d','\0'共6个,A=6),覆盖字符串1的前A个字符,其余字符保持原来的值。

错误

char a[5];
char b[5]="abc";
a=b;

a,b都是一个字符数组名,是一个地址常量,不能改变值。 只能通过strcpy、strncpy函数进行赋值。

strncpy
指定字符串2的前n个字符复制到字符串1里

int main(void)
{
    char str1[10]="1111111111";
    char str2[10]="world";

    printf("复制前str1:%s",str1); 
    strncpy(str1,str2,3);

    printf("\n复制后str1:\n");
    int i;  
    for(i=0;i<10;++i)
    {
        printf("%c",str1[i]);
    }
    printf("\n");   
    return 0;
}
//输出:
复制前str1:1111111111
复制后str1:
wor1111111

可以看见这次复制字符串2的时候没有'\0'

5. strcmp——字符串比较函数

用法

char str1[]="APP";
char str2[]="APPLE";
strcmp(str1,str2);
strcmp("APP","APPLE");
strcmp(str1,"APPLE");

字符串比较规则:
将两个字符串自左至右逐个字符比较(按ASCII字符的大小比较),直到遇到不同字符,或者出现'\0'为止

如果字符全部相同,则认为两个字符串相等,函数值为0 若字符不完全相同,则以第一对不相同的字符为准,若字符串1>字符串2,返回正整数;字符串2>字符串1,返回负整数。

int main(void)
{
    char str1[]="APP";
    char str2[]="APPLE";
    printf("%d\n",strcmp(str1,str2));
    return 0;
}
//结果
-1

注意

一、英文小写字母 > 英文大写字母
二、两个字符串都是全英文构成,则按照它们在字典中的大小比较,按字母顺序,在字典后边的大于在字典前面的,同时注意小写>大写
三、不能用数组名直接比较大小,数组名代表的是字符串首地址,无实际大小含义。

6. strlen——测字符串长度的函数

int main(void)
{
    char str1[10]="APP";
    printf("%d\n",strlen(str1));
    return 0;
}
//结果
3

很明显只输出有效字符个数

7. strlwr和strupr——字符串大小写转换函数

strlwr —— 将字符串大写字母全部转成小写 strupr —— 将字符串小写字母全部转成大写

int main(void)
{
    char str1[10]="APP";
    char str2[]="Apple";
    printf("%s\n",strlwr(str1));
    printf("%s\n",strupr(str2));
    return 0;
}
//结果
app
APPLE

注意

字符串处理函数是库函数,并不是C语言本身的组成部分,而是各编译系统为方便用户使用提供的公共函数,不同编译系统在函数名和使用方法上可能会不同,但常用的几个都一样。
使用字符串函数先把头文件string.h包含进来

本文章使用limfx的vsocde插件快速发布