说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

字符数组-C语言教程

HTML文档下载 WORD文档下载 PDF文档下载
在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。用来存放字符量的数组称为字符数组。
7.3 字符数组
用来存放字符量的数组称为字符数组。
7.3.1 字符数组的定义
形式与前面介绍的数值数组相同。
例如:
    char c[10];
由于字符型和整型通用,也可以定义为int c[10]但这时每个数组元素占2个字节的内存单元。
字符数组也可以是二维或多维数组。
例如:
    char c[5][10];
即为二维字符数组。
7.3.2 字符数组的初始化
字符数组也允许在定义时作初始化赋值。
例如:
    char c[10]={‘c’, ‘  ’, ‘p’, ‘r’, ‘o’, ‘g’, ‘r’, ‘a’,’m’};
赋值后各元素的值为:
    数组C    c[0]的值为‘c’
c[1]的值为‘ ’
c[2]的值为‘p’ 
c[3]的值为‘r’
c[4]的值为‘0’
c[5]的值为‘g’
c[6]的值为‘r’
c[7]的值为‘a’
c[8]的值为‘m’
其中c[9]未赋值,由的值为‘p’系统自动赋予0值。
当对全体元素赋初值时也可以省去长度说明。
例如:
    char c[]={`c`,` `,`p`,`r`,`o`,`g`,`r`,`a`,`m`};
这时C数组的长度自动定为9。
7.3.3 字符数组的引用
【例7.8】
main(){  int i,j;  char a[][5]={{'B','A','S','I','C',},{'d','B','A','S','E'}};  for(i=0;i<=1;i++)    {      for(j=0;j<=4;j++)          printf("%c",a[i][j]);      printf("\n");    }}
本例的二维字符数组由于在初始化时全部元素都赋以初值,因此一维下标的长度可以不加以说明。
7.3.4 字符串和字符串结束标志
在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。前面介绍字符串常量时,已说明字符串总是以'\0'作为串的结束符。因此当把一个字符串存入一个数组时,也把结束符'\0'存入数组,并以此作为该字符串是否结束的标志。有了'\0'标志后,就不必再用字符数组的长度来判断字符串的长度了。
C语言允许用字符串的方式对数组作初始化赋值。
例如:
    char c[]={'c', ' ','p','r','o','g','r','a','m'};
可写为:
        char c[]={"C program"};
    或去掉{}写为:
        char c[]="C program";
用字符串方式赋值比用字符逐个赋值要多占一个字节, 用于存放字符串结束标志'\0'。上面的数组c在内存中的实际存放情况为:

C

 

p

r

o

g

r

a

m

\0

    ‘\0'是由C编译系统自动加上的。由于采用了‘\0'标志,所以在用字符串赋初值时一般无须指定数组的长度, 而由系统自行处理。
7.3.5 字符数组的输入输出
在采用字符串方式后,字符数组的输入输出将变得简单方便。
除了上述用字符串赋初值的办法外,还可用printf函数和scanf函数一次性输出输入一个字符数组中的字符串,而不必使用循环语句逐个地输入输出每个字符。
【例7.9】
main(){  char c[]="BASIC\ndBASE";  printf("%s\n",c);}
注意在本例的printf函数中,使用的格式字符串为“%s”,表示输出的是一个字符串。而在输出表列中给出数组名则可。不能写为:
printf("%s",c[]);
【例7.10】
main(){  char st[15];  printf("input string:\n");  scanf("%s",st);  printf("%s\n",st);}
本例中由于定义数组长度为15,因此输入的字符串长度必须小于15,以留出一个字节用于存放字符串结束标志`\0`。应该说明的是,对一个字符数组,如果不作初始化赋值,则必须说明数组长度。还应该特别注意的是,当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。
例如当输入的字符串中含有空格时,运行情况为:
    input string:
        this is a book
输出为:
this
从输出结果可以看出空格以后的字符都未能输出。为了避免这种情况,可多设几个字符数组分段存放含空格的串。
程序可改写如下:
【例7.11】
main(){  char st1[6],st2[6],st3[6],st4[6];  printf("input string:\n");  scanf("%s%s%s%s",st1,st2,st3,st4);  printf("%s %s %s %s\n",st1,st2,st3,st4);}
    本程序分别设了四个数组, 输入的一行字符的空格分段分别装入四个数组。然后分别输出这四个数组中的字符串。
