浅谈字符数组

简介: 浅谈字符数组

一、什么是字符数组

  • 字符数组就是建立一连串的字符存储空间用来存储字符,多个字符也就形成了字符串。
  • 字符数组中的一个元素用来存放一个字符,数组定义、元素赋值等操作类似于整形数组,但是字符数组的赋值方式多了一种(下面详细讲)

二、字符数组的定义和赋值

1. 先定义一个数组,再为挨个元素进行赋值

这种定义方式的缺点是挨个赋值的代码量太多,没有太多意义,降低了可读性。

char c[10];
c[0]=’I’;   c[1]=’ ’;
c[2]=’a’;   c[3]=’m’;
c[4]=’  ’;   c[5]=’h’; 
c[6]=’a’;  c[7]=’p’; 
c[8]=’p’;  c[9]=’y’;

存储的结构如下:

2. 在定义的同时给该字符数组进行初始化

2.1 错误的初始化方式

//错误的初始化方式:
char c[10]={’I’,’ ’,’a’,’m’,’ ’,’h’,’a’,’p’,’p’,’y’};

存储的结构如下:

注意: 该赋值的方式是错误的,因为如果不是用字符串的形式命名,需要在结尾加一个’\0’。

2.2 正确的初始化方式

//正确的初始化方式
char c[10]={’c’,’ ’,’p’,’r’,’o’,’g’,’r’,’a’,’m’,0};

存储的结构如下:

重点:

*对比了正确的初始化方式和错误的初始化方式,我们可以从他们对应的存储结构上看到,正确的初始化方式多个’\0’。


为什么少了个’\0’就会差别这么呢?

这就涉及了字符串和字符串结束标志

(1)在C语言中,是将字符串作为字符数组来处理的

(2)关心的是字符串的有效长度而不是字符数组的长度 (有效长度 == 实际长度)

(3)为了测定字符串的实际长度,C语言规定了字符串结束标志 ’\0’

(4)’\0’代表ASCII码为0的字符

(5)从ASCII码表可以查到,ASCII码为0的字符不是一个可以显示的字符,而是一个“空操作符”,即它什么也不做。用它作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志

其实相对于上面的正确初始化方式,还有一种将整个字符串赋值给字符数组,代码如下:

char c[]={'I',' ','a','m',' ','h','a','p','p','y'};
//如上的定义初始化方式可以写成下面的三种形式
char c[]={"I am happy"};
//可写成
char c[]="I am happy";
//相当于
char c[11]={"I am happy"};

加深类比:

char c[10]={”China”};
//可写成
char c[10]=”China”;
//从c[5]开始,元素值均为\0

3. 特别注意!!!

3.1 字符数组和整型数组一样不支持隔语句初始化!!!

代码如下:

//此种定义了整型数组后,对他再赋值的方式是错误的!!!
  int a[4] = {1};
  a = { 1,2,3,5,6 };
  //此种定义了字符数组后,对他再赋值的方式是错误的!!!
  char c[5] = { 'a' };
  c = { 'a','b','c' };

三、字符串处理函数

在程序中往往需要对字符串作某些操作处理,两个字符串连接、两个字符串进行比较等在C函数库中提供了一些字符串处理函数,使用很方便。

函数 作用
gets(字符数组) 从终端输入一个字符串到字符数组
puts(字符数组) 将一个字符串(以’\0’结束的字符序列)输出到终端
strcat(字符数组1,字符数组2) 连接两个字符数组中的字符串把字符串2接到字符串1的后面
strcpy(字符数组1,字符串2) 将字符串2复制到字符数组1中去
strcmp(字符串1,字符串2) 比较串1和串2。若串1=串2,则函数值为0;若串1>串2,则函数值为一个正整数;若串1<串2,则函数值为一个负整数
strlen(字符数组) 测试字符串长度
strlwr(字符串) 将字符串中大写字母换成小写字母
strupr(字符串) 将字符串中小写字母换成大写字母

3.1 gets(字符数组)

其一般形式为:strlen (字符数组);它是测试字符串长度的函数,函数的值为字符串中的实际长度。如: gets(str); Computer↙

3.2 puts(字符数组)

puts函数(输出字符串函数)其一般形式为: puts (字符数组);作用是将一个字符串输出到终端,如: char str[20]=”China”;puts(str); 输出China。

3.3 strcat(字符数组1,字符串2)

strcat函数(字符串连接函数)其一般形式为:strcat(字符数组1,字符数组2);其作用是把两个字符串连接起来,把字符串2接到字符串1的后面,结果放在字符数组1中。

char str1[30]=”People”;
char str2[]=”China”;
printf(”%s”, strcat(str1,str2));  
//输出:PeopleChina

3.4 strcmp(字符串1,字符串2)

比较的结果由函数值带回

如果字符串1=字符串2,则函数值为0
如果字符串1>字符串2,则函数值为一个正整数
如果字符串1<字符串2,则函数值为一个负整数

3.5 strlen(字符数组)

char str[10]=”China”;

printf(”%d”,strlen(str));

输出结果是5

也可以直接测试字符串常量的长度

strlen(”China”);

3.6 strlwr(字符串)和strupr(字符串)

其返回值是一个字符指针类型

(1)其一般形式为strlwr (字符串);函数的作用是将字符串中大写字母换成小写字母

(2)其一般形式为strupr (字符串);函数的作用是将字符串中小写字母换成大写字母


四、字符数组和字符指针

4.1 字符型指针

字符型指针用char*定义,它不仅可以指向一个字符型常量,还可以指向一个字符串。

char str[] = "I am happy";
char* c = str;

此时c变量就是存储了str数组的第一个元素的地址,代码如下:

4.2 字符指针作函数参数

