字符数组的基本语法
1.字符串和字符串的存储方式
1.1字符串的定义
字符串是指若干有效字符的序列。包括字母、数字、专用字符、转义字符等等。
例如:
"China" "a+b=c" "Li-Li"
"39.4" "%d\n" "解放军"
字符串存放在一个字符型数组中,因此为了存放字符串,常常在程序中定义字符型数组。
例如:
char str[8] = {"Be Jing"};
解释:
表示 str 是一个字符型数组,可以放 8 个字符
#include<stdio.h>
int main()
{
int i = 0;
char str[8] = {"Be Jing"};
for (i = 0; i < 8; i++)
{
printf("str[%d] = '%c'\n",i,str[i]);//%c 打印字符
}
return 0;
}
输出结果:
字符数组的起始地址就是第一个元素的存储地址。
C语言中是以 ‘\0’ 字符作为字符串结束标志的,所以图中的 str[7] 就是表示 ‘\0’ ,只是没有显示出来。
注意:
字符数组和字符串是两个不同的概念,字符串存放在字符数组中,字符串以 ‘\0’ 作为结束标志。
2.字符数组的初始化
2.1字符数组的初始化规则
(1)逐个地为数组中而元素指定初值字符。
- 一个字符一个字符地分别赋给各元素。
例如:
char str[8] = { 'B','e',' ','J','i','n','g','\0' };
- 当对数组中全部元素指定初值的情况下,字符数组的大小可以不必定义。
例如:
char str[ ] = { 'B','e',' ','J','i','n','g','\0' };
(2)也可以用下面的初始化方式对字符数组指定初值。
例如:
char str[8] = {"Be Jing"};
注意:
单个字符用单撇号括起来,而字符串用双撇号括起来,这种微小的差别千万不要忽略。
对比:方式(1)和方式(2)
方式(2)中 “Be Jing” 是一个字符串,根据前面介绍的用 ‘\0’ 作为字符串结束标志的方法,系统将自动在最后一个字符后面加入一个 ‘\0’ 字符,并把让一起存入字符数组中。
而在方式(1)中,则不存在这个问题,系统只是一一对应的将各个元素赋值。
(3)在采用方式(2)进行初始化时,数组的元素个数应该足够大,以便容纳全部有用字符和 ‘\0’ 。上面的数组 str 虽然未定义大小,但系统会自动给它定义为 str[8]。
两种初始化方式等价:
char str[8] = {"Be Jing"};
char str[8] = {"Be Jing"};
如果写成:
char str[7] = {"Be Jing"};
会出现什么情况?
本来是应该把 8 个字符赋给 str 数组的,但是 str 数组只含 7 个元素,因此最后一个字符 ‘\0’ 未能放入 str 数组里面,而是存放到 str 数组之后的存储单元中。
这种现象叫字符数组的“下界溢出”。这就会破坏其他数据区或程序本身。
(4)C语言允许再初始化一个一维字符数组时省略字符串常量外面的大括号
例如:
char str[8] = "Be Jing";
char str[ ] = "Be Jing";
3.字符串的输入和输出
3.1三种关于字符串的输入方式
- 用 scanf( ) 函数的 %c 占位符,逐个字符输入
例子:请输入一个长度为 7 的字符串
#include<stdio.h>
int main()
{
char str[8] = { 0 };
str[7] = '\0';
int i = 0;
for (i = 0; i < 7; i++)
{
scanf("%c",str[i]);
}
printf("%s\n",str);
return 0;
}
- 用 scanf( ) 函数的 %s 占位符,实现整个字符串的一次输入
#include<stdio.h>
int main()
{
char str[8] = { 0 };
scanf("%s",str);
printf("%s\n",str);
return 0;
}
- 用C语言中提供的读字符串函数 gets( ) 实现整个字符串(包括空格)的一次输入
#include<stdio.h>
int main()
{
char str[8] = { 0 };
gets(str);
printf("%s\n",str);
return 0;
}
注意:
1.用 scanf( ) 函数的 %s 占位符输入字符串时,以空格或回车符作为字符串的间隔符号。如果输入的字符串包含有空格,例如 “Be Jing”,则只将 “Be” 作为字符串输入,如果:
scanf(“%s %s”,str1,str2);
输入:Be Jing (回车)
系统会将 “Be” 和 ‘\0’ 输入到字符数组 str1中,把 “Jing” 和 ‘\0’ 送到字符数组 str2 中。2.用 scanf( ) 函数的 %s 占位符输入字符串时,按回车或空格后,回车或空格符前面的字符将作为一个字符串输入,系统会自动在字符串末尾加上 ‘\0’ 。
3.由于数组名代表数组的起始地址,因此在 scanf( ) 函数中只写数组名 str 即可。写成:scanf(“%s”,str);
不用写成: scanf(“%s”,&str);
3.2三种关于字符串的输出方式
- (1)用 printf( ) 函数的 %c 占位符,将字符串中的各个字符逐个输出。
例子:
输入一个字符串
#include<stdio.h>
int main()
{
char str[] = { "Be Jing" };
int i = 0;
for (i = 0; i < 7; i++)
{
printf("%c",str[i]);
}
return 0;
}
- (2)用 printf( ) 函数的 %s 占位符实现整个字符串的一次输出。
#include<stdio.h>
int main()
{
char str[] = { "Be Jing" };
printf("%s\n",str);
return 0;
}
- (3)用C语言中提供的读字符串函数 gets( ) 实现整个字符串(包括空格)的一次输入。
#include<stdio.h>
int main()
{
char str[] = { "Be Jing" };
puts(str);
return 0;
}
结果都是:
注意:
(1)要输出字符串中某个元素时,要指出元素的下标,而且应采用方式(1)输出。
(2)采用方式(2)输出一个字符串时,只需要写出字符数组名而不必带下标。由于数组名代表该数组的起始地址,在输出是就从该地址开始逐个输出字符,直到字符结束标志 ‘\0’ 为止。
(3)再进行字符串输出时,输出字符不包括 ‘\0’ ,系统只输出 ‘\0’ 以前的有用字符。
(4)如果一个字符数组中字符串并未占满全部元素的空间,则采用方式(2)、(3)输出时,‘\0’ (包括 ‘\0’)不予输出。如果在一个字符数组中有两个 ‘\0’ ,则输出时遇到第一个 ‘\0’ 即认为字符串结束。
(5)put( ) 函数的作用和 printf( “%s”,字符串) 函数相同。但 put( ) 函数只能输出一次,并且 put( ) 函数输出时将 ‘\0’ 转换为换行符输出。
4.二维字符数组
4.1二维字符数组的定义
定义:二维字符数组可以认为有若干个一维数组所组成。
因此,一个 n*m 的二维字符数组可以存放 n 个字符串,每个字符串最大长度为 m-1 。
例如:
char s[3][6] = { "China","Japan","Korea" };
定义一个二维字符数组 s ,其存储内容如下:
- 引用某一行某一列的元素
例如:s[1][2] 是字符 ‘p’,可以单独输出。 - 引用某一行的元素
例如:s[1] 是字符串 “Japan”,可以单独输出。
注意:
s[1]相当于一个一维数组名,s[1]是字符串 “Japan” 的起始地址,与就是二维数组 s 是第一行的起始地址(行数是从第 0 行开始的)。
4.2二维字符数组的用法举例
看一段代码:
#include<stdio.h>
int main()
{
char s[3][6] = { "China","Japan","Korea" };
s[1][5] = ' ';//把空格赋值给 '\0'
printf("%s\n",s[1]);
return 0;
}
输出结果:
原因:
在程序人为地将第 1 行第 5 列(即 Japan 后面的字符)由原来的 ‘\0’ 改为空格字符。
这样输出时,就从 s[1] 所代表的地址开始,输出各个字符直到第 2 行最后一个字符(‘\0’)为止。
例子:输入一个学生名,要求查询该学生是否属于该班。
思路:
- 建立一个二维字符数组 list 存放班级学生信息。
- 用一个一维字符数组 name 存放需查找的学生信息。
- 用单重循环语句将二维字符数组中的各字符串与 name 比较即可。
#include<stdio.h>
#include<string.h>
#define MAX 5
#define LEN 10
int main()
{
char name[LEN] = { 0 };
char list[MAX][LEN] = { "萧炎","叶凡","石昊","陈平安","李火旺" };
int i = 0;
puts("请输入您查询的姓名: ");
gets(name);
for ( i = 0; i < MAX; i++)
{
if (strcmp(list[i], name) == 0)//strcmp()的头文件是:string.h
break; //strcmp(字符串1,字符串2);
} //如果字符串1 = 字符串2,则函数值返回 0;
if (i < MAX)
{
printf("%s 是我们班的同学\n",name);
}
else
{
printf("%s 不是我们班的同学\n", name);
}
return 0;
}
结果如下: