欢迎光临
我们一直在努力

C语言:字符数组

字符数组

再C语言中支持字符串常量,不支持字符串变量。如果想要实现类似的字符串变量,C语言提供了两种实现方式:

  • 字符数组:

     char name[] = "哪吒";

  • 字符指针

     char *name = "哪吒";

概念

元素类型位char(字符型)的数组叫做字符数组。字符数组本质上是为了存储字符串数据(注意,C语言中字符是字节字符(1字符=1字节,C语言中没有字节这个表示法,我们一般使用char表示字节:1char = 8bit))。

硬件中存放数据以bit(位)为单位,系统对于内存的操作以char(字节)为单位。系统为内存以1个字节为单位进行编号(编号是内存地址)

实验

 char a = 'A';     // 正确 字符
 char b = '1';     // 正确 字符
 char c = 1;       // 正确 ASCII码
 char d = '\\n';    // 正确 只要其对应的ASCII码的范围在0~127之间,都属于字符
 char e = "A";     // 错误 双引号括起来的内容叫做字符串常量
 char f = '和';    // 错误 char类型仅占1个字节,而中文字符(如GBK/UTF-8 编码)至少占2字节/3字节,无法用单个char存储;且中文的编码值超出0~127

语法

一维数组:

 char 数组名[数组容量];

二维数组:

 char 数组名[行容量][列容量];

字符数组的语法于之前学的数组语法区别仅在于数据类型是char而已。

注意:所有类型数组初始化都可用0填充。字符串char数组初始化时,没有完全初始化的时候,使用\\0或者0填充(\\0仅起到一个占位或者标识的作用,无法通过printf等打印输出到控制台的)。

示例

 char c[8] = {'h','e','l','l','o'};
// 一维的字符数组的初始化,未初始化部分补\\0 或者 0 等价与下面写法
 char c[8] = {'h','e','l','l','o','\\0','\\0','\\0'};

案例
案例1:输出一个字符序列:I LOVE YOU
  • 代码

     #include <stdio.h>
     ​
     // 输出一个字符序列:I LOVE YOU
     void test1()
     {
      // 创建一个数组,用来存储 I LOVE YOU 空格' ' 也是字符,对应的ASCII是32
      char arr[] = {'I',' ','L','O','V','E', 32 ,'Y','O','U'};
     
      // 计算数组的容量
      int len = sizeof(arr) / sizeof(arr[0]);
     
      // 遍历数组
      for (int i = 0; i < len; i++) printf("%c",arr[i]); printf("\\n");
         return 0;
     }

  • 结果

     I LOVE YOU

案例2:输出一个用字符*组成的空菱形图案
  • 代码

     #include <stdio.h>
     ​
     // 一维数组:输出一个字符序列:I LOVE YOU
     void test1()
     {
      // 创建一个数组,用来存储 I LOVE YOU 空格' ' 也是字符,对应的ASCII是32
      char arr[] = {'I',' ','L','O','V','E', 32 ,'Y','O','U'};
     
      // 计算数组的容量
      int len = sizeof(arr) / sizeof(arr[0]);
     
      // 遍历数组
      for (int i = 0; i < len; i++) printf("%c",arr[i]); printf("\\n");
     }
     ​
     // 二维数组:输出一个用字符`*`组成的空菱形图案
     void test2()
     {
      // 创建一个二维的字符数组,存放菱形
      char arr[5][5] = {
      {' ',' ','*',' ',' '},
      {' ','*',' ','*',' '},
      {'*',' ',' ',' ','*'},
      {' ','*',' ','*',' '},
      {' ',' ','*',' ',' '}
      };
     
      // 计算行和列的容量
      int row_len = sizeof(arr) / sizeof(arr[0]);
      int col_len = sizeof(arr[0]) / sizeof(arr[0][0]);
     
      // 遍历数组
      for (int i = 0; i < row_len; i++)
      {
      for (int j = 0; j < col_len; j++) printf("%c",arr[i][j]); printf("\\n");
      }
     
      printf("\\n");
         
         return 0;
     }

  • 结果

      *
      * *
     *   *
      * *
      *

注意:

  • 如果定义时不初始化,元素值不确定(局部作用域)

     char arr1[2];  // 此时,这个数组中元素的值是随机值(垃圾值)
     char arr2[3] = {'a','b','c'}; // 完全初始化(元素个数与数组容量一致)
     char arr3[3] = {'a'};    // 部分初始化,未初始化元素补'\\0'
     char arr4[3] = {};       // 此时所有的元素使用 \\0 填充
     char arr5[3] = {0};      // 此时所有的元素使用 \\0 填充   '\\0' == 0
     char arr6[3] = {'\\0'}    // 等价于上面写法

  • 如果提供的字符个数大于数组长度,则按照语法错误处理(会报警告,但是能编译通过);如果字符个数小于数组长度,后面的元素自动补\\0。

    char arr1[2] = {'h','e','e'};//错误:初始化元素个数超过数组容量,属于未定义行为(UB),编译会报警告,严谨编写此类代码。
     char arr1[3] = {'a'};//正确:部分初始化,未初始化部分自动补 \\0

  • 如果提供的字符个数与数组容量相同,可以省略数组容量,系统会自动确定元素的个数,适合字符较多时。

     char arr1[] = {'b','c','i'};//正确,更具初始化的元素,由系统自动计算元素个数。

字符串结束标志

说明:

  • C语言规定字符串常量以\\0作为结束标志

  • 编译系统对字符串常量自动添加一个\\0作为结束标志。char *name = "tom",实际存储为{'t','o','m','\\0'}。

  • 程序中往往通过判断\\0来检测字符串是否结束。

  • \\0的ASCII码时0,不是一个可显示可输出的字符,是“空操作符”。不会增加有效字符,仅仅用作给工程判别的标志或者在数组中占位。

    char a1[] = {'h','i'};
     printf("%c%c",a1[0],a1[1]);  // 输出:hi
     printf("%s",a1);    // 错误,因无`\\0`会越界访问,属于未定义行为(可能输出乱码/崩溃)
     ​
     char a2[] = {'h','i','\\0'};  
     printf("%s", a2); // 输出:hi   sizeof(a2) 返回3字节
     ​
     char c[] = "hello";  
     printf("%s",c);   // 输出:hello     sizeof(c) 返回6字节

字符数组的多样表示:

char数组可以以数组的形式一个一个输出每个字符;也可以以字符串形式整体输出。

 #include <stdio.h>
 ​
 int main()
 {
 // 方式1:手动逐个字符初始化,需手动添加`\\0`(否则不是合法字符串)
  char s1[] = {'h','e','l','l','o',' ','w','o','r','l','d','\\0'};  // 字符串必须 \\0结束
  // 方式2/3:字符串常量初始化(推荐),编译器自动加`\\0`(以下两种写法等价)
  char s2[] = "hello world";  // 最简写法
  char s3[] = {"hello world"};// 与s2等价,多一层{}无意义,不推荐
 
  // 字符串的第1种输出:
  printf("s1=%Lu,s2=%Lu,s3=%Lu\\n", sizeof(s1), sizeof(s2), sizeof(s3)); // s1=12,s2=12,s3=12
 
  // 计算数组大小
  int len = sizeof(s3) / sizeof(s3[0]);
 
  // 遍历
  for (int i = 0; i < len; i++)
  {
  // 过滤 \\0
  if (s1[i] == 0 || s2[i] == '\\0' || s3[i] == 0) continue;
 
  printf("%c,%c,%c\\n",s1[i],s2[i],s3[i]);
  }
 
  printf("\\n");  
 
  // 字符串的第2种输出:
  printf("%s,%s,%s\\n", s1, s2, s3);
  printf("\\n");
 
     return 0;
 }

结果:

 s1=12,s2=12,s3=12
 h,h,h
 e,e,e
 l,l,l
 l,l,l
 o,o,o
  , ,
 w,w,w
 o,o,o
 r,r,r
 l,l,l
 d,d,d
 ​
 hello world,hello world,hello world

注意:

  • 字符串的长度不一定等于字符数组的长度

    示例:

     char name[] = "hello";

    解释:

    • 数组长度(sizeof(name)):6,包含'h'/'e'/'l'/'l'/'o'/'\\0'

    • 字符串长度(strlen(name)):5,仅统计\\0之前的有效字符,需包含<string.h>头文件

  • 利用字符串常量可以对字符串数组进行初始化,但不能用字符串常量来对字符数组赋值。(因为C语言规定数组名是常量,无法通过数组名进行赋值)

赞(0)
未经允许不得转载:171主机测评 » C语言:字符数组
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址