C软件工程师就业求职手册第6章字符串.docx
- 文档编号:24137807
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:53
- 大小:42.02KB
C软件工程师就业求职手册第6章字符串.docx
《C软件工程师就业求职手册第6章字符串.docx》由会员分享,可在线阅读,更多相关《C软件工程师就业求职手册第6章字符串.docx(53页珍藏版)》请在冰豆网上搜索。
C软件工程师就业求职手册第6章字符串
第6章字符串
在C/C++语言中没有专门的字符串变量,通常用字符数组来存放字符串。
字符串是以"\0"作为结束符。
C/C++提供了丰富的字符串处理函数,下面列出了几个最常用的函数。
字符串输出函数puts。
字符串输出函数gets。
字符串连接函数strcat。
字符串复制函数strcpy。
测字符串长度函数strlen。
字符串是面试的重点考查部分的相关知识,通过考查字符串的相关知识可以考察程序员的编程规范以及编程习惯。
并且其中包括了许多知识点,例如内存越界、指针与数组操作等。
许多公司在面试时会要求应聘者写一段复制字符串或字符串子串操作的程序。
本章列举了一些与字符串相关的面试题,有些题目要求较高的编程技巧。
6.1 数字与字符串的转化
应聘时经常出现数字与字符串之间转化的问题,面试官通过这类题目来考察应聘者能力,例如是否熟悉常用的库函数,是否了解ASCII码以及是否了解字符串的存储格式等。
6.1.1 数字转化为字符串
面试例题1:
使用库函数将数字转换为字符串。
考点:
C库函数中数字转换为字符串的使用。
出现频率:
★★★
解析
C语言提供了几个标准库函数,可以将任意类型(整型、长整型、浮点型等)的数字转换为字符串,下面列举了各函数的方法及其说明。
itoa():
将整型值转换为字符串。
ltoa():
将长整型值转换为字符串。
ultoa():
将无符号长整型值转换为字符串。
gcvt():
将浮点型数转换为字符串,取四舍五入。
ecvt():
将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。
fcvt():
指定位数为转换精度,其余同ecvt()。
还可以使用sprintf系列函数把数字转换成字符串,其比itoa()系列函数运行速度慢。
下列程序演示了如何使用itoa()函数和gcvt()函数:
1 #include
2 #include
3
4 intmain()
5 {
6 intnum_int=435;
7 doublenum_double=435.10f;
8 charstr_int[30];
9 charstr_double[30];
10
11 itoa(num_int,str_int,10); //把整数num_int转成字符串str_int
12 gcvt(num_double,8,str_double); //把浮
点数num_double转成字符串str_double
13
14 printf("str_int:
%s\n",str_int);
15 printf("str_double:
%s\n",str_double);
16
17 return0;
18 }
程序输出结果:
1 str_int:
435
2 str_double:
435.10001
代码第11行中的参数10表示按十进制类型进行转换,转换后的结果是"435",如果按二进制类型进行转换,则结果为"1101110011"。
代码第12行中的参数8表示精确位数,这里得到的结果是"435.10001"。
答案
可以使用atoi系列函数把数字转换成字符串。
面试例题2:
不使用库函数将整数转换为字符串。
考点:
数字转换为字符串,理解相关ASCII码。
出现频率:
★★★★
解析
如果不使用atoi或sprintf等库函数,可以通过把整数的各位上的数字加"0"转换成char类型并存到字符数组中。
但是要注意,需要采用字符串逆序的方法。
如以下程序所示:
1 #include
2 usingnamespacestd;
3
4 voidint2str(intn,char*str)
5 {
6 charbuf[10]="";
7 inti=0;
8 intlen=0;
9 inttemp=n<0?
-n:
n; //temp为n的绝对值
10
11 if(str==NULL)
12 {
13 return;
14 }
15 while(temp)
16 {
17 buf[i++]=(temp%10)+'0'; //把temp的每一位上的数存入buf
18 temp=temp/10;
19 }
20
21 len=n<0?
++i:
i; //如果n是负数,则多需要一位来存储负号
22 str[i]=0; //末尾是结束符0
23 while
(1)
24 {
25 i--;
26 if(buf[len-i-1]==0)
27 {
28 break;
29 }
30 str[i]=buf[len-i-1]; //把buf数组里的字符拷到字符串
31 }
32 if(i==0)
33 {
34 str[i]='-'; //如果是负数,添加一个负号
35 }
36 }
37
38 intmain()
39 {
40 intnNum;
41 charp[10];
42
43 cout<<"Pleaseinputaninteger:
";
44 cin>>nNum;
45 cout<<"output:
";
46 int2str(nNum,p); //整型转换成字符串
47 cout<
48
49 return0;
50 }
程序中的int2str函数完成了int类型到字符串类型的转换。
在代码第46行对int2str函数做了测试。
程序的执行结果如下所示:
Pleaseinputaninteger:
1234
Output:
1234
如果输入的是个负数,程序执行结果如下所示:
Pleaseinputaninteger:
-1234
Output:
-1234
接下来对int2str函数的实现进行分析。
代码第9行,把参数n的绝对值赋给temp,以后在计算各个位的整数时用temp,这样保证在负数情况下取余不会出现问题。
代码第11~第14行判断str的有效性,str不为NULL。
代码第15~第19行的while循环中,将n的各个位存放到局部数组buf中,存放的顺序与整数顺序相反。
例如n为整数123456,while循环结束后buf应为"654321"。
代码第21行计算转换后字符串的长度len,如果是负数,长度应该再加1。
代码第22~第31行把数组buf中的非0元素逆向复制到参数str指向的内存中,如果n是负数,则str指向的第一个内存存放负号。
6.1.2 字符串转化为数字
面试例题3:
使用库函数将字符串转换为数字。
考点:
C库函数中字符串转换为数字的使用。
出现频率:
★★★★
解析
与上节数字转换为字符串类似,C/C++语言提供了几个标准库函数,可以将字符串转换为任意类型(整型、长整型、浮点型等)。
以下列举了各函数的方法及其说明。
atof():
将字符串转换为双精度浮点型值。
atoi():
将字符串转换为整型值。
atol():
将字符串转换为长整型值。
strtod():
将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字。
strtol():
将字符串转换为长整值,并报告不能被转换的所有剩余数字。
strtoul():
将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字。
以下程序演示如何使用atoi()函数和atof()函数。
1 #include
2 #include
3
4 intmain()
5 {
6 intnum_int;
7 doublenum_double;
8 charstr_int[30]="435"; //将要被转换为整型的字符串
9 charstr_double[30]="436.55"; //将要被转换为浮点型的字符串
10
11 num_int=atoi(str_int); //转换为整型值
12 num_double=atof(str_double); //转换为浮点型值
13
14 printf("num_int:
%d\n",num_int);
15 printf("num_double:
%lf\n",num_double);
16
17 return0;
18 }
输出结果:
num_int:
435
num_double:
436.550000
面试例题4:
不使用库函数将字符串转换为数字。
考点:
字符串转换为数字时,对相关ASCII码的理解。
出现频率:
★★★★
解析
程序代码如下:
1 #include
2 usingnamespacestd;
3
4 intstr2int(constchar*str)
5 {
6 inttemp=0;
7 constchar*ptr=str; //ptr保存str字符串开头
8
9 if(*str=='-'||*str=='+') //如果第一个字符是正负号,
10 { //则移到下一个字符
11 str++;
12 }
13 while(*str!
=0)
14 {
15 if((*str<'0')||(*str>'9')) //如果当前字符不是数字
16 { //则退出循环
17 break;
18 }
19 temp=temp*10+(*str-'0');//如果当前字符是数字则计算数值
20 str++; //移到下一个字符
21 }
22 if(*ptr=='-') //如果字符串是以"-"开头,则转换成其相反数
23 {
24 temp=-temp;
25 }
26
27 returntemp;
28 }
29
30 intmain()
31 {
32 intn=0;
33 charp[10]="";
34
35 cin.getline(p,20); //从终端获取一个字符串
36 n=str2int(p); //把字符串转换成整型数
37
38 cout< 39 40 return0; 41 } 程序执行结果: 输入: 1234 输出: 1234 输入: -1234 输出: -1234 输入: +1234 输出: 1234 程序中的str2int函数作用是将字符串转换成整数。 这个函数的转换过程与例题2中的int2str函数相比更加简单,它只需要做一次while循环(代码第13行)就能把数值大小计算出来,如果结果是负数,就加一个负号。 6.2 字符串与数组 字符串一般是用字符数组的方式存储,例如下面的str定义: charstr[]="123456"; 这里str是一个字符数组,它存放了一个字符串"123456",由于字符串还有一个结束符"\0",所以此数组的长度为7而不是6。 6.2.1 strcpy函数与memcpy函数 strcpy和memcpy都是标准C库函数,它们有下面的特点。 strcpy提供了字符串的复制。 即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。 memcpy提供了一般内存的复制。 即memcpy对于需要复制的内容没有限制,因此用途更广。 面试例题5: 编程实现strcpy函数。 考点: 字符串复制的实现。 出现频率: ★★★★ 已知strcpy函数的原型是: char*strcpy(char*strDest,constchar*strSrc); 要求如下。 (1)不调用库函数,实现strcpy函数; (2)解释为什么要返回char*。 解析 程序代码如下: 1 #include 2 3 char*strcpy(char*strDest,constchar*strSrc)//实现 strSrc到strDest的复制 4 { 5 if((strDest==NULL)||(strSrc==NULL))//判 断参数strDest和strSrc的有效性 6 { 7 returnNULL; 8 } 9 char*strDestCopy=strDest; //保存目标字符串的首地址 10 while((*strDest++=*strSrc++)! ='\0');//把 strSrc字符串的内容复制到strDest下 11 12 returnstrDestCopy; 13 } 14 15 intgetStrLen(constchar*strSrc) //实现获取strSrc字符串的长度 16 { 17 intlen=0;//保存长度 18 while(*strSrc++! ='\0') //循环直到遇见结束符'\0'为止 19 { 20 len++; 21 } 22 23 returnlen; 24 }; 25 26 intmain() 27 { 28 charstrSrc[]="HelloWorld! "; //要被复制的源字符串 29 charstrDest[20]; //要复制到的目的字符数组 30 intlen=0; //保存目 的字符数组中字符串的长度 31 32 len=getStrLen(strcpy(strDest,strSrc));//链 式表达式,先复制后计算长度 33 printf("strDest: %s\n",strDest); 34 printf("LengthofstrDest: %d\n",len); 35 36 return0; 37 } (1)strcpy函数的实现说明。 代码第5~第7行判断传入的参数strDest和strSrc是否为NULL,如果是则返回NULL。 代码第9行把strDest的值保存到strDestCopy指针中。 代码第10行对strSrc和strDest两个指针进行循环移动,并不断复制strSrc内存的值到strDest内存中。 由于已经保存了strDest指针的值,因此这里只需返回strDestCopy的值,而函数调用完后返回的就是strDest的值。 (2)strcpy函数返回char*类型的原因是为了能使用链式表达式。 首先调用strcpy使得strDest指针复制strSrc的内存数据,然后调用getStrLen函数获取strDest字符串的长度。 这样不仅调用方便,而且程序结构简洁明了。 程序的输出结果如下: strDest: HelloWorld! LengthofstrDest: 12 面试例题6: 编程实现memcpy函数。 考点: 内存复制的实现。 出现频率: ★★★★ 答案 程序代码如下所示: 1 #include 2 #include 3 4 void*memcpy2(void*memTo,constvoid*memFrom,size_tsize) 5 { 6 assert((memTo! =NULL)&&(memFrom! =NULL));//memTo和memFrom必须有效 7 char*tempFrom=(char*)memFrom; //保存memFrom首地址 8 char*tempTo=(char*)memTo; //保存memTo首地址 9 10 while(size-->0) //循环size次,复制memFrom的值到memTo中 11 *tempTo++=*tempFrom++; 12 13 returnmemTo; 14 } 15 16 intmain() 17 { 18 charstrSrc[]="HelloWorld! "; //将被复制的字符数组 19 charstrDest[20]; //目的字符数组 20 21 memcpy2(strDest,strSrc,4); //复制strSrc的前4个字符到strDest中 22 strDest[4]='\0'; //把strDest的第5个元素赋为结束符'\0' 23 printf("strDest: %s\n",strDest); 24 25 return0; 26 } memcpy的实现如下。 与strcpy不同,memcpy用参数size决定复制多少个字符(strcpy遇到结束符"\0"结束)。 由于在主程序中只复制了strSrc的前4个字符(代码第22行),程序输出如下: strDest: Hell 面试例题7: strcpy与memcpy的区别。 考点: 字符串复制与内存复制之间的区别。 出现频率: ★★★★ 解析 strcpy和memcpy主要有以下3方面的区别。 复制的内容不同。 strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。 复制的方法不同。 strcpy不需要指定长度,它遇到字符串结束符"\0"便结束。 memcpy则是根据其第3个参数决定复制的长度。 用途不同。 通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。 6.2.2 数组越界 (1) C++不会自动检查数组越界,也就是说如果数组越界,程序编译时不会报错,从而在执行时产生非法操作或者得不到正确的结果。 因此在使用数组时,一定要在编程中判断是否越界以保证程序的正确性。 面试例题8: 改错--数组越界。 考点: 数组越界出现的问题。 出现频率: ★★★★ 题 (1) 1 voidtest1() 2 { 3 charstring[10]; 4 char*str1="0123456789"; 5 strcpy(string,str1); 6 } 题 (2) 1 voidtest2() 2 { 3 charstring[10],str1[10]; 4 inti; 5 for(i=0;i<10;i++) 6 { 7 str1[i]='a'; 8 } 9 strcpy(string,str1); 10 } 题(3) 1 voidtest3(char*str1) 2 { 3 charstring[10]; 4 if(strlen(str1)<=10) 5 { 6 strcpy(string,str1); 7 } 8 } 解析 这3道题都有数组越界的问题。 题 (1)中,string是一个含有10个元素的字符数组,str1指向的字符串长度为10,在进行strcpy调用时,会将str1的结束符也复制到string数组里,即复制的字符个数为11,这样会导致string出现数组越界。 程序不一定会因此而崩溃,但这是一个潜在的危险。 解决办法是将string的元素个数定义为11。 题 (2)中,str1和string都是含有10个元素的字符数组,并且str1的元素全部被赋为字符"a",然后再调用strcpy。 这里会出现以下两个问题: 一个问题是str1表示的字符数组没有以'\0'结束,在随后调用strcpy时无法判断什么时候复制结束;另一个问题是string的数组长度不够,出现数组越界的现象。 解决办法是将string和str1的元素个数都定义为11个,并在调用strcpy之前加入一条语句把str1[10]赋为'\0'。 题(3)中,if语句使用小于等于"<="进行比较,如果str1的长度等于10,也会出现数组越界的情况。 解决办法是把"<="
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件工程师 就业 求职 手册 字符串
![提示](https://static.bdocx.com/images/bang_tan.gif)