字符数组的各种姿势

  • 字符数组的定义[1]
  • 字符数组的初始化[1]
  • 字符数组的引用[1]
  • 字符数组的遍历
  • 字符数组的输入输出[1]
  • 字符串与字符数组的结束标志[1]
  • 字符串的各种操作
  • 字符串[2]
  • 字符串的输入输出[2]
    • 字符串的输入[2]
    • 字符串的输出[2]
  • 字符串常用方法[2]
    • 计算字符串的长度
    • 字符串拼接
    • 字符串拷贝
    • 字符串比较
    • 字符串数组
  • 参考资料

字符数组的定义[1]

字符数组可以是一维、二维或多维数组。例如:

#include
void main()
{
    char CharArry_1[num1]; //一维数组定义
    char CharArray_2[num1][num2]; //二维数组定义
    char CharArray_3[num1][num2][num3]; //三维数组定义
    // ...
    char CharrArray_N[num1][num2]...[numN]; //N维数组定义
}

形象的理解:

一维数组:
字符数组的各种姿势_第1张图片
二维数组:
在这里插入图片描述
N维数组:
字符数组的各种姿势_第2张图片用万能的excel表格来说,就是
字符数组的各种姿势_第3张图片

字符数组的初始化[1]

为什么要对字符数组进行初始化呢?
回答:无论是什么,在C中定义只是划分区域(在内存中):分配储存位置。

字符数组也允许在定义时作初始化赋值。例如:

#include
void main()
{
    char CharArry_1[10]={'c', '  ', 'p', 'r', 'o', 'g', 'r', 'a','m'}; //一维数组初始化

}