在前面介绍过,scanf的各输入项必须以地址方式出现,如 &a,&b等。但在前例中却是以数组名方式出现的,这是为什么呢?
这是由于在C语言中规定,数组名就代表了该数组的首地址。整个数组是以首地址开头的一块连续的内存单元。
如有字符数组char c[10],在内存可表示如图。

C[0]

C[1]

C[2]

C[3]

C[4]

C[5]

C[6]

C[7]

C[8]

C[9]

设数组c的首地址为2000,也就是说c[0]单元地址为2000。则数组名c就代表这个首地址。因此在c前面不能再加地址运算符&。如写作scanf("%s",&c);则是错误的。 在执行函数printf("%s",c) 时,按数组名c找到首地址,然后逐个输出数组中各个字符直到遇到字符串终止标志'\0'为止。
7.3.6 字符串处理函数
C语言提供了丰富的字符串处理函数, 大致可分为字符串的输入、输出、合并、修改、比较、转换、复制、搜索几类。 使用这些函数可大大减轻编程的负担。用于输入输出的字符串函数,在使用前应包含头文件"stdio.h",使用其它字符串函数则应包含头文件"string.h"。
下面介绍几个最常用的字符串函数。
1. 字符串输出函数 puts
   格式:  puts (字符数组名)
   功能:把字符数组中的字符串输出到显示器。 即在屏幕上显示该字符串。
【例7.12】
#include"stdio.h"main(){  char c[]="BASIC\ndBASE";  puts(c);}
    从程序中可以看出puts函数中可以使用转义字符,因此输出结果成为两行。puts函数完全可以由printf函数取代。当需要按一定格式输出时,通常使用printf函数。
2. 字符串输入函数gets
   格式:  gets  (字符数组名)
   功能:从标准输入设备键盘上输入一个字符串。
 本函数得到一个函数值,即为该字符数组的首地址。
【例7.13】
#include"stdio.h"main(){  char st[15];  printf("input string:\n");  gets(st);  puts(st);}
    可以看出当输入的字符串中含有空格时,输出仍为全部字符串。说明gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束。这是与scanf函数不同的。
3. 字符串连接函数strcat
   格式:  strcat (字符数组名1,字符数组名2)
   功能:把字符数组2中的字符串连接到字符数组1 中字符串的后面,并删去字符串1后的串标志“\0”。本函数返回值是字符数组1的首地址。
【例7.14】
#include"string.h"main(){  static char st1[30]="My name is ";  int st2[10];  printf("input your name:\n");  gets(st2);  strcat(st1,st2);  puts(st1);}
    本程序把初始化赋值的字符数组与动态赋值的字符串连接起来。要注意的是,字符数组1应定义足够的长度,否则不能全部装入被连接的字符串。
4. 字符串拷贝函数strcpy
   格式:  strcpy (字符数组名1,字符数组名2)
   功能:把字符数组2中的字符串拷贝到字符数组1中。串结束标志“\0”也一同拷贝。字符数名2,也可以是一个字符串常量。这时相当于把一个字符串赋予一个字符数组。
【例7.15】
#include"string.h"main(){  char st1[15],st2[]="C Language";  strcpy(st1,st2);  puts(st1);printf("\n");}
本函数要求字符数组1应有足够的长度,否则不能全部装入所拷
贝的字符串。
5. 字符串比较函数strcmp
   格式:  strcmp(字符数组名1,字符数组名2)
   功能:按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。
          字符串1=字符串2,返回值=0;
  字符串2〉字符串2,返回值〉0;
  字符串1〈字符串2,返回值〈0。
本函数也可用于比较两个字符串常量,或比较数组和字符串常量。
【例7.16】
#include"string.h"main(){ int k;  static char st1[15],st2[]="C Language";  printf("input a string:\n");  gets(st1);  k=strcmp(st1,st2);  if(k==0) printf("st1=st2\n");  if(k>0) printf("st1>st2\n");  if(k<0) printf("st1<st2\n");}
本程序中把输入的字符串和数组st2中的串比较,比较结果返回到k中,根据k值再输出结果提示串。当输入为dbase时,由ASCII 码可知“dBASE”大于“C Language”故k〉0,输出结果“st1>st2”。
6. 测字符串长度函数strlen
   格式:  strlen(字符数组名)
   功能:测字符串的实际长度(不含字符串结束标志‘\0’) 并作为函数返回值。
