大一上语音上课第6章数组_第1页
大一上语音上课第6章数组_第2页
大一上语音上课第6章数组_第3页
大一上语音上课第6章数组_第4页
大一上语音上课第6章数组_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第6章数组6.1一维数组6.2二维数组6.3字符串及其操作6.4应用举例

数组,一种构造型的数据类型,用户根据不同的实际需求,将属于同一数据类型的一组数据按照一定规律组织在一起。6.1一维数组定义方式为:

数据类型

数组名[整型常量表达式]

例如:inta[10];//它表示数组名为a,此数组可以存放10个整型数据说明:(1)数据类型,指数组中元素的数据类型,所有元素必须是同一数据类型。(2)数组名,命名规则遵循标识符的命名规则,数组名与其后的“方括号”之间不能有空格分隔。(3)只能使用“方括号”,并且方括号中只能是常量表达式,不能使用变量。常量表达式的值代表这一数组最多可以存放元素的个数,也称为“数组的大小”。例:如下数组的定义是否合法?inta(5);

char123b[10];intk=5;floatc[k];#defineM20intnum[M];

不合法,没有使用“[]”不合法,数组名命名不合法,不能以数字开头不合法,虽然k已赋值,但k是变量,不能标识数组大小合法,M是利用编译预处理命令define定义的符号常量对于普通变量:假设有定义:inta;我们可以获知:(1)变量名:a(2)变量的值:不确定(3)变量在内存中的地址:&a(4)在内存中占多少个字节:一个整型数据占据的字节数(5)在引用中变量名a代表变量的值对于一维数组(存放一组同类型的变量)假设有定义:inta[5];我们可以获知:(1)数组名:a(2)该数组在内存存放的首地址:a(3)数组最多存放5个整型数据,因此在内存占字节数:5*sizeof(int),并且是连续存放。其中,关键字sizeof的功能是计算得出相应数据类型在当前计算机系统中所占字节数。(4)数组中各个变量的名称:a[0]、a[1]、a[2]、a[3]、a[4]。其中0、1、2、3、4称为数组下标,下标从0开始。引用时a[下标]代表相应变量的值。(5)数组中各个变量在内存中的地址:&a[0]、&a[1]、&a[2]、&a[3]、&a[4]。可以发现:a=&a[0]对于普通变量的引用举例:一维数组各元素的引用举例:#include<stdio.h>voidmain(){inta;//定义

scanf(“a=%d”,&a);//&a表示变量的地址printf(“a=%d”,a);//变量名a代表变量的值}程序运行情况是:a=5↙a=5#include<stdio.h>voidmain(){inti,a[5];//定义一维整型数组aprintf(“pleaseinputnumbers:”);for(i=0;i<=4;i++)scanf(“%d”,&a[i]);/*循环体,为数组每个元素输入值,&a[i]表示第i个元素的地址*/for(i=0;i<=4;i++)printf(“a[%d]=%d”,i,a[i]);/*循环体,输出数组每个元素,a[i]表示第i个元素的值*/}程序的运行情况是:pleaseinputnumbers:12345↙a[0]=1a[1]=2a[2]=3a[3]=4a[4]=5以下数组的定义或引用是否合法?(1)voidmain(){floata;inta[5];…}(2)若有定义“charch[10];”,则:

ch[10]ch(2)ch[2.5]

ch[2.5+2.5]ch[10-10]定义非法,同一个函数中不允许数组名与普通变量同名非法,下标超界,范围是0~9非法,只能使用“[]”非法,下标只能是整型,不能是实型非法,下标只能是整型表达式合法,相当于ch[0]初始化(定义的同时赋予初始值)普通变量,例:inta=5;一维数组,例:

chara[5]={‘h’,’e’,’l’,’l’,’o’};

a[0]~a[4]的初值依次是字符常量‘h’、’e’、’l’、’l’、’o’。数组中的每一个元素都赋了初值,属于“完全赋值”。

inta[6]={1,2,3};“不完全赋值”,根据规定,未赋初值的数组元素默认为“0”。此语句等价于“inta[6]={1,2,3,0,0,0};”

inta[]={1,2,3};

