Discuz教程网

C语言案例教程 - 第五章 数组和字符串

[复制链接]
authicon 09927306 发表于 2011-1-8 13:12:42 | 显示全部楼层 |阅读模式
本帖最后由 09927306 于 2011-1-8 18:49 编辑

第5章
数组和字符串
【例5-1】
将10个元素的整型数组a分两行输出。


  1.         main()
  2.           {  int i,a[10]={1,2,3,4,5,6,7,8,9,10};
  3.              for (i=0;i<10;i++)
  4.                { printf("%3d",a[i]);
  5.                  if (i%5==4||i==9)
  6.                     printf("\\n");
  7.                }
  8.           }
复制代码


为了将a数组的10个元素值分两行输出,即每行输出5个,所以在for循环的循环体中增加了一个if语句,它的作用是:当循环变量i为0~3时,i%5均不等于4,printf(\"\\n\")不被执行,不实现换行;当i等于4时,显示完a[4]后,有i等于4及i%5等于4,于是printf(\"\\n\")被执行,从而换入下一行。当i为5~8时,i%5均不等于4,printf(\"\\n\")不被执行,也就不实现换行;当显示完a[9]后,有i等于9及i%5等于4,printf(\"\\n\")又被执行,再换入下一行。也就是说,由于if语句的存在,实现了每5个数显示在同一行上。程序运行结果如下:

1
2
3
4
5

6
7
8
9 10
【例5-2】
用gets()从键盘接收一个英文句子,然后用puts()输出该英文句子。
可以用一维字符数组来存放输入的英文句子,程序如下:


  1.         #include <stdio.h>
  2.         main()
  3.           { char word[80];
  4.             printf("Input a statement:");
  5.             gets(word);
  6.             puts(word);
  7.           }
复制代码


程序运行情况如下:
    Input a statement:I am a student.↙


I am a student.
【例5-3】
利用二维字符数组输入和输出若干个国家的名称。
可以用二维字符型数组来存放若干个国家的英文名称。前面已经提到,二维字符型数组可以看成字符串数组,即把二维数组当做由若干个元素组成的一维数组,而每个元素都是一个字符串。例如,定义:char country[3][8];,其中,country[0]~country[2]分别代表1个字符串的首地址。因此,可以把country直接作为gets()和puts()的参数来输入输出字符串。程序如下:


  1.        #include <stdio.h>
  2.         main()
  3.           { int i;
  4.             char country[3][8];
  5.             printf("请输入国家名称:");
  6.             for(i=0;i<3;i++)
  7.                gets(country[i]);
  8.             for(i=0;i<3;i++)
  9.                puts(country[i]);
  10.           }
复制代码


程序运行情况如下:

请输入国家名称:China↙

America↙

Japan↙

China

America

Japan
其中,前3行是输入的数据,后3行是输出的结果。
【例5-4】
编制程序分档统计某班30名学生某门课考试成绩,即分别统计0~9分,10~19分,……,90~99分,100分的人数。
用一个int型数组a[11]来分别存放11个分数档的人数,即a[0]存放0~9分的人数,a[1]存放10~19分的人数,……,a[10]存放100分的人数。稍加分析就可以发现,设某人的考试成绩为x,则x/10正好就对应数组a的下标。因此,每输入1个成绩x,只要进行a[x/10]+=1的计数操作,就能正确统计出各分数档的人数。程序如下:


  1.     main()
  2.      { int a[11]={0},i;
  3.        float x;
  4.        for(i=1;i<=30;i++)
  5.          { scanf("%f",&x);
  6.            a[(int)x/10]+=1;
  7.          }
  8.      printf("0~9 10~10 20~29 30~39 40~49 50~59 60~69 70~79
  9. 80~89 90~99 100\\n");
  10.        for(i=0;i<11;i++)
  11.          printf("  %2d  ",a[i]);
  12.      }
复制代码


上面的程序假定了各人的成绩都是实数,由于数组的下标必须为整数,因此使用了强制类型转换。
【例5-5】
试编程找出二维数组a[3][4]中最大和最小的元素,并指出它们所在的行号和列号。
求最大值和最小值是通过不断比较实现的。以求最大值为例,通常将数组的第一个元素作为基准变量max,用它与第二个元素比较,如果第二个元素大,则将它的值存入max中;否则max值保持不变。再用max与第三个元素比较,处理方法与前面相同。这样,总是将最大数存放在max中,始终用max和后续的元素逐一比较,当所有的元素已经比较过,max中的值就是最大值。下面的程序中用max和min代表最大值和最小值,row1,column1,row2和column2分别代表最大值和最小值所在的行号和列号。


  1.         #include <stdio.h>
  2.         main()
  3.           { int a[4][4],i,j,max,row1,column1;
  4.             int min,row2,column2;
  5.             for (i=0;i<4;i++)
  6.               for (j=0;j<4;j++)
  7.                 scanf("%d",&a[i][j]);
  8.             max=a[0][0];row1=0;column1=0;
  9.             min=a[0][0];row2=0;column2=0;
  10.             for (i=0;i<4;i++)
  11.               for (j=0;j<4;j++)
  12.                 { if (max<a[i][j])
  13.                    {  max=a[i][j];
  14.                       row1=i;
  15.                       column1=j; }
  16.                   if (min>a[i][j])
  17.                     { min=a[i][j];
  18.                       row2=i;
  19.                       column2=j; }
  20.                 }
  21.             printf("max=%d,row=%d,column=%d",max,row1,column1);
  22.             printf("min=%d,row=%d,column=%d",min,row2,column2);
  23.           }
复制代码


程序运行结果如下:



1 3 5 7↙

2 4 6 8↙

-3 -5 -7 -9↙

-2 -4 -6 -8↙

max=8,row=1,column=3

min=-9,row=2,column=3

【例5-6】
数据统计中经常用到标准差的概念。假设有n个数di
(i=1~n),其标准差的计算公式如下:

其中,dd是di的平均值:
建立一个数组d[N]来存放各个di,先求所有di的平均值dd,然后求(di–dd)2之和,最后用标准差计算公式来求得标准差。程序如下:
   
#include <stdio.h>


  1.         #include <math.h>
  2.         #define N 1000
  3.         main()
  4.           { int i,n=0;
  5.             float d[N],dd,s;
  6.             do                         /* 循环输入d数组各元素*/
  7.               { scanf("%f",&d[n]);
  8.                 n++;
  9.                } while(d[n-1]!=0);       /* 输入0时结束 */
  10.             n--;                           /* 扣除多计入的1 */
  11.             dd=0;                          /* 进入平均值计算 */
  12.             for (i=0;i<n;i++)
  13.             dd+=d[i];
  14.             dd/=n;                         /* 求得平均值dd */
  15.             s=0;                           /* 进入计算标准差 */
  16.             for (i=0;i<n;i++)
  17.               s+=(d[i]-dd)*(d[i]-dd);   /* 用s暂存差的平方和 */
  18.             s=sqrt(s/(n-1));               /* 求得标准差s */
  19.             printf("s=%f",s);
  20.           }
复制代码


程序运行结果如下:

4.5 4.6 4.5 4.5 4.6 4.6 4.6 4.4 4.7 4.5↙

4.6 4.5 4.6 4.5 4.4 4.7 4.5 4.4 4.6 4.5↙

0↙

s=0.085294

上一章:C语言案例教程 - 第四章 程序流程控制
下一章:C语言案例教程 - 第六章:指 针






上一篇:C语言案例教程 - 第四章 程序流程控制
下一篇:C语言案例教程 - 第六章:指 针
authicon  楼主| 09927306 发表于 2011-1-8 13:13:36 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:50 编辑

【例5-7】
选择排序。假设有20个数,要求将它们按从小到大的顺序排列。
离开数组,任何排序算法都难以实现。因此,先将20个数存放在数组a中,然后进行选择排序。以20个元素从小到大排序为例,选择排序的基本思想是:第一轮从所有20个数中选出最小的数,即先将a[0]与其后的各个数a[j]进行比较,凡出现比a[0]小的数就记下它的位置j,经过一轮(共比较19次)后,最小的数就选择出来了,将它与a[0]交换位置。这样,经过第一轮比较,最小数被存放在a[0]中。第二轮从余下的19个数中选出最小的数存放在a[1]中,即将a[1]与其后的各个数a[j]进行比较,凡出现比a[1]小的数就记下它的位置j,经过这一轮(共比较18次)后,次小的数就选择出来了,把它交换到a[1]中。依次类推,到第19轮时,要从最后剩下的两个数中选出最小数存放在a[18]中,最大的数则落在a[19]中。至此,整个数组已经有序。程序实现时,要用两重循环,外层循环控制比较的轮数i(共19轮),内层循环控制该轮比较的次数j(j从i+1变化到20)。
要对n个数进行选择排序,总共要进行(n–1)+(n–2)+…+1=n(n–1)/2次比较和最多n–1次交换,是一种比较简单但效率较低的排序方法。程序如下:


  1.         #include <stdio.h>
  2.         #define N 20
  3.         main()
  4.           { int i,j,k;
  5.             float a[N],t;
  6.             for (i=0;i<N;i++)
  7.               scanf("%f",&a[i]);
  8.             for (i=0;i<N-1;i++)
  9.               { k=i;   
  10.                 for (j=i+1;j<N;j++)
  11.                   if (a[j]<a[k])
  12.                      k=j;       /* 记录比a[i]小的元素的位置 */
  13.                 if (i!=k)          /* 必要时进行交换 */
  14.                   { t=a[i]; a[i]=a[k]; a[k]=t; }
  15.                }
  16.             for (i=0;i<N;i++)
  17. printf("%6.2f%c",a[i],(i%10==9||i==N-1)?'':' ');
  18.                            /* 按每行10个元素输出排序结果 */
  19.           }
复制代码


程序运行结果如下:

2 3 6 1 7 5 10 8 15 20 4 9 19 11 18 16 17 12 14 13↙

1.00

2.00

3.00

4.00

5.00


6.00

7.00

8.00

9.00

10.00

11.00 12.00 13.00 14.00 15.00 16.00 17.00 18.00 19.00 20.00
如果要求从大到小排序,只要将内层循环中的if (a[j]<a[k])改为if (a[j]>a[k])即可。
【例5-8】
用冒泡排序算法对20个数按从小到大的顺序进行排序。
冒泡排序算法是另一种常用的排序算法。以20个元素从小到大排序为例,它的基本过程是:第一轮在所有的20个数中依次进行相邻两个数的比较,即先将a[0]与a[1]比较,若a[0]>a[1],则将二者交换;然后将a[1]与a[2]比较,若a[1]>a[2],则将二者交换;否则再进行下面两个相邻元素的比较。经过这一轮19次比较后,最大数已沉到数组的底部,即a[19]存放的是最大值。第二轮在去除最大数后剩余的19个数中同样进行两个相邻数的比较和交换,即a[0]与a[1]、a[1]与a[2]比较,经18次比较和交换后,次大数沉底,存放在a[18]中。依次类推,到第19轮时,将数组最顶部的两个数进行比较和交换,使最小数上浮到数组的顶部,存放在a[0]中。至此,排序过程结束。在整个排序过程中,每轮比较都使当前数据集合中的最大数沉底,而最小数则像气泡一样不断上浮,直到气泡上浮到数组的最顶部,排序过程即告结束,因此称之为冒泡排序。
冒泡排序的比较次数和选择排序相同,但交换次数比选择排序大。程序如下:


  1.        #include <stdio.h>
  2.         #define N 20
  3.         main()
  4.           { int i,j,k;
  5.             float a[N],t;
  6.             for (i=0;i<N;i++)
  7.               scanf("%f",&a[i]);
  8.             for (i=0;i<N-1;i++)
  9.               for (j=0;j<N-i-1;j++)
  10.                 if (a[j]>a[j+1])
  11.                   { t=a[j];
  12.                     a[j]=a[j+1];
  13.                     a[j+1]=t;
  14.                   }
  15.             for(i=0;i<N;i++)
  16.               printf("%6.2f%c",a[i],(i%10==9||i==N-1)?'':' ');
  17.           }
复制代码


程序运行结果如下:

20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1↙

1.00

2.00

3.00

4.00

5.00

6.00

7.00

8.00

9.00 10.00

11.00 12.00 13.00 14.00 15.00 16.00 17.00 18.00 19.00 20.00
【例5-9】
假设有n个从小到大排好序的数,存放在数组v中,请编制程序实现二分检索(对分检索、折半检索)算法。
二分检索算法通过每次将搜索区间缩小一半的方法,很快将搜索区间缩小为1个元素,从而确定是否查找到待查的数据。先设立3个标记:low指向搜索区间顶部,high指向搜索区间底部,mid=(low+high)/2则指向搜索区间中部。开始时,令low=0,high=n–1,即将整个数组作为搜索区间。当要查找某个x是否在数组v中时,按下列步骤进行。
(1)求mid=(low+high)/2,判断v[mid]是否等于x,若v[mid]=x,则已搜索到,查找结束;若v[mid]<x,说明x在区间后半部分,可令low=mid+1,high保持不变,即将该区间后半部分作为新的搜索区间;若v[mid]>x,说明x在区间的前半部分,可令high=mid–1,low保持不变,即将该区间上半部分作为新的搜索区间。总之,经过这次处理,搜索区间已缩小为原来的一半。
(2)在新的搜索区间上求mid=(low+high)/2,重复与(1)中相同的操作,可继续将搜索区间进一步缩小。
(3)   经过有限次(最多log2n次)搜索后,最终结果是:或者x已找到,或者已出现low=high,即区间缩小为只有1个元素。如果是后一种情况,就可以肯定地得到x是否在数组中的结论。
程序如下:


  1.         #include <stdio.h>
  2.         #define N 20
  3.         main()
  4.           { int v[N],x,low,high,mid,i;
  5.             printf("Enter data being sorted :\n");
  6.             for (i=0;i<N;i++)
  7.               scanf("%d",&v[i]);
  8.             printf("Enter number to be searched :\n");
  9.             scanf("%d",&x);
  10.             low=0;
  11.             high=N-1;
  12.             mid=(low+high)/2;
  13.             while (low<high&&x!=v[mid])
  14.               { if(x<v[mid])
  15.                   high=mid-1;
  16.                 else
  17.                   low=mid+1;
  18.                 mid=(low+high)/2;
  19.               }
  20.             if (x==v[mid])
  21.                printf("%d is at position %d.of array.",x,mid);
  22.             else
  23.                printf("%d is not in array.",x);
  24.           }
复制代码


程序运行时,先读入N个有序数,然后读入要查找的x,继而使用二分检索算法来进行查找。程序运行情况如下:

1 2 3 4 5 6 7 8 9 10↙

11 12 13 14 15 16 17 18 19 20↙

14↙

14 is at position 13 of array.
authicon  楼主| 09927306 发表于 2011-1-8 13:14:32 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:50 编辑

【例5-10】
用strlen函数测试给定字符串的长度。


  1. #include <string.h>
  2.      main()
  3.         { char s[]="ab\n\012\\"";
  4. printf("%d  ",strlen(s));
  5. s[3]=0;
  6. printf("%d\n",strlen(s));
  7.         }
复制代码


① 字符串"ab\n\012\\\"中除含有2个普通字符'a'和'b'外,还含有4个转义字符,分别是'\n'、'\012'、'\\'和'\'。由于每个转义字符只记作1个字符,且字符串末尾的'\0 '不计入字符串长度之内,因此该字符串的长度是6。
② 在C语言中,'\0'、0和NULL是等价的,都表示'\0'字符。经过s[3]=0赋值后,数组s中存放的是"ab\n\0\\\",而在计算字符串长度时,遇到'\0'字符就认为字符串结束,因此该字符串的长度计为3。
程序运行后,输出结果为:
6
3
【例5-11】
字符串拷贝函数的使用示例。


  1. #include <string.h>
  2.      main()
  3.         { char str[2][4];
  4.           strcpy(str[0],"you"); strcpy(str[1],"me");
  5.           printf("%s  %s\n",str[0],str[1]);
  6.           str[0][3]='&';
  7.           printf("%s  %s\n",str[0],str[1]);
  8.        }
复制代码


程序中strcpy(str[0],"you")的作用是将字符串"you"拷贝到str[0]中;同样,strcpy(arr[1],"me")的作用是将字符串"me"拷贝到arr[1]中。这时,数组str的存储情况为:
y

o

u

\0

m

e

\0

\0

因此,第一个printf()输出的结果为:you
me。
执行赋值语句arr[0][3]='&'后,arr[0]末尾的'\0'字符被替换成了字符'&',数组arr的存储情况变成:
y

o

u

&

m

e

\0

\0

第二个printf()函数在输出完arr[0]后,由于没有遇到'\0'字符,将越界继续输出arr[1]中的字符,直到遇到'\0'字符为止。因此,第二个printf()的输出为:you&me
me。
【例5-12】
编制程序,从给定的5个字符串中找出最小的字符串。
可将5个字符串存放在1个二维字符型数组str中,并设置1个一维字符型数组st用来存放最小的字符串。先将str中第一个字符串拷贝到st中,并以st为基准,逐个与str中余下的4个字符串比较,每次比较,总是将较小的字符串拷贝到st中。比较结束时,st中存放的就是最小的字符串。程序如下:


  1. #include <string.h>
  2.     main()
  3.       {char str[][10]={"Book","Basic","Boolen","Babble", "Bascket"}, st[10];
  4. int i;
  5. strcpy(st,str[0]);
  6. for(i=1;i<5;i++)
  7. if(strcmp(st,str[i])>0)
  8.    strcpy(st,str[i]);
  9.        printf("Minimum string is %s\n",st);
  10.    }
复制代码


程序运行结果如下:
Minimum string is Babble
【例5-13】
字符串连接函数使用示例。


  1. #include <string.h>
  2.         main()
  3.           { char s1[7]="ABC",s2[]="xyz",str[50]="abc";
  4.             strcat(str,strcat(s1,s2));
  5.             printf("%s",str);
  6.          }
复制代码


程序中使用了strcat函数的嵌套调用,内层调用为strcat(s1,s2),它将s2中的字符串连接到s1的末尾,使s1中存放的字符串变为ABCxyz,该字符串也是strcat(s1,s2)的返回值。外层调用为strcat(str,strcat(s1,s2)),相当于strcat(str,"ABCxyz"),因此,str中存放的字符串为abcABCxyz。
【例5-14】
若一个字符串正读和反读都一样,如level,madam等,我们称之为回文。请编一个程序验证输入的字符串是不是回文。
要验证一个字符串是不是回文,只要分别将它的第一个字符和最后一个字符、第二个字符和倒数第二个字符,直至最中间的两个字符进行比较,如果对应相等,说明它是回文,否则就不是。程序如下:


  1. #include <string.h>
  2.     #include <stdio.h>
  3.     main()
  4.      { char str[80];
  5.        int i,k,m=0;
  6.        gets(str);
  7.        k=strlen(str);
  8.        for( i=0;i<k/2;i++)
  9.          if (str[i]!=str[k-i-1]) { m=1;break;}
  10.        if (m)  printf("%s no.\n",str);
  11.        else  printf("%s yes.\n",str);
  12.      }
复制代码


程序中使用了变量m作为标志,其作用是标识循环是正常结束还是非正常退出。当逐对比较的字符都对应相同时,表示该字符串是回文,循环将正常结束;当逐对比较的字符中有一对不相同时,就说明该字符串不是回文,后续的比较就不再进行,先令m=1,而后通过break控制循环提前结束。因此,在循环出口处,根据m的值就可确定字符串是不是回文。
authicon  楼主| 09927306 发表于 2011-1-8 13:21:00 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:53 编辑

【例5-10】
用strlen函数测试给定字符串的长度。


  1. #include <string.h>
  2.      main()
  3.         { char s[]="ab\n\012\\"";
  4. printf("%d  ",strlen(s));
  5. s[3]=0;
  6. printf("%d\n",strlen(s));
  7.         }
复制代码


① 字符串"ab\n\012\\\"中除含有2个普通字符'a'和'b'外,还含有4个转义字符,分别是'\n'、'\012'、'\\'和'\'。由于每个转义字符只记作1个字符,且字符串末尾的'\0 '不计入字符串长度之内,因此该字符串的长度是6。
② 在C语言中,'\0'、0和NULL是等价的,都表示'\0'字符。经过s[3]=0赋值后,数组s中存放的是"ab\n\0\\\",而在计算字符串长度时,遇到'\0'字符就认为字符串结束,因此该字符串的长度计为3。
程序运行后,输出结果为:
6
3
【例5-11】
字符串拷贝函数的使用示例。


  1. #include <string.h>
  2.      main()
  3.         { char str[2][4];
  4.           strcpy(str[0],"you"); strcpy(str[1],"me");
  5.           printf("%s  %s\n",str[0],str[1]);
  6.           str[0][3]='&';
  7.           printf("%s  %s\n",str[0],str[1]);
  8.        }
复制代码


程序中strcpy(str[0],"you")的作用是将字符串"you"拷贝到str[0]中;同样,strcpy(arr[1],"me")的作用是将字符串"me"拷贝到arr[1]中。这时,数组str的存储情况为:
y

o

u

\0

m

e

\0

\0

因此,第一个printf()输出的结果为:you
me。
执行赋值语句arr[0][3]='&'后,arr[0]末尾的'\0'字符被替换成了字符'&',数组arr的存储情况变成:
y

o

u

&

m

e

\0

\0

第二个printf()函数在输出完arr[0]后,由于没有遇到'\0'字符,将越界继续输出arr[1]中的字符,直到遇到'\0'字符为止。因此,第二个printf()的输出为:you&me
me。
【例5-12】
编制程序,从给定的5个字符串中找出最小的字符串。
可将5个字符串存放在1个二维字符型数组str中,并设置1个一维字符型数组st用来存放最小的字符串。先将str中第一个字符串拷贝到st中,并以st为基准,逐个与str中余下的4个字符串比较,每次比较,总是将较小的字符串拷贝到st中。比较结束时,st中存放的就是最小的字符串。程序如下:


  1. #include <string.h>
  2.     main()
  3.       {char str[][10]={"Book","Basic","Boolen","Babble", "Bascket"}, st[10];
  4. int i;
  5. strcpy(st,str[0]);
  6. for(i=1;i<5;i++)
  7. if(strcmp(st,str[i])>0)
  8.    strcpy(st,str[i]);
  9.        printf("Minimum string is %s\n",st);
  10.    }
复制代码


程序运行结果如下:
Minimum string is Babble
【例5-13】
字符串连接函数使用示例。


  1. #include <string.h>
  2.         main()
  3.           { char s1[7]="ABC",s2[]="xyz",str[50]="abc";
  4.             strcat(str,strcat(s1,s2));
  5.             printf("%s",str);
  6.          }
复制代码


程序中使用了strcat函数的嵌套调用,内层调用为strcat(s1,s2),它将s2中的字符串连接到s1的末尾,使s1中存放的字符串变为ABCxyz,该字符串也是strcat(s1,s2)的返回值。外层调用为strcat(str,strcat(s1,s2)),相当于strcat(str,"ABCxyz"),因此,str中存放的字符串为abcABCxyz。
【例5-14】
若一个字符串正读和反读都一样,如level,madam等,我们称之为回文。请编一个程序验证输入的字符串是不是回文。
要验证一个字符串是不是回文,只要分别将它的第一个字符和最后一个字符、第二个字符和倒数第二个字符,直至最中间的两个字符进行比较,如果对应相等,说明它是回文,否则就不是。程序如下:


  1. #include <string.h>
  2.     #include <stdio.h>
  3.     main()
  4.      { char str[80];
  5.        int i,k,m=0;
  6.        gets(str);
  7.        k=strlen(str);
  8.        for( i=0;i<k/2;i++)
  9.          if (str[i]!=str[k-i-1]) { m=1;break;}
  10.        if (m)  printf("%s no.\n",str);
  11.        else  printf("%s yes.\n",str);
  12.      }
复制代码


程序中使用了变量m作为标志,其作用是标识循环是正常结束还是非正常退出。当逐对比较的字符都对应相同时,表示该字符串是回文,循环将正常结束;当逐对比较的字符中有一对不相同时,就说明该字符串不是回文,后续的比较就不再进行,先令m=1,而后通过break控制循环提前结束。因此,在循环出口处,根据m的值就可确定字符串是不是回文。
authicon  楼主| 09927306 发表于 2011-1-8 13:22:52 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:53 编辑

【例5-10】
用strlen函数测试给定字符串的长度。


  1. #include <string.h>
  2.      main()
  3.         { char s[]="ab\n\012\\"";
  4. printf("%d  ",strlen(s));
  5. s[3]=0;
  6. printf("%d\n",strlen(s));
  7.         }
复制代码


① 字符串"ab\n\012\\\"中除含有2个普通字符'a'和'b'外,还含有4个转义字符,分别是'\n'、'\012'、'\\'和'\'。由于每个转义字符只记作1个字符,且字符串末尾的'\0 '不计入字符串长度之内,因此该字符串的长度是6。
② 在C语言中,'\0'、0和NULL是等价的,都表示'\0'字符。经过s[3]=0赋值后,数组s中存放的是"ab\n\0\\\",而在计算字符串长度时,遇到'\0'字符就认为字符串结束,因此该字符串的长度计为3。
程序运行后,输出结果为:
6
3
【例5-11】
字符串拷贝函数的使用示例。


  1. #include <string.h>
  2.      main()
  3.         { char str[2][4];
  4.           strcpy(str[0],"you"); strcpy(str[1],"me");
  5.           printf("%s  %s\n",str[0],str[1]);
  6.           str[0][3]='&';
  7.           printf("%s  %s\n",str[0],str[1]);
  8.        }
复制代码


程序中strcpy(str[0],"you")的作用是将字符串"you"拷贝到str[0]中;同样,strcpy(arr[1],"me")的作用是将字符串"me"拷贝到arr[1]中。这时,数组str的存储情况为:
y

o

u

\0

m

e

\0

\0

因此,第一个printf()输出的结果为:you
me。
执行赋值语句arr[0][3]='&'后,arr[0]末尾的'\0'字符被替换成了字符'&',数组arr的存储情况变成:
y

o

u

&

m

e

\0

\0

第二个printf()函数在输出完arr[0]后,由于没有遇到'\0'字符,将越界继续输出arr[1]中的字符,直到遇到'\0'字符为止。因此,第二个printf()的输出为:you&me
me。
【例5-12】
编制程序,从给定的5个字符串中找出最小的字符串。
可将5个字符串存放在1个二维字符型数组str中,并设置1个一维字符型数组st用来存放最小的字符串。先将str中第一个字符串拷贝到st中,并以st为基准,逐个与str中余下的4个字符串比较,每次比较,总是将较小的字符串拷贝到st中。比较结束时,st中存放的就是最小的字符串。程序如下:


  1. #include <string.h>
  2.     main()
  3.       {char str[][10]={"Book","Basic","Boolen","Babble", "Bascket"}, st[10];
  4. int i;
  5. strcpy(st,str[0]);
  6. for(i=1;i<5;i++)
  7. if(strcmp(st,str[i])>0)
  8.    strcpy(st,str[i]);
  9.        printf("Minimum string is %s\n",st);
  10.    }
复制代码


程序运行结果如下:
Minimum string is Babble
【例5-13】
字符串连接函数使用示例。


  1. #include <string.h>
  2.         main()
  3.           { char s1[7]="ABC",s2[]="xyz",str[50]="abc";
  4.             strcat(str,strcat(s1,s2));
  5.             printf("%s",str);
  6.          }
复制代码


程序中使用了strcat函数的嵌套调用,内层调用为strcat(s1,s2),它将s2中的字符串连接到s1的末尾,使s1中存放的字符串变为ABCxyz,该字符串也是strcat(s1,s2)的返回值。外层调用为strcat(str,strcat(s1,s2)),相当于strcat(str,"ABCxyz"),因此,str中存放的字符串为abcABCxyz。
【例5-14】
若一个字符串正读和反读都一样,如level,madam等,我们称之为回文。请编一个程序验证输入的字符串是不是回文。
要验证一个字符串是不是回文,只要分别将它的第一个字符和最后一个字符、第二个字符和倒数第二个字符,直至最中间的两个字符进行比较,如果对应相等,说明它是回文,否则就不是。程序如下:


  1. #include <string.h>
  2.     #include <stdio.h>
  3.     main()
  4.      { char str[80];
  5.        int i,k,m=0;
  6.        gets(str);
  7.        k=strlen(str);
  8.        for( i=0;i<k/2;i++)
  9.          if (str[i]!=str[k-i-1]) { m=1;break;}
  10.        if (m)  printf("%s no.\n",str);
  11.        else  printf("%s yes.\n",str);
  12.      }
复制代码


程序中使用了变量m作为标志,其作用是标识循环是正常结束还是非正常退出。当逐对比较的字符都对应相同时,表示该字符串是回文,循环将正常结束;当逐对比较的字符中有一对不相同时,就说明该字符串不是回文,后续的比较就不再进行,先令m=1,而后通过break控制循环提前结束。因此,在循环出口处,根据m的值就可确定字符串是不是回文。
authicon  楼主| 09927306 发表于 2011-1-8 13:25:08 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:54 编辑

【例5-15】
编制程序,其功能是从键盘输入一个字符串,然后将该字符串中的字符'a'全部替换成字符'b'。
通过循环从字符串的第一个字符起逐个向后搜索,凡遇到字符'a',就用赋值语句将它替换成字符'b'。当已达到字符串末尾的'\0'字符时,整个替换工作结束。程序如下:


  1.     #include <string.h>
  2.     #include <stdio.h>
  3.     main()
  4.      { char str[80];
  5.        int i=0;
  6.        gets(str);
  7.        printf("before replacing: %s\n",str);
  8.        while(str[i])
  9.          { if (str[i]=='a')
  10. str[i]='b';
  11.            i++; }
  12.        printf("after replacing: %s\n",str);
  13.      }
复制代码


【例5-16】
编制程序,其功能是从键盘输入一个字符串,然后将该字符串中指定的字符删除。
由于字符串占用一片连续的存储空间,删除某个字符只要将该字符后续的字符顺序向前移动一个位置。例如,要删除字符串"abcd"中的'b',只要将字符'c'和'd'顺序向前移动一个位置。程序如下:


  1.    #include <string.h>
  2.     #include <stdio.h>
  3.     main()
  4.      { char str[80],ch;
  5.        int i=0,j;
  6.        printf("Enter a string:");
  7.        gets(str);
  8.        printf("Enter a character to be deleted:");
  9.        scanf("%c",&ch);
  10.        while(str[i])
  11.          { if (str[i]==ch)
  12.              for(j=i;str[j];j++)
  13.                str[j]=str[j+1];
  14.           else
  15.             i++;
  16.          }
  17.        str[i]='\0';
  18.        printf("after deleting: %s\n",str);
  19.      }
复制代码


程序中用改变i的值来逐个审视str中的各个字符是不是要删除。如果要删除的字符连续出现,为使这些字符都被删除,每当移动完该字符后续的字符后,暂不修改i的值,继续判断移动到i位置上的字符是不是还要删除。
【例5-17】
编制程序,其功能是从键盘输入1个字符串,然后在指定的字符前插入1个字符。
与例5-16相仿,插入字符实际上是将该字符及其后续字符均向后移动1个位置,在空出的位置上放置要插入的字符。例如,要在字符串"abcd"中的字符'b'前插入1个字符'e',只要将字符'b'、'c'、'd'顺序后移1个位置,在腾出的空位上放入字符'e'即可。程序如下:


  1.     #include <string.h>
  2.     #include <stdio.h>
  3.     main()
  4.      { char str[80],ch1,ch2;
  5.        int i=0,j,k;
  6.        printf("Enter a string:");
  7.        gets(str);
  8.        printf("Enter a character expressing the position to be inserted:");
  9.        scanf("%c%*c",&ch1);
  10.        printf("Enter a character to be inserted:");
  11.        scanf("%c",&ch2);
  12.        while(str[i])
  13.          { k=strlen(str);
  14.            if (str[i]==ch1)
  15.              { for(j=k;j>i;j--)
  16.                  str[j]=str[j-1];
  17.                str[i]=ch2;
  18.                str[k+1]='\0';
  19.                i++;
  20.              }
  21.            i++;
  22.          }
  23.        printf("after inserting: %s\n",str);
  24.      }
复制代码


对程序说明如下。
① 在执行scanf("%c",&ch1)时,从键盘输入一个字符并以回车键结束,输入的字符被变量ch1接收,但回车符将被下一个scanf()中的ch2接收,为此,增加了一个抑制输入控制符“%*c”,其作用是使回车符被跳过。
② 为了插入一个字符,需要移动指定位置及其后续的各个字符,这种移动要从字符串末尾开始顺序移动。因此,字符串中最后一个字符的位置要由字符串的长度确定,而随着字符的插入,字符串的长度是在变化的。
③ 由于字符的移动,造成字符串末尾的'\0'字符被最后一个字符替换掉,因此在插入字符后,应在字符串末尾增加一个'\0'字符。
④ 当在某字符前插入一个字符后,该字符已被移动到下一个位置,为了防止无休止地插入,一旦某字符前已插入字符,就应跳过该字符。例如,当字符串"abcd"中的字符'b'前插入一个字符'e'后,字符'b'已经移动到第3号位置上,这时就应跳过'b'字符,继续审视再下一个字符。
程序运行时,如果从键盘输入的字符串为"abccdcce",要在其前面插入字符的字符为'c',插入的字符为'x',则程序运行结果为:
→→Enter a string:abccdcce

Enter a character expressing the position to be inserted:c
Enter a character to be inserted:x
after inserting: abxcxcdxcxce

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-3 17:15

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表