7.3 字符数组
考点5 字符数组的定义及其初始化和引用
真考链接
考点5经常考查到。选择题中主要以读程序题要求考生写出程序运行结果的形式出现,是必考内容,难度适中,属于重点理解重点掌握内容。在操作题中,使用数组处理字符是经常考查的内容,常在修改题中对此知识点进行考查,考核概率为20%。
字符数组就是数组中的每个元素都是字符,定义方法与普通数组相同,即逐个对数组元素进行赋值。例如:
char c[11];
c为该数组名,该数组共有11个元素,并且每个元素都为字符型。
对字符数组初始化,可逐个元素地赋值,即把字符逐个赋给数组元素。例如:
char a[9] ={'T', 'h', 'a', 'n', 'k', ' ', 'y', 'o', 'u'};
如果花括号中提供的初值个数(即字符个数)大于数组长度,则编译时会按语法错误处理。如果初值个数小于数组长度,则将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符('\0')。例如:
char c[6] ={'G', 'o', 'o', 'd'};
数组元素在内存中的存储状态如图7.1所示。
图7.1 数组元素在内存中的存储状态
字符数组的引用形式与其他数组的引用形式相同,采用下标引用,即数组名[下标]。
例如:
#include <stdio.h>
main()
{ char c[9] ={'T', 'h', 'a', 'n', 'k', 'ц', 'y', 'o', 'u'};
int i;
for(i=0;i<9;i++)
printf("% c",c[i]);
}
输出结果为:Thank you。
真题精选
【例1】已知字母A的ASCII码是65,则有下面的程序段:
#include <stdio.h>
main()
{ char c[5] ={65,66,67,68,69};
int i;
for(i=0;i< =4;i++)
printf("% c ",c[i]);
}
则程序段的输出结果是( )。
A.1 2 3 4 B.0 1 2 3 C.ABCDE D.65 66 67 68
【答案】C
【解析】ASCII码65、66、67、68、69分别对应的字母为A、B、C、D、E,初始化到字符数组c中,所以输出结果为ABCDE。
【例2】下列给定程序中函数fun()的功能是:统计substr所指的子符串在str所指的字符串中出现的次数。例如,若字符串为aaas1kaaas,子字符串为as,则应输出2。请改正程序中的错误,使它能得出正确的结果。
注意:不要改动main()函数,不得增行或删行,也不得更改程序的结构。
试题程序
#include <stdio.h>
int fun(char *str,char *substr)
{ int i,j,k,num=0;
/*****found*****/
for(i = 0,str[i],i++)
for(j=i,k=0;substr[k] ==str[j];k++,j++)
/*****found*****/
If(substr[k+1] == '\0')
{ num++;
break;
}
return num;
}
main()
{ char str[80],substr[80];
printf("Input a string:");
gets(str);
printf("Input a substring:");
gets(substr);
printf("% d\n",fun(str,substr));
}
【答案】(1)for(i=0;str[i];i++)
(2)if(substr[k+1] =='\0')
【解析】本题考查:for循环语句的格式,for循环语句使用最为灵活,其一般形式为for(表达式1;表达式2;表达式3),注意表达式之间使用“;”相隔;if条件语句的格式,其中if关键字需要区别大小写,这里不能混淆使用。关键字是由C语言规定的具有特定意义的字符串组成,也称为保留字。用户定义的标识符不应与关键字相同,并且关键字应小写。
考点6 字符串和字符串结束标识
真考链接
考点6难度适中,属于理解性内容,在选择题中考核概率为 60%。在操作题中一般与其他知识点一起出现,出现的概率为70%。
C语言中,将字符串作为字符数组来处理。为了测定字符串的实际长度,C语言规定了一个字符串结束标识,以字符'\0'代表。也就是说,在遇到字符'\0'时,表示字符串结束,由它前面的字符组成字符串。
系统对字符串常量也自动加一个'\0'作为结束符。例如:
char c[] ="c program";
数组c共有9个字符,但在内存中占10个字节,最后一个字节'\0'是由系统自动加上的。
有了结束标识'\0'后,在程序中往往依靠检测'\0'的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。
说明:'\0'代表ASCII码为0的字符,是一个“空操作符”,它什么也不干。在输出时也不输出'\0',它只是一个结束的标志。
真题精选
【例1】下面程序输出的结果是( )。
#include <stdio.h>
main()
{ char c[9] ={'T','h','a','\0','k',' ','y','o','u'};
printf("% s",c);
}
A.Thank you B.Thank C.Tha D.无输出
【答案】C
【解析】C语言规定了一个字符串结束标识,以字符'\0'代表。字符数组中a后面为'\0',字符串在此处结束,所以输出结果为Tha。
【例2】以下程序的输出结果是( )。
char c[5] ={'a','b','\0','c','\0'};
printf("% s",c);
A.a B.b C.ab D.abc
【答案】C
【解析】由于字符数组c的元素c[2]中保存的是字符'\0'(串结束标识),因此将数组c作为字符串处理时,遇到字符'\0'输出就会结束。
考点7 字符数组的输入/输出
真考链接
考点7属于重点理解重点掌握知识点,属于必考点。在操作题中主要考查字符数组的输入/输出。填空和编程题都很有可能涉及对字符处理的程序,其中输入/输出也是考查的重点,考核概率为20%。
字符数组的输入/输出可以有以下两种方法:
(1)用“%c”格式符将字符逐个输入或输出。
(2)用“%s”格式符将整个字符串一次输入或输出。
例如:
char c[ ] = "program";
printf("% s",c);
小提示
用格式符“%s”输出字符串时,printf()函数中的输出项应该是数组名,而不是数组中的某个元素,如“printf ("%s",c[0]);”是不对的,应改为“printf("%s",c);”。当数组中的字符串的实际长度小于数组定义的实际长度时,在输出时也是遇到'\0'就结束;当数组中有多个'\0'时,遇到第一个'\0'就结束输出。结束符'\0'不被输出。在使用scanf()函数中,输入项是字符数组名。输入项为字符数组名时,不用再加取地址符“&”。因为在C语言中数组名代表该数组的起始地址,如“scanf("%s",str);”。
真题精选
【例1】下面程序输出的结果是( )。
#include<stdio.h>
main()
{ char w[][10] = {"ABCD","EFGH","IJKL","MNOP"};
for(k = 1;k < 3;k++)printf("% s ",&w[k][k]);
}
A.ABCDFGHKL B.ABCEFGIJM C.EFGJK0 D.FGHKL
【答案】D
【解析】当k=1时,引用的是w[1][1],值为字符串“FGH”;当k=2时,引用的是w[2][2],即字符串“KL”。
【例2】以下程序的输出结果是( )。
main()
{ char a[] ="abcdefg",b[10] ="abcdefg";
printf("% d% d\n",sizeof(a),sizeof(b));
}
A.77 B.88 C.810 D.1010
【答案】C
【解析】字符数组a共有8个元素,b有10个元素。
【例3】规定输入的字符串中只包含字母和*号。编写函数fun(),其功能是:删除字符串中所有的*号。编写函数时,不得使用C语言提供的字符串函数。
例如,字符串中的内容为:****A*BC*DEF*G*******,删除后,字符串中的内容应当是:ABCDEFG。
注意:部分源程序给出如下。请勿改动主函数main()和其他函数中的任何内容,仅在函数fun()的花括号中填入你编写的若干条语句。
试题程序
#include <conio.h>
#include <stdio.h>
void fun(char *a){
}
void main()
{ char s[81];
printf("Enter a string:\n");
gets(s);
fun(s);
printf("The string after deleted:\n");
puts(s);
}
【答案】void fun(char *a)
{ int i,j=0;
for(i=0;a[i]!= '\0';i++)
if(a[i]!= '*')
a[j++] =a[i];*若不是要删除的字符'*'则留下*/
a[j] = '\0';/*最后加上字符串结束符'\0'*/
}
【解析】用循环操作从字符串开始往后逐个进行比较,若不是要删除的字符(用if(a[i]!='*')来控制)则保留。变量i和j用来表示原字符串的下标和删除*号后新字符串的下标。注意下标变量j要从0开始,最后还要加上字符串结束标识'\0'。
考点8 字符串处理函数
真考链接
考点8偏难,属于重点理解重点掌握的内容,考查主要以选择题的形式出现。考核概率为 100%。在操作题中,考核概率为20%。
C语言没有提供对字符串进行整体操作的运算符。但在C语言的函数库中提供了一些用来处理字符串的函数,可以通过调用这些库函数来实现字符串的赋值、合并和比较运算。使用这些函数时,必须在程序前面的命令行包含标准头文件"string.h",具体内容见表7.1。
表7.1 字符串处理函数
小提示
puts()、gets()这两个函数是针对一个字符或一个字符串的处理函数。而以“str”开头的处理函数,都是针对字符串的处理函数。
常见问题
字符串处理函数strcpy()的作用是什么?
strcpy()的调用形式为strcpy(字符数组1,字符数组2),其作用就是把字符数组2所指字符串的内容复制到字符数组1所指的存储空间中。函数返回字符数组1的值。
真题精选
【例1】下面程序输出的结果是( )。
#include <stdio.h>
#include <string.h>
main()
{ char c[20] ={'T', 'h', 'a', '\0', 'k', 'ц', 'y', 'o', 'u'};
printf("% d",strlen(c));
}
A.20 B.9 C.3 D.4
【答案】C
【解析】此函数计算出以字符数组为起始地址的字符串的长度,并作为函数值返回,这一长度不包括串尾的结束标识‘\0’。所以输出为字符串“Tha”的长度3。
【例2】s1和s2已正确定义并分别表示两个字符串。 若要求当s1所指字符串大于s2所指字符串时,执行语句S,则以下选项中正确的是( )。
A.if(s1>s2)S; B.if(strcmp(s1,s2))S;
C.if(strcmp(s2,s1) >0)S; D.if(strcmp(s1,s2) >0)S;
【答案】D
【解析】比较两个字符串时不能直接将两个字符串名进行比较,而是使用字符串处理函数strcmp(s1,s2),当s1所指字符串大于s2所指字符串时,strcmp(s1,s2)>0,所以选D。
【例3】调用函数strlen("abcd\0ef\0g")的返回值为( )。
A.4 B.5 C.8 D.9
【答案】A
【解析】注意字符串中的字符‘\0’,它在C的字符串中具有特殊的意义,字符‘\0’标志字符串的结束。计算串长时,只计算字符‘\0’之前的字符数量,而不管‘\0’之后是什么字符。
【例4】下列给定程序中,函数fun()的功能是:从形参ss所指字符串数组中,删除所有串长超过k的字符串,函数返回剩余字符串的个数。ss所指字符串数组中共有N个字符串,且串长小于M。
请在标号处填入正确的内容,使程序得出正确的结果。
注意:部分源程序给出如下。不得增行或删行,也不得更改程序的结构。
试题程序
#include <stdio.h>
#include <string.h>
#define N 5
#define M 10
int fun(char(*ss)[M],int k)
{ int i,j=0,len;
for(i=0;i< 【1】;i++)
{ len=strlen(ss[i]);
if(len< =【2】)
strcpy(ss[j++],【3】);
}
return j;}
main()
{ char x[N][M] = {"Beijing","Shang
hai","Tianjin","Nanjing","Wuhan"};
int i,f;
printf("\nThe original string\n\n");
for(i=0;i<N;i++)puts(x[i]);
printf("\n");
f=fun(x,7);
printf("The string witch length is less than or equal to 7:\n");
for(i=0;i<f;i++)puts(x[i]);
printf("\n");
}
【答案】【1】N 【2】k 【3】ss[i]
【解析】本题考查:for循环语句;if语句条件表达式;字符串复制函数strcpy的使用。
标号【1】:for循环语句的作用是遍历字符串数组中的每一个字符串,所以循环变量i的循环条件是i<N。
标号【2】:题目要求删除串长度小于k的字符串,所以if条件语句的条件表达式是len<=k。
标号【3】:通过字符串复制函数将串长不大于k的字符串另存,并记录个数。