【例7.17】
#include"string.h"main(){ int k;  static char st[]="C language";  k=strlen(st);  printf("The lenth of the string is %d\n",k);}
7.4 程序举例
【例7.18】把一个整数按大小顺序插入已排好序的数组中。
为了把一个数按大小插入已排好序的数组中,应首先确定排序是从大到小还是从小到大进行的。设排序是从大到小进序的,则可把欲插入的数与数组中各数逐个比较,当找到第一个比插入数小的元素i时,该元素之前即为插入位置。然后从数组最后一个元素开始到该元素为止,逐个后移一个单元。最后把插入数赋予元素i即可。如果被插入数比所有的元素值都小则插入最后位置。
main(){  int i,j,p,q,s,n,a[11]={127,3,6,28,54,68,87,105,162,18};  for(i=0;i<10;i++)      { p=i;q=a[i];	for(j=i+1;j<10;j++)	if(q<a[j]) {p=j;q=a[j];}	if(p!=i)	{	  s=a[i];	  a[i]=a[p];	  a[p]=s;	}	printf("%d ",a[i]);      }    printf("\ninput number:\n");    scanf("%d",&n);    for(i=0;i<10;i++)      if(n>a[i])      {for(s=9;s>=i;s--) a[s+1]=a[s];      break;}      a[i]=n;    for(i=0;i<=10;i++)      printf("%d ",a[i]);    printf("\n");}
本程序首先对数组a中的10个数从大到小排序并输出排序结果。然后输入要插入的整数n。再用一个for语句把n和数组元素逐个比较,如果发现有n>a[i]时,则由一个内循环把i以下各元素值顺次后移一个单元。后移应从后向前进行(从a[9]开始到a[i]为止)。 后移结束跳出外循环。插入点为i,把n赋予a[i]即可。 如所有的元素均大于被插入数,则并未进行过后移工作。此时i=10,结果是把n赋于a[10]。最后一个循环输出插入数后的数组各元素值。
    程序运行时,输入数47。从结果中可以看出47已插入到54和 28之间。
【例7.19】在二维数组a中选出各行最大的元素组成一个一维数组b。
a=( 3  16 87  65
  4  32 11 108 
10 25 12  37)
b=(87 108 37)
本题的编程思路是,在数组A的每一行中寻找最大的元素,找到之后把该值赋予数组B相应的元素即可。程序如下:
main(){    int a[][4]={3,16,87,65,4,32,11,108,10,25,12,27};    int b[3],i,j,l;    for(i=0;i<=2;i++)      { l=a[i][0];	for(j=1;j<=3;j++)	if(a[i][j]>l) l=a[i][j];	b[i]=l;}    printf("\narray a:\n");    for(i=0;i<=2;i++)      { for(j=0;j<=3;j++)	printf("%5d",a[i][j]);	printf("\n");}      printf("\narray b:\n");    for(i=0;i<=2;i++)      printf("%5d",b[i]);    printf("\n");}
程序中第一个for语句中又嵌套了一个for语句组成了双重循环。外循环控制逐行处理,并把每行的第0列元素赋予l。进入内循环后,把l与后面各列元素比较,并把比l大者赋予l。内循环结束时l 即为该行最大的元素,然后把l值赋予b[i]。等外循环全部完成时,数组b中已装入了a各行中的最大值。后面的两个 for语句分别输出数组a和数组b。
【例7.20】输入五个国家的名称按字母顺序排列输出。
    本题编程思路如下:五个国家名应由一个二维字符数组来处理。然而C语言规定可以把一个二维数组当成多个一维数组处理。 因此本题又可以按五个一维数组处理, 而每一个一维数组就是一个国家名字符串。用字符串比较函数比较各一维数组的大小,并排序,输出结果即可。