通过初始值的个数来约定数组的大小。此语句等价于“inta[3]={1,2,3};”注意:在定义时“[]”中的值不能为空,只有当有初始值进行初始化时,才可省略,利用初始值的个数作为数组的大小。6.2二维数组(1)定义形式:

类型说明符

数组名[整型常量表达式][整型常量表达式];说明:第一个方括号的值代表二维数组的“行数”,第二个方括号的值代表二维数组的“列数”。在语法格式上二维数组的要求与一维数组相同,只是比一维数组多一个下标。

例如:inta[3][4];//数组a最多可以存放3行4列共12个整型数据。(2)数组元素的引用方式:

数组名[下标][下标]

例:a[0][0],a[0][1],a[0][2],a[0][3]a[1][0],a[1][1],a[1][2],a[1][3]a[2][0],a[2][1],a[2][2],a[2][3]行与列的下标都是从0开始!!疑问:一维数组是从第0个元素开始连续存放,二维数组如何存放?计算机内存没有什么所谓的“行”与“列”,都是以字节为单位的连续空间,二维数组在内存存放时,采用“逐行存放”,行是“从上到下”,每一行是“从左至右”。如例中数组a[3][4],存放顺序是:a[0][0]->a[0][1]->a[0][2]->a[0][3]->a[1][0]->…->a[2][2]->a[2][3]二维数组元素引用举例:例:二维数组中各元素的输入输出。#include<stdio.h>voidmain(){inti,j,a[3][4];//定义二维整型数组a,3行4列printf(“pleaseinputnumbers:\n”);for(i=0;i<3;i++)//变量i控制行的变化{for(j=0;j<4;j++)//变量j控制列的变化scanf(“%d”,&a[i][j]);//循环体,为数组每个元素输入值}for(i=0;i<3;i++){for(j=0;j<4;j++)printf(“a[%d][%d]=%-4d”,i,j,a[i][j]);//循环体,输出数组每个元素printf(“\n”);}}

程序的运行情况是:pleaseinputnumbers:123456789101112↙a[0][0]=1a[0][1]=2a[0][2]=3a[0][3]=4a[1][0]=5a[1][1]=6a[1][2]=7a[1][3]=8a[2][0]=9a[2][1]=10a[2][2]=11a[2][3]=12二维数组初始化举例说明:(1)inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};(2)inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};(3)inta[3][4]={{1,2},{5}};说明:此例属于“不完全赋值”,未给出初值的元素默认为0。相当于:inta[3][4]={{1,2,0,0},{5,0,0,0},{0,0,0,0}};(4)inta[3][4]={1,2,5};相当于:inta[3][4]={{1,2,5,0},{0,0,0,0},{0,0,0,0}};(5)inta[][4]={1,2,3,4,5,6,7,8,9,10,11,12};说明:二维数组也可以通过初始值的个数来约定数组和“行数”。特别注意,只能省略“行数”,不能省略“列数”。原因在于二维数组是按行进行存放的,省略列数,就无法控制何时转入下一行。例中的初始化形式等价于:inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

(6)inta[][4]={1,2,3,4,5,6};说明:此种情况属于不完全赋值的情况,等价于:inta[2][4]={1,2,3,4,5,6,0,0};或inta[2][4]={{1,2,3,4},{5,6,0,0}};

6.3字符串及其操作6.3.1字符串与字符数组

C/C++语言规定字符串存放内存时,除了要将其中的每个字符存入内存外,还要在最后加一个‘\0’字符存入内存,‘\0’字符是字符串“结束标志”,它的ASCII为0。计算机在对字符串进行操作时,也是根据这个“结束标志”来判断字符串是否结束。

因此,在定义用于存放字符串的字符数组时,数组的大小应该是:“字符串的长度+1”,所谓字符串的长度是指字符串中所包含的字符总数,所谓“+1”就是给“结束标志”所保留的。一维数组存放“一串字符”或“字符串”(1)chara[4]={‘a’,’b’,’c’,’d’};说明:定义了一个一维字符数组a,数组的大小是4,最多可以存放4个字符。从初始化的结果可知,数组a存放了4个字符‘a’、’b’、’c’、’d’,而不能说数组a存放了一个字符串“abcd”,因为没有‘\0’。注意只有字符串常量才能使用双引号。

