参考资料:高教版《全国计算机等级考试二级教程——C语言程序设计》、《21天学通C语言》
用一维字符数组存放字符串
字符串
C语言对字符串的约定
在C语言中,字符串是借助于字符型一维数组来存放的,并规定以字符'\0'作为“字符串的结束标志”。
注意:‘\0’作为标志占用存储空间,但不计入串的实际长度。
C语言中表示字符串常量的约定
C语言中允许使用“字符串常量”,字符串常量是由双引号括起来的一串字符。
在表示字符串常量时,不需要人为地在其末尾加入‘\0’。
C语言中字符串常量给出的是地址值
每一个字符串常量都分别占用内存中一串连续的存储空间,这些连续的存储空间实际上是字符型一维数组。在C语言中,字符串常量被隐含处理成一个以’\0‘结尾的无名字符型一维数组。
若有以下定义和语句:
char *sp;
sp = "Hello!";
此赋值语句并不是把字符串的内容放入了sp中,而是把字符串在内存中所占的首地址赋予了指针sp,使指针变量sp指向该字符串。
字符数组与字符串的区别
仅可以在字符数组内存放字符串,不能通过赋值语句将字符串常量或其他字符数组中的字符串直接赋给字符串变量。
可以说:字符串是字符数组的一种具体应用。
通过赋初值的方式给一维数组赋字符串
用一维数组赋初值的相同方式给一维字符数组赋初值
在给一维字符数组赋初值时,只要所赋初值的字符个数少于数组元素的个数,系统会自动在其后的元素中加入'\0'。
如果一个字符数组用来作为字符串使用,那么在定义该字符串数组时,数组的大小就应该比它将要实际存放的最长字符串多一个元素,从而给在末尾存放'\0'留有空间。如果字符数组最后没有'/0',就不能把它当做字符串来使用。
当用赋初值方式来定义字符数组的大小时,定义应该写成:
char str[] = {'s', 't', 'r', 'i', 'n', 'g', '!', '\0'};
在赋初值时直接赋字符串常量
可以直接用字符串常量给一维字符数组赋初值。例如:
char str[10] = {"string!"};
可以省略花括号写成以下形式,这种方法是用字符串字面量进行赋值的方法:
char str[10] = "string!";
在这里由于“string!”是字符串常量,不必人为在最后加入'/0'。
也可以用以下形式来定义:
char str[] = "string!";
在C程序执行过程中给一维字符数组赋字符串
不可以用赋值语句给字符数组整体赋一串字符
当做字符串变量使用的字符数组,不能由赋值语句直接赋字符串常量,因为字符串常量给出的是地址值,而数组名是一个地址常量,不能被重新赋值。
给数组元素逐个赋字符值,最后人为加入串结束标志
可以通过逐个给数组元素赋值的方式达到给一维数组赋字符串的目的。例如:
char mark[10]
mark[0] = 'C';
mark[1] = ' ';
mark[2] = 'p';
mark[3] = 'r';
……
mark[9] = '\0';
也可以通过给一维字符数组输入字符并在最后加'\0'的方式,给一维数组赋字符串,例如:
char mark[10];
int n;
for(i = 0; i < 9; i++)
scanf("%c", &mark[i]);
mark[i] = '\0';
这时需要从键盘键入一个指定的字符。
使指针指向一个字符串
通过赋初值的方式使指针指向一个字符串
可以在定义字符指针变量的同时,将存放字符串的存储单元起始地址赋给指针变量。如:
char *ps1 = "form one";
这里把存放字符串常量的无名存储区的首地址赋给了指针变量ps1,使ps1指向字符串的第一个字符f。
也可这样定义:
char str[] = "form one", *ps2 = str;
通过赋初值使ps2指向字符串的第一个字符f。
通过赋值运算使指针指向一个字符串
可以通过赋值运算将某个字符串的起始地址赋给一个字符型指针变量,从而使其指向一个具体的字符串。如:
char *ps1;
ps1 = "form one";
也可以这样赋值:
char str[] = "form two", *ps2;
ps2 = str;
在编译期分配字符串的空间
char *message;
以上语句生命了一个指向char类型变量的指针message,此时它尚未指向任何内容。但如果改变指针的声明:
char *message = "Great Caesar\'s Ghost!";
当执行该声明时,字符串Great Caesar's Ghost!(包括末尾的空字符)将被储存在内存中的某处,且指针message被初始化为指向该字符串的第一个字符。一旦定义了message,它就是指向该字符串的指针,可以当做指向字符串的指针来使用。
字符串的输入和输出
输入和输出字符串时的必要条件
当对字符串进行输出时,输出项既可以是字符串常量或字符数组名,也可以是已指向字符串的字符指针变量。
当对字符串进行输入时,输入项既可以是字符数组名,也可以是字符指针变量。
注意:字符数组应有足够大的存储空间。使用指针变量作为输入项时,指针必须已经指向确切的、足够大的存储空间。
用格式说明符%s进行整串输入和输出
输入
在scanf函数中使用格式说明符%s可以实现字符串的整体输入:
scanf("%s", str_adr);
这里str_adr是地址值,可以是字符数组名、字符数组元素的地址或字符指针变量。例如:
char str[15];
scanf("%s", str);
注意:
- 用%s格式符输入字符串时,空格和回车符都作为输入数据的分隔符而不能被读入。
- 输入字符串的长度超过字符数组所能容纳的字符个数时,相当于下标越界,不报错。
- 当输入项是数组元素的地址时,输入的字符将从这一元素开始依次存放在该数组中。
输出
在printf函数中使用格式说明符%s可以实现字符串的整体输出:
printf("%s", str_adr);
此处的str_adr是地址值。
调用gets、puts函数在终端输入或输出一行字符串
gets函数
gets函数用于从终端读入字符串(包括空格),直到输入一个换行符为止(换行符不作为字符串的内容,系统自动用'\0'代替)。
gets函数的调用形式如下:
gets(str_adr);
其中str_adr是地址值,可以是字符数组名、字符数组元素的地址或字符指针变量。
例如:
char str[20];
gets(str);
puts函数
puts函数用于输出存储单元中的字符,遇到'\0'结束输出,并自动输出一个换行符。
puts函数的调用形式如下:
puts(str_adr);
其中str_adr是存放待输出字符串的起始地址。
puts函数唯一的参数是指向待显示字符串的指针。由于字符串字面量相当于指向字符串的指针,因此puts函数除了可以显示指针指向的字符串,还可以用于显示字符串字面量。
字符串数组
所谓字符串数组就是数组中的每个元素又都是一个存放字符串的一维数组。
-
可以用二维字符数组实现这一数据结构。可以认为:二维数组的第一个下标决定了字符串的个数,第二个下标决定了字符串的最大长度。
-
字符串数组可以在定义的同时赋初值,如:
char ca[3][5] = {"A", "BB", "CCC"}; 也可写成: char ca[][5] = {"A", "BB", "CCC"};
-
可以定义字符型指针数组并通过赋初值来构成一个类似的字符串数组。例如:
char *pa[3] = {"a", "bb", "ccc"};
用于字符串处理的函数
字符串复制函数strcpy()
strcpy(s1, s2);
此函数用来把s2所指字符串的内容复制到s1所指存储空间中。
字符串连接函数strcat()
strcat(s1, s2);
该函数将s2所指字符串的内容连接到s1所指字符串的后面,并自动覆盖s1中的'\0'。
该函数的返回值为s1的地址值。
求字符串长度函数strlen()
strlen(s);
此函数计算出以s为起始地址的字符串的长度,并作为函数值返回。
注意:长度不包括结尾的'\0'。
字符串比较函数strcmp()
strcmp(s1, s2);
该函数用于比较s1和s2所指字符串的大小。若s1>s2,函数值大于0;若s1<s2,函数值小于0;若s1=s2,函数值为0。
注意:该函数比较字符串的大小的方法是通过比较两字符串对应位置上字符的大小(即ASCII码值)。
网友评论