编程如下:
main(){    char st[20],cs[5][20];    int i,j,p;    printf("input country's name:\n");    for(i=0;i<5;i++)      gets(cs[i]);    printf("\n");    for(i=0;i<5;i++)      { p=i;strcpy(st,cs[i]);	for(j=i+1;j<5;j++)      if(strcmp(cs[j],st)<0) {p=j;strcpy(st,cs[j]);}    if(p!=i)      {	strcpy(st,cs[i]);	strcpy(cs[i],cs[p]);	strcpy(cs[p],st);      }    puts(cs[i]);}printf("\n");}
本程序的第一个for语句中,用gets函数输入五个国家名字符串。上面说过C语言允许把一个二维数组按多个一维数组处理,本程序说明cs[5][20]为二维字符数组,可分为五个一维数组cs[0],cs[1],cs[2],cs[3],cs[4]。因此在gets函数中使用cs[i]是合法的。 在第二个for语句中又嵌套了一个for语句组成双重循环。这个双重循环完成按字母顺序排序的工作。在外层循环中把字符数组cs[i]中的国名字符串拷贝到数组st中,并把下标i赋予P。进入内层循环后,把st与cs[i]以后的各字符串作比较,若有比st小者则把该字符串拷贝到st中,并把其下标赋予p。内循环完成后如p不等于i说明有比cs[i]更小的字符串出现,因此交换cs[i]和st的内容。至此已确定了数组cs的第i号元素的排序值。然后输出该字符串。在外循环全部完成之后即完成全部排序和输出。
7.5 本章小结
1.数组是程序设计中最常用的数据结构。数组可分为数值数组(整数组,实数组),字符数组以及后面将要介绍的指针数组,结构数组等。
2.数组可以是一维的,二维的或多维的。
3.数组类型说明由类型说明符、数组名、数组长度(数组元素个数)三部分组成。数组元素又称为下标变量。 数组的类型是指下标变量取值的类型。
4.对数组的赋值可以用数组初始化赋值,输入函数动态赋值和赋值语句赋值三种方法实现。 对数值数组不能用赋值语句整体赋值、输入或输出,而必须用循环语句逐个对数组元素进行操作。
Swift的初始化方法 TIOBE 2015年1月编程语言排行榜:JavaScript成大赢家 为什么iOS开发不需要Storyboard? 仅有纽扣大小的开发板 Intel Curie “撒娇”的豌豆荚?被百度手机助手屏蔽太糟心! 【工具推荐】Pgcli—自动完成和语法高亮的Postgres命令行工具 CES 2015:挑一款机器人带回家? 夜行、睡眠与健康:CES 2015十款酷炫的可穿戴产品 Java 9中新的货币API 唯“简”不破,Apple Watch App的设计之道 Google Glass从X labs“毕业”,更换项目负责人 不进化,则消亡——互联网时代企业管理的十项实践 RedMonk 2015年1月编程语言排行榜:进击的Swift! 微信开放JS SDK,这场web巨变意味着什么? 盘点一些iOS开发技巧:Swift和Objective-C 2014年,那些“颜值”爆表的UI动画 《近匠》爱加密:谁说iOS应用不需要保护? SwiftColorArt:开源易用的Swift图片类库 人气爆棚 干货满满 中国电信天翼开放平台开放日圆满落幕 必须Mark!43个优秀的Swift开源项目推荐 治拖延、疗懒癌!安利12款提高工作效率工具 把ES6带进Node社区 Io.js 1.0.0正式发布 Java 2014:10个最热门、最具争议性的话题 回顾:2014年最流行前端开发框架对比评测 实例讲解SQL注入攻击 调试大规模服务器集群的五大策略 .NET编译平台Rosly将迁移到Github Wasai虚拟现实头盔与体验馆发布:虚拟现实的线下经济 订票系统不再瘫痪 阿里云确认与12306合作 Apple前工程师Warren Moore:Swift中Metal使用初体验 手把手教学:详解Swift中的iOS设计模式 急救! 如何操作磁卡读写器 Help,如何更改DataGrid控件选中那个单元格的背景色和前景色? 2000共享文件问题,请高手看一下,很古怪的! 朋友,你好! 离开 论坛 散分【四】 高手救命,简单数据库规划问题!!!价值50分!!! 想听听大家对 static 命名的函数、变量的用法 Access数据库传到服务器后,变为只读了?求助,白思不得其解 请问怎样取得PCM流 离开 论坛 散分【五】 打包,解包??? 离开 论坛 散分【六】 离开 论坛 散分【七】 求教SQL语句,高手、或刚入门的同道都进来讨论一哈 最初linux使用什么编译开发的? 离开 论坛 散分【八】 关于字符串截取问题 谁有FASTREPORT的注册版本 我急用!在线等待!谢谢! 离开 论坛 散分【九】 Application.messagebox和messagebox有什么区别呢? 水晶报表的两个小问题? 怎样向Foxpro表中添加float型数据? 离开 论坛 散分【十】 问一个和Session有关的问题,达人请进 在宏里把ie关闭。非常感谢 如何让window.showModalDialog的page提交数据到原来的父页面? 合租住房!! 有没有一个命令直接解开iso文件或提取里面的一个文件或文件夹 请给看看程序:AVI视频的读取和重建 如何显示出电脑内已经注册的dll文件列表? 中程浮点数问题! solaris下CC编译器的问题? UML的书籍和软件? 那里有vs.net2003的vss6.0d版本? 有时候exe文件不能运行? 自己准备写一个工资发放和发布的程序,欢迎探讨. 襄儿妹妹还在吗?幸好偶这个马甲还有点分,全给你吧,这个ID密码她不知道呵呵~~~ 关于linux WEB服务器名的问题? 请教ATL中CBindStatusCallback的问题 我的IE不能打开新窗口?用鼠标左键点击超链接没有反应? 我的项目改变目录后打不开,怎么办? 多CPU机器,同时可有几个线程处于运行状态? 高分求高效高斯模糊算法。。 如何判断软件是否过期 是不是运行ASP.Net应用的服务器必须安装.Net FrameWork呢?还是只要有Win2000 Server和IIS就行。 谈情说爱 清除内存中用call调用的脚本文件? 一个很老的问题,如何避免CListCtrl闪烁。 请大家给看看程序:avi视频读取和重建 研究数字图像处理应该那些知识? 丨x一1丨十丨y十2丨二0,求x十y的值. STB是什么意思啊?详细讲解哦 22 (22 8:59:5)1.在△ABC中,AB=AC,D为△ABC外一点,AD交BC于E,求证:AB2=AD×AE.2.在平行四边形ABCD中,AM⊥BC于M,AN⊥CD于N,求证:△AMN∽△ABC. 已知x^2一5x十1二0,求x^4十1/x^4的值 鲁迅的《朝花夕拾》是一部散文集,其中作者回忆了自己青少年时代的两位,他们分别是谁?各是什么样的形象?他们一个是寿镜吾一个是藤野先生 爸爸会伯伯共同投资了一个工程项目总投资为320万元其中伯伯的资产占总资产的5成5那么爸爸和伯伯分投资了多少钱? 若丨x+1丨+(x+y-2)²=0,求2x+y的值急 若丨x丨=5,丨y丨=2,且x>y>0,求x+y的值 “父亲的病”这篇文章是不是出自《朝花夕拾》这本散文集里?是第几章的? 奥林匹克公园怎么走谁可以告诉我下?我现在在丰台六里桥,谁知道我坐什么车可以到吗? 这个是什么卦..阳爻—— 阴爻———— 老阴爻———— X 阳爻—— 阳爻—— 老阳爻——X请大神们指教啊,这个后面的数字都是什么啊 最下面是初九然后依次往上是怎么算的? 俄罗斯警方逮捕一名系自杀式炸弹腰带男F35中距离导弹试射成功 日本自卫队美国一航天飞机“追梦者”试飞降落时滑俄罗斯警方逮捕一名系自杀式炸弹腰带男日本花美男惊艳女装照 让女生情何以堪安倍警卫车队连续两天发生交通事故 无日本一空宅被拆除时惊现\"死婴罐\"民调显示日本近1/4年轻人称自己在“美国一航天飞机“追梦者”试飞降落时滑新加坡欲购88套美国多管制导火箭发射日媒披露日本或早已成为美情报机构窃听【热点】重磅消息突袭!房地产要变天?【推荐】这三句话,改变无数人!你敢看【看点】一家公司要了你后,凭什么给你68岁身价70亿,开劳斯莱斯,政府送Uber回击微信“封杀” 公开ICP世纪佳缘、百合网合并 吴琳光任首席执让我强行安利一下#主要看气质#的正确耐克与“詹皇”签下终身合约51分!马刺创分差纪录狂虐76人北京接待国际会议数量亚洲领先广东清远职业技术学院党委书记苏浩志被
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