(2)chara[5]={‘a’,’b’,’c’,’d’,’\0’};说明:有字符串结束标志’\0’,可以说数组a中存放了一个字符串“abcd”。

(3)chara[5]={“abcd”};说明:大括号中没有出现’\0’,但出现了双引号,“双引号”是字符串常量的标志。表示用一个字符串常量对该数组进行初始化赋值。需要注意的是数组的大小要为结束标志’\0’保留一位。

(4)chara[5]=”abcd”;说明:此种形式与情况3)等价,省去了一对花括号,也是合法的。

(5)chara[]=”abcd”;说明:初始化赋值时,可以由初始值来约定数组的大小,例如此例中用一个字符串常量”abcd”给数组赋初值,因此数组的大小为5(留有1位放’\0’)。

(6)chara[]={‘a’,’b’,’c’,’d’,};说明:注意与(5)的对比,此时利用初始值来约定数组的大小,大小为4。二维数组存放多个字符串例如:chars[3][10]={"456","ab","M"};

表示二维数组s可以存放三个字符串,每个串的长度最大为9,留有一位放置结束符’\0’。例中初始化后的结果是:第1个串:s[0][0]的值为’4’,s[0][1]的值为’5’,s[0][2]的值为’6’,s[0][3]的值为’\0’;第2个串:s[1][0]的值为’a’,s[1][1]的值为’b’,s[1][2]的值为‘\0’;第3个串:s[2][0]的值为’M’,s[2][1]的值为‘\0’。

二维数组可用于存放多个字符串,数组的“行数”代表存放多少个字符串;数组的“列数”代表每个字符串的长度+1。注意“列数”应该是所有需要存放的字符串中最长的一个串的长度+1。6.3.2-(1)字符串的输出(printf函数和puts函数)printf()函数例

printf()函数使用%c控制格式输出字符串。#include<stdio.h>voidmain(){inti;charstr[6]={‘w’,‘o’,‘r’,‘l’,‘d’,‘\0’};//初始化,存放一字符串“world”for(i=0;i<6;i++)printf(“%c”,str[i]);//利用循环语句逐个输出字符串中的字符}程序的运行情况:注意:字符‘\0’不显示在屏幕上!例

printf()函数使用%s控制格式输出字符串。#include<stdio.h>voidmain(){chartr1[5]={‘w’,’o’,’r’,’l’,’d’};//初始化,存放一组字符,没有结束标志’\0’charr2[6]={‘w’,’o’,’r’,’l’,’d’,’\0’};//初始化,存放一字符串“world”charstr3[]=”world”;//初始化,存放一字符串“world”printf(“str1:%s\n”,str1);//输出字符数组str1,输出内容书写数组名str1printf(“str2:%s\n”,str2);//输出字符数组str2,输出内容书写数组名str2printf(“str3:%s\n”,str3);//输出字符数组str3,输出内容书写数组名str3}程序的运行情况:

puts()函数

puts()函数也可实现输出字符串,并且自动将字符串的结束标’\0’转换成回车换行符。例

使用puts()函数输出字符串。#include<stdio.h>voidmain(){charstr1[5]={‘w’,’o’,’r’,’l’,’d’};//初始化,存放一组字符,没有结束标志’\0’

charstr2[6]={‘w’,’o’,’r’,’l’,’d’,’\0’};//初始化,存放一字符串“world”

charstr3[]=”world”;//初始化,存放一字符串“world”

puts(str1);//输出字符数组str1,输出内容书写数组名str1puts(str2);//输出字符数组str2,输出内容书写数组名str2puts(str3);//输出字符数组str3,输出内容书写数组名str3}程序的运行情况:(2)字符串的输入(scanf函数和gets函数)scanf函数例

scanf()函数使用%c控制格式输入字符串。#include<stdio.h>voidmain(){inti;charstr[6];for(i=0;i<5;i++)scanf(“%c”,&str[i]);//利用循环语句逐个输入字符串中的字符str[5]=’\0’;//数组最后一位放置结束标志puts(str);//利用puts函数输出字符串}

程序的运行情况:world↙world例