(1)如果想把一个字符串从一个函数“传递”到另一个函数,可以用地址传递的办法,即用字符数组名作参数,也可以用字符指针变量作参数。

(2)在被调用的函数中可以改变字符串的内容

(3)在主调函数中可以引用改变后的字符串

例子如下:

例子1:有一字符数组a,内存有字符串"I am a boy.",要求把该字符串复制到字符数组b中。(要求用函数完成实现)

例子2:有字符串a=“I am a teacher.”, 字符串b=“You are a student.”,要求把字符串b连接到字符串a的后面。即字符串a的内容为“I am a teacherYou are a student.”

4.3 调用函数时实参与形参的对应关系

4.4 字符指针和字符数组的差别

虽然用字符数组和字符指针变量都能实现字符串的存储和运算,但它们二者之间是有区别的,不应混为一谈。主要有以下几点:

(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第1个字符的地址),决不是将字符串放到字符指针变量中。

(2)赋值方式:对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值:

char str[14];

str=”I love China!″; (×)

而对字符指针变量,可用下面方法赋值:

char *a;

a=”I love China!″;

但注意赋给a的不是字符,而是字符串第一个元素的地址。

(3)对字符指针变量赋初值:

char *a=”I love China!″; 等价于 char *a;a=”I love China!″;

而对数组的初始化:

char str[14]={”I love China!″};不能等价于char str[14];str[]=”I love China!″;

无论是什么数组都不支持动态赋整条数据,例如int a[];a={1,2,3,4},此赋值方式是错误的!!!

(4)如果定义了一个字符数组,在编译时为它分配内存单元,它有确定的地址。而定义一个字符指针变量时,给指针变量分配内存单元,在其中可以放一个字符变量的地址。

//第一种
char *a; scanf(“%s”,a);   //错
char *a,str[10];      
//第二种
a=str;                  
scanf (“%s”,a);     // 对

说人话就是,指针变量是用来存放地址的,而字符数组是在内存开辟了一个空间来存储字符的,两者的性质就不一样。scanf函数输入的是一个字符串是要放到一个存储空间里面,所以直接用一个存放指针的变量来存放一组字符串就不行了

(5)指针变量的值是可以改变的。

例如:

#include <stdio.h>
void main()
 { char *a="I am Chinese!";
    a=a+6; 
    printf("%s\n",a);
}

其中的char *a=“I am Chinese!”;a=a+6; 不能改成char a[]=“I am Chinese!”;a=a+6;。这里可以理解为数组名是一辆车上的司机,而字符指针变量是一个导游,元素是乘客。导游可以到处走,而司机不可以到处走。

(6)对字符数组可以用下标法和地址法引用数组元素(a[5],(a+5))。如果字符指针变量p=a,则也可以用指针变量带下标的形式和地址法引用(p[5],(p+5))。

(7)字符数组中各元素的值是可以改变的(可以对它们再赋值),但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能对它们再赋值)。如:

char a[]="House";
    char *b="House";
    a[2]='r';   // 对
    b[2]='r';   // 错

因为他们存储的位置不同,传递给字符型指针的字符串是存储在常量池里面,常量池里面的数据不可以修改。

五、多维数组的字符指针

首先得明确一个概念数组名a的意思是指向该二维数组的第一行,而 a+1,a+2表示的是第二行和第三行。如果加了一个*,如:*a,*(a+1)+1,*(a+2)+2分别表示第一行的第一列、第二行的第二列、第三行的第三列。其中的数组名即代表第一行,也代表了第一行的第一列个元素的地址

表现形式 含义 地址
a 一行一列元素的地址,也是第一行的地址 1000
*(a+1)+1 第二行第二列的元素地址 1004
*( *(a+1)+1) 第二行第二列的元素值 值:5

特别注意:

(1)如果是用指针变量去读取数据,就只需一个*号就可以读取数据,因为指针与数组名不同,他就只是指向地址,所以只需要考虑地址位置就可以读取地址里面的值,而数组名不一样,他代表了一个数组的层次关系,它是一个数组的队头。例如二维数组中,既要表清楚行和列,所以需要a表示第一行,*a表示第一行第一列。

(2)用数组名去取值

六、多重指针

相关文章
|
1月前
|
存储 C语言 索引
怎样定义字符数组
字符数组是C语言和其他一些编程语言中用于存储字符序列的数据结构。字符数组可以存储一个或多个字符,并通过索引访问每个字符。下面我们将详细解释如何定义字符数组,并附上相应的代码示例。
61 0
|
30天前
|
存储 Java C++
字符数组
字符数组
24 1
|
23天前
|
存储 C语言
字符指针变量与字符数组的比较
字符指针变量与字符数组的比较
24 3
|
1月前
|
存储 C++ 索引
C++程序字符数组:深入理解与实践
C++程序字符数组:深入理解与实践
25 2
|
1月前
|
存储 程序员 C++
使用字符指针变量和字符数组的比较
使用字符指针变量和字符数组的比较
29 1
|
1月前
|
存储 C++
17字符数组
17字符数组
21 0
|
9月前
|
存储 编译器 C语言
C语言(四)字符串与字符数组
C语言(四)字符串与字符数组
100 0
|
9月前
|
人工智能
字符指针变量和字符数组
字符指针变量和字符数组
C中的字符指针
字符指针就是存储字符串的指针,有上面代码可以看出字符指针存放的就是字符串的首地址 下面我们来看一关于字符指针的题
|
C语言
c语言 字符数组,字符串
char str[5] = { ‘A’,66,‘C’ ,‘D’ ,69 }; / / 66换成大写字母就是B,69就是E char str[5] = { ‘A’,66,‘C’ }; / / 初始化部分元素,其余默认是0 char str[ ] = { ‘A’,66,‘C’ ,‘D’ ,69 }; / / 这样初始化时,可以不写个数
114 0