赋值后各元素的值为:
c[0]的值为‘c’
c[1]的值为‘ ’
c[2]的值为‘p’
c[3]的值为‘r’
c[4]的值为‘0’
c[5]的值为‘g’
c[6]的值为‘r’
c[7]的值为‘a’
c[8]的值为‘m’
一维数组:
字符数组的各种姿势_第4张图片
其中c[9]未赋值,由的值为‘p’系统自动赋予0值。当对全体元素赋初值时也可以省去长度说明。
例如:
char c[]={‘c’, ’ ', ‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’, ‘m’ };
这时C数组的长度自动定为9。

注意:程序员计数,都是从0开始数!!
为什么?
回答:计算机的二进制 0-1

字符数组的引用[1]

字符数组和普通数组一样,也是通过下标引用。

【例7-8】输出字符数组中的元素。

#include 
int main(void)
{
    int i,j;
    char a[][5]={{'B','A','S','I','C',},{'d','B','A','S','E'}};
    for(i=0;i<=1;i++)
    {
        for(j=0;j<=4;j++)
            printf("%c",a[i][j]);
        printf("\n");
    }
    return 0;
}

本例的二维字符数组由于在初始化时全部元素都赋以初值,因此一维下标的长度可以不加以说明。

字符数组的遍历

循环是一个非常有潜力的结构!!
注意:什么是结构?
回答:一种运算就是一种结构!!

回到循环结构上来:

#include
void main()
{
    char CharArry_1[num1]; //一维数组定义
    for(int i=0;i<num1;i++)
    {
       scanf("%c",CharArry_1 + i);
       printf("%c",CharArry_1 + i);
    }
}

延申:计算复杂度
上面的循环与下面的循环,有哪里不同

#include
void main()
{
    char CharArry_1[num1]; //一维数组定义
    for(int i=0;i<num1;i++)
    {
       scanf("%c",CharArry_1[i]);
    }
    
     for(int i=0;i<num1;i++)
    {
       printf("%c",CharArry_1[i]);
    }
}

思路回来:
上面说了一重for循环,
对于二维字符数组,循环怎么走?

#include
void main()
{
    char CharArry_2[num1][num2]; //二维数组定义
    for(int i=0;i<num1;i++)
    {
       for(int j=0;j<num2;j++)
       {
          scanf("%c",CharArry_1 + i);
          printf("%c",CharArry_1 + i);
       }
    }
}

同理,对N维数组的循环的走法,也可以这么写。

字符数组的输入输出[1]

【例7-9】使用printf()输出整个字符数组。

#include 
int main(void)
{
    char c[]="BASIC\ndBASE";
    printf("%s\n",c);
    
    return 0;
}

注意在本例的printf函数中,使用的格式字符串为“%s”,表示输出的是一个字符串。
【例7-10】使用 scanf() 从控制台输入一个字符串,然后使用 printf() 将其输出。

#include 
int main(void)
{
    char CharArray[15];
    printf("input string: ");
    scanf("%s",CharArray);
    printf("your string is: %s\n",CharArray);
    
    return 0;
}

本例中由于定义数组长度为15,因此输入的字符串长度必须小于15,以留出一个字节用于存放字符串结束标志\0。应该说明的是,对一个字符数组,如果不作初始化赋值,则必须说明数组长度。还应该特别注意的是,当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。


字符串与字符数组的结束标志[1]

在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。前面介绍字符串常量时,已说明字符串总是以’\0’作为串的结束符。因此当把一个字符串存入一个数组时,也把结束符’\0’存入数组,并以此作为该字符串是否结束的标志。有了’\0’标志后,就不必再用字符数组的长度来判断字符串的长度了。

C语言允许用字符串的方式对数组作初始化赋值。例如:

 char c[]={'c', ' ','p','r','o','g','r','a','m'};

可写为:

 char c[]={"C program"};

或去掉{}写为:

 char c[]="C program";

用字符串方式赋值比用字符逐个赋值要多占一个字节, 用于存放字符串结束标志’\0’。上面的数组c在内存中的实际存放情况为:
在这里插入图片描述
‘\0’是由C编译系统自动加上的。由于采用了‘\0’标志,所以在用字符串赋初值时一般无须指定数组的长度, 而由系统自行处理。
再说一下ASCII码:
0 、 ‘0’ 、 “0” 、 ’\0’ 区别


思路再回到我们的对字符串的输入:
当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。
那么对于含有空格的字符串来说,怎么输入呢?
【例7-11】含有空格的字符串的输入

#include 
int main(void)
{
    char st1[6],st2[6],st3[6],st4[6];   
    scanf("%s%s%s%s",st1,st2,st3,st4); //设置四个数组 输入的一行字符的空格分段分别装入四个数组
    
    printf("input string:");
    printf("your string: %s %s %s %s\n",st1,st2,st3,st4);// 打印输出时,将空格补上
    return 0;
}

本程序分别设了四个数组, 输入的一行字符的空格分段分别装入四个数组。然后分别输出这四个数组中的字符串。在前面介绍过,scanf的各输入项必须以地址方式出现,如 &a、&b 等。但在前例中却是以数组名方式出现的,这是为什么呢?

这是由于在C语言中规定,数组名就代表了该数组的首地址。整个数组是以首地址开头的一块连续的内存单元。

字符数组的各种姿势_第5张图片

数组名CharArray就代表这个首地址。因此在CharArray前面不能再加地址运算符(取地址)&
如写作scanf("%s",&CharArray);则是错误的。在执行函数printf("%s",CharArray) 时,按数组名CharArray找到首地址,然后逐个输出数组中各个字符直到遇到字符串终止标志’\0’为止。

字符串的各种操作

字符数组与字符串,难以割舍的关系!

C语言学的程度,在于掌握库的多少!

字符串[2]

  • 用双引号引起来的就是字符串,字符串由字符组成
  • 字符串使用%s格式化输出
  • 字符串以\0结尾,没有\0就不是字符串
  • 只要是用双引号括起来的都是字符串
  • 字符串的本质就是数组
    注意: 字符串变量和普通的字符数组有一定的区别,C语言规定,字符串必须以\0结尾(作为字符串的结束符号),所以字符串变量的元素个数比字符数组的元素多一个\0
#include 

int main(int argc, const char * argv[]) 
{
    
    char name[] = "zhangsan";
    
    // %u 表示无符号,sizeof 返回的是一个无符号长整型
    printf("name --> %s  size --> %lu\n", name, sizeof(name)); // name -> zhangsan size->9
    
    // 字符串本质就是一个字符数组,前提是末尾以\0结尾
    char name1[] = {'z', 'h', 'a', 'n', 'g', 's', 'a', 'n', '\0'};
    printf("name1 --> %s\n", name1);    // name1 --> zhangsan
    
    // 部分初始化中,没有被初始化的元素默认是0, \0 对应的ASCII值是 0
    char name2[9] = {'z', 'h', 'a', 'n', 'g', 's', 'a', 'n'};
    printf("name2 --> %s\n", name2);    // name2 --> zhangsan
    
    // 字符串的本质就是数组
    char name3[] = "lisi";
    printf("name3 --> %s \n", name3);   // name3 --> lisi
    name3[0] = 'x';
    printf("name3 --> %s \n", name3);   // name3 --> xisi
    

    return 0;
}

字符串的输入输出[2]

字符串的输入[2]

#### 字符串输入
字符串输入可以使用 scanf 和 gets 进行输入,各有利弊

  • 输入字符串
    • 使用scanf的%s占位符接收键盘输入的字符串
    • scanf 接收字符串,会以空格,tab,回车作为结束符号,利用scanf接收字符串时,字符串不能出现空格,tab,回车
  • 使用gets接收字符串

#include
void main()
{
   // scanf
    printf("请输入一个字符串:\n");
    char buf[10];
    scanf("%s", buf);   // 输入:fdsa fdas
    printf("buf --> %s\n", buf);    // buf --> fdsa
   
   // gets
    char buf[10];
    printf("请输入一个字符串,使用gets接收:\n");
    gets(buf);
    printf("buf --> %s\n", buf);    // buf --> fdsaf fdsa
}

字符串的输出[2]

字符串输出可以使用printf 和 puts 进行输出,各有利弊

 输出字符串
	 * 使用printf的%s占位符输出
		* 弊端:如果想要换行,必须加上\n
		* 优点:可以自定义格式化需要的字符串,也就是可以按照我们需要的格式来输出
	 * 使用puts函数进行输出
		* 优点:可以自动换行
		* 缺点:不可以自定义格式,只能原样输出
#include
void main()
{
   // printf
   char CharArray[] = “lisi”;
   printf(“name = %s!!!\n”, CharArray);
   printf("-----\n");

   // puts
  // 自动换行,只能原样输出
   puts(CharArray);
   printf("----\n");
}


字符串常用方法[2]

计算字符串的长度

#include   //stdio头文件 基本输入输出操作
#include  //想要对字符串进行调用函数,必须调用string头文件 内含丰富、功能强大的库函数

// 申明函数
int stringLen(char value[]); 

int main(int argc, const char * argv[]) {
    
    char String[] = "IamString!";
    
    // 计算字符串的长度,不包括末尾\0的长度
    
    // 调用系统内置函数strlen 计算字符串的长度,需要先导入 string.h 头文件
    size_t length = strlen(string);     // lenght -->10
    printf("lenght --> %lu\n", length);
        
    // 自定义计算字符串长度的函数
    int length2 = stringLen(string);
    printf("length2 --> %i\n", length2);    // length2 --> 10
    return 0;
}

// 自定义计算字符串长度的函数
int stringLen(char value[])
{
    int count = 0;
    
    while (value[count] != '\0') 
      { count ++; } 
        
    return count;
}

字符串拼接

在这里插入图片描述
使用内置方法strcat进行2个字符串拼接,将后者拼接到前者后面,前提是前者空余的长度要大于后者的长度,否则会报错
使用内置方法strncat进行2个字符串拼接,可以指定将后者的前多少个字符与前者进行拼接

#include
#include
void mian()
{
   // 字符串拼接
   char str1[20] = "hello";
   char str2[10] = " world"; //注意哟,开头有一个空格

   printf("str1拼接前 --> %s\n", str1);        // str1拼接前 --> hello
   printf("str2拼接前 --> %s\n", str2);        // str2拼接前 -->  world
   strcat(str1, str2);
   printf("\n");
   printf("str1拼接后 --> %s\n", str1);        // str1拼接后 --> hello world
   printf("str2拼接后 --> %s\n", str2);        // str2拼接后 -->  world

  // 使用 strncat 可以指定将后者的前多少个字符与前者进行拼接
   strncat(str1, str2, 3);		// 最后一个参数3表示指定str2的前多少个字符拼接到str1后面
   printf("str1拼接后 --> %s\n", str1);        // str1拼接后 --> hello world wo
   printf("str2拼接后 --> %s\n", str2);        // str2拼接后 -->  world
}

字符串拷贝

strcpy 函数会将源的数据拷贝到目录中,并且会覆盖掉目标中原有的数据,目标的长度必须能够存放拷贝的数据,长度不够会报错
strncpy 函数在strcpy函数的基础之上,增加一个参数,可以指定拷贝几个字符0

#include
#include
void main()
{
   // 将str2中的内容拷贝到str1中
    char str1[20] = "hello"; 
    char str2[] = " world!"; //注意哟,开头有一个空格

    printf("str1 拷贝前 --> %s\n", str1);      // str1 --> hello
    printf("str2 拷贝前 --> %s\n", str2);      // str2 -->  world!
    strcpy(str1, str2);
    printf("str1 拷贝后 --> %s\n", str1);      // str1 -->  world!
    printf("str2 拷贝后 --> %s\n", str2);      // str2 -->  world!

  // strncpy 函数在strcpy函数的基础之上,增加一个参数,可以指定拷贝几个字符
   char str3[20] = "hello";
   char str4[] = "_world!";
   strncpy(str3, str4, 2);
   printf("str3 拷贝后 --> %s\n", str3);      // str3 拷贝后 --> _wllo
   printf("str4 拷贝后 --> %s\n", str4);      // str4 拷贝后 --> _world!
}

字符串比较

strcmp 会对传入的字符串进行比较,比较完毕后会返回一个整型的值

#include
#include
void main()
{
   /*
	 int result = strcmp(str1, str2)
	 如果result等于0,证明两个字符串相等
	 如果result小于0,证明str1小于str2
	 如果result大于0,证明str1大于str2
  */

    char str1[] = "abc";
    char str2[] = "abc";
    int result = strcmp(str1, str2);
    printf("result --> %i\n", result);  // result --> 0

    char str1[] = "ab1";
    char str2[] = "abc";
    int result = strcmp(str1, str2);
    printf("result --> %i\n", result);  // result --> -50

    char str1[] = "absadsa";
    char str2[] = "abc";
    int result = strcmp(str1, str2);
    printf("result --> %i\n", result);  // result --> 16
}

字符串数组

如果想存储一堆字符串可以使用字符串数组,字符串数组就是二维数组

#include
void main()
{
   char names[5][20] = {
	    "zhangsan",
	    "lisi",
	    "wangwu",} 
}

参考资料

[1] C语言字符数组及其应用
[2] 字符串和字符串数组
[3] 0 、 ‘0’ 、 “0” 、 ’\0’ 区别

你可能感兴趣的:(程序语言)