scanf()函数使用%s控制格式输入字符串。#include<stdio.h>voidmain(){charstr1[7];charstr2[7];printf(“inputstr1:”);//提示语scanf(“%s”,str1);//数组名str1即是数组的首地址,无需取地址符’&’printf(“inputstr2:”);scanf(“%s”,str2);//数组名str2即是数组的首地址,无需取地址符’&’printf(“str1:%s\n”,str1);//利用printf函数输出字符串str1printf(“str2:%s\n”,str2);//利用printf函数输出字符串str2}

程序的运行情况:inputstr1:good!↙inputstr2:good!↙

str1:good!str2:good为何str2的输出结果没有“!”原因:scanf函数利用s%格式控制输入字符串时,当键入的是“空格”、“Tab键”或“回车键”时,系统默认输入结束,不会将其后的字符保存到字符数组中去。gets()函数gets()函数也可以实现输入字符串到字符数组中,当遇到“回车键”时,系统默认用户输入结束。

使用gets()函数输入字符串。#include<stdio.h>voidmain(){charstr1[7];charstr2[7];printf(“inputstr1:”);//提示语gets(str1);//输入字符串存放于数组str1,数组名str1即是数组的首地址printf(“inputstr2:”);gets(str2);//输入字符串存放于数组str2,数组名str2即是数组的首地址printf(“str1:%s\n”,str1);//利用printf函数输出字符串str1printf(“str2:%s\n”,str2);//利用printf函数输出字符串str2}

程序的运行情况:inputstr1:good!↙

inputstr2:good!↙

str1:good!str2:good!字符串str2为何有“!”原因:使用gets函数实现字符串的输入,当输入“回车键”时才认为输入结束!6.3.3字符串处理函数(使用前只要包含对应的头文件

string.h)测字符串长度函数——strlen(字符数组)

功能:计算指定字符串的实际长度(不含字符串结束标志’\0’),并返回字符串的长度。例

字符串长度函数strlen()函数的使用。#include<stdio.h>#include<string.h>//包含相应的头文件voidmain(){

intl1,l2;

charstr1[]="Helloworld!";//用字符串初始化字符数组str1

charstr2[]="Helloworld\0!";//用字符串初始化字符数组str2l1=strlen(str1);//使用strlen()函数计算串str1的长度

printf("Thelenthofthestr1is%d\n",l1);l2=strlen(str2);//使用strlen()函数计算串str2的长度

printf("Thelenthofthestr2is%d\n",l2);}

程序的运行结果:Thelenthofthestr1is12 Thelenthofthestr2is11字符串连接函数——strcat(字符数组1,字符数组2)功能:将字符数组2中存放的字符串连接到字符数组1中存放的字符串尾部,同时删去字符串1的结束标志“\0”,组成新的字符串,存入字符数组1中,该函数返回值是字符串1的首地址。注意:字符数组1的大小要足够大。例:

字符串连接函数使用。#include<stdio.h>#include<string.h>voidmain(){charstr1[12]="Hello";charstr2[7]=”world!”;

strcat(str1,str2);puts(str1);}程序运行结果:Helloworld!字符串比较函数——strcmp(字符数组1,字符数组2)功能:按照从左至右的顺序依次比较字符数组1和字符数组2对应位置字符的ASCII码值,并返回比较结果,比较结果对应的返回值如下:

字符串1=字符串2,返回0

字符串1>字符串2,返回大于0的数

字符串1<字符串2,返回小于0的数例:

字符串比较函数使用。#include<stdio.h>#include<string.h>voidmain(){intn;charstr1[6],str2[6];printf("inputastr1:");gets(str1);//输入字符串1printf("inputastr2:");gets(str2);//输入字符串2n=strcmp(str1,str2);//比较两个串if(n==0)printf("str1=str2\n");if(n>0)printf("str1>str2\n");if(n<0)printf("str1<str2\n");}程序运行结果:inputastr1:jim↙inputastr2:anna↙str1>str2字符串复制函数——strcpy(字符数组1,字符数组2)功能:把字符数组2中的字符复制到字符数组1中,结束标志也一同复制进去。注意,数组1的大小应该能放下数组2中的字符串,否则可能发生系统内存被覆盖的危险。另外,如果数组1原来存放有字符串,复制操作后原有的字符串将被覆盖。

例:

字符串复制函数使用。#include<stdio.h>#include<string.h>voidmain(){charstr1[13]="Helloworld!";charstr2[7]="world!";printf("beforecopystr1:%s\n",str1);strcpy(str1,str2);//把数组str2中的字符串复制给数组str1printf("aftercopystr1:%s\n",str1);}

程序运行结果:beforecopystr1:Helloworld!aftercopystr1:world!小写变大写函数——strupr(字符串)功能:将指定字符串中所有小写字母均换成大写字母。大写换小写函数—strlwr(字符串)功能:将指定字符串中所有大写字母均换成小写字母。

例:

字符串大小写转换函数使用。#include<stdio.h>#include<string.h>voidmain(){charstr1[6]="HELLO";charstr2[7]="world!";printf("beforetransformstr1:%s\n",str1);printf(“aftertransformstr1:%s\n”,strlwr(str1));printf("beforetransformstr2:%s\n",str2);printf(“aftertransformstr2:%s\n”,strupr(str2));}

程序运行结果:6.4应用举例例:输入10个整数,找出其中的最大值。

#include<stdio.h>voidmain(){inti,max,a[10];printf(“input10numbers:”);for(i=0;i<10;i++)scanf(“%d”,&a[i]);//利用循环语句输入10个数max=a[0];//假设数组第一个数最大,赋值给变量maxfor(i=1;i<10;i++)//利用for循环,让变量max与数组其余9个元素逐个比较{if(max<a[i])max=a[i];//如果当前的数比max大,则赋值给max}printf("max=%d",max);}

运行结果:input10numbers:9876543210↙max=9例:

利用冒泡排序法将N个数进行从小到大的升序排序,N的数量有用户指定。冒泡法的基本思想是:(1) 将N个数输入到一个数组a中;(2) 第0趟:从a[0]到a[N-1],将相邻的两个数两两进行比较。如果前一个数比后一个数大,则两个数进行交换;否则,保持原来的顺序。比较结束后最大数放置在数组的最后,即a[N-1]。最大的数如同“最重的气泡”往后沉;(3) 第1趟:重复算法的第(2)步,将a[0]到a[N-2]各数依次两两进行比较,其中最大的数放置到a[N-2]中,“次重的气泡”往后沉;第2趟:再将a[0]到a[N-3]各数进行两两比较,其中最大的数调到a[N-3]中;……最后第N-2趟:将a[0]到a[1]中较大的数调到a[1]中。综上,可以利用循环嵌套来实现,外层循环控制比较的趟数(总共N-1趟,即从第0趟开始到第N-2趟),内层循环控制每一趟进行数两两比较的次数,次数=(N-1)-趟数。假设N=5时,将进行N-1=4趟可以完成对数组a中的5个数从小到大的排序工作。见表6-1所示。从表中可以发现当进行完第1趟比较工作之后,顺序已经排列完成,实际上没有必要再进行后面的比较了。因此我们可以设置一个“标志变量”,赋予初值,当某一趟中并没有进行交换操作,表示顺序已经排好,则结束循环,提前结束整个排序工作。

a[0]a[1]a[2]a[3]a[4]初始值765810第0趟657810第1趟567810第2趟567810第3趟567810#defineM20#include<stdio.h>voidmain(){inti,j,t,a[M],num;intexchange=0;//标志变量,初值为0printf(“inputnum<%d:”,M);//提示语scanf("%d",&num);//让用户指定数的个数,个数在宏定义M之内printf(“inputnumber:”);for(i=0;i<num;i++)scanf("%d",&a[i]);//允许用户输入num个数for(i=0;i<num-1;i++)//外层循环控制“趟数”{exchange=0;//标志变量恢复初始状态for(j=0;j<num-1-i;j++)//内层循环控制每一趟中“比较的次数”,次数与趟数之间有联系{if(a[j]>a[j+1])//要求升序排列,如果前面的数大于后面的数,则两数交换位置{t=a[j];a[j]=a[j+1];a[j+1]=t;//两数的交换必须通过第三个变量进行

exchange=1;//发生过交换,标志变量exchange=1}}

if(!exchange)//如果没有发生交换,exchange的值应为0,“!exchange”为“真”break;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论