版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章数组、字符串与动态内存分配6.1数组概念6.2一维数组6.3多维数组6.4字符数组6.5指针数组与main函数的参数6.6内存的动态分配与释放《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第1页。6.1数组概念数组:一组相同数据类型的元素按一定顺序线性排列。数组的特点:(1)数组是相同数据类型的元素的集合。(2)数组中的各元素是有先后顺序的。它们在内存中按照这个顺序连续存放在一起。(3)每个数组元素用整个数组的名字和它自己在数组中的位置表达,此位置被叫做下标或索引。
a[0]a[1]a[2]
a[3]a[4]a[5]
2334-89
-901250《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第2页。6.1数组概念数组特点:(1)数组是相同数据类型的元素的集合。(2)数组中的各元素是有先后顺序的。它们在内存中按照这个顺序连续存放在一起。(3)每个数组元素用整个数组的名字和它自己在数组中的位置表达(此位置被叫做下标或索引)。
例如,一个包含6个整型元素的数组a,定义为:
inta[6];在内存中的顺序存储结构如下:
a[0]a[1]a[2]
a[3]a[4]a[5]
2334-89
-901250数组下标数组名下标变量《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第3页。6.1数组概念使用数组的好处:便于组织循环数组按维数分为:一维数组多维数组//求100个数据的和:inta[100]={1,2,3,4,…100}s=0;for(i=0;i<=99
;i++)s=s+a[i];《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第4页。6.2一维数组6.1.1一维数组的声明6.2.1一维数组的初始化6.2.3一维数组元素的表示方法6.2.4用指针访问一维数组6.2.5函数参数为访问一维数组的指针6.2.6一维数组综合程序设计举例《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第5页。6.1.1一维数组的声明声明数组:指定数组名称、数组所包含的元素的数据类型和元素的个数。声明一维数组的语法格式:
数据类型数组名[常量表达式];常量表达式:数组元素的个数(length)符号常量或常量名组成的表达式,不能是变量[]是数组的标志。声明数组意味着给数组分配一组连续的存储空间,空间的大小:length*sizeof(dataType)
。例如,inta[10];
声明了含有10个元素的整型数组,分配10个元素的内存空间(每个元素占4个字节)。sizeof(a)=40
《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第6页。
inta[10];10个元素:a[0],a[1],a[2],…,a[9]每个元素的数据类型a[0]a[1]a[2]a[3]…a[7]a[8]a[9]6.1.1一维数组的声明空间的大小(字节数):10*4=40Bytes数组的元素个数(长度):1010*sizeof(int)=40sizeof(a)=40《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第7页。6.1.1一维数组的声明声明数组: 数据类型数组名[常量表达式];例如:intcount=10;charcArray[count];//错误,元素个数count是变量constintcount=10;charcArray[count];//正确,元素个数是常量unsignedcharbArray[count+1];//正确,元素个数是常量#definelength100longlArray[legnth];//正确,元素个数是常量《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第8页。6.2.1一维数组的初始化数组的初始化:在声明数组的同时,给数组的每一个元素指定一个初始值。语法格式:
数据类型数组名[常量表达式]={初始化列表};或
数据类型数组名[]={初始化列表};初始化列表:用逗号分隔的一组常量值。例如:inta[5]={1,2,3,4,5};即a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第9页。6.2.1一维数组的初始化例:inta[5]={1,2,3,4,5};即a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5例:计算初始化列表中值的个数来确定数组元素的个数。inta[]={1,2,3,4,5};例:初始化列表中的数据个数小于数组元素的个数,则编译器给剩下的数组元素的初值0。inta[5]={1,2};即a[0]=1,a[1]=2,a[2]=0,a[3]=0,a[4]=0。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第10页。6.2.1一维数组的初始化例如:charc[10]={'0','1','2'};即c[0]=48,c[1]=49,c[2]=50,c[3]=c[4]=…=c[9]=0。或c[0]=‘0’,c[1]=‘1’,c[2]=‘2’,c[3]=c[4]=…=c[9]=‘\0’数组元素的赋值也可通过赋值语句进行:例如:shorts[5];s[0]=1;s[1]=2;s[2]=3;s[3]=s[2]-s[1];s[4]=s[3]-s[1]-2;《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第11页。6.2.3一维数组元素的表示方法一维数组元素的使用:下标变量表示法。语法格式为:数组名[下标]下标的取值范围:0~length-1。访问数组元素时,下标不能越界。下标是整型或者可以转化成整型的量使用数组元素就像使用简单变量一样例如:inta[100];for(i=0;i<=100;i++)a[i]=i;99《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第12页。6.2.3一维数组元素的表示方法避免下标越界的方法:用符号名如length表示数组元素的个数,用length-1作为数组下标的下界。例如:#define
length100inta[length];for(i=0;i<=length-1
;i++)
a[i]=i;
对数组从尾向头遍历元素for(i=length-1;i>=0;i--)
a[i]=i;《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第13页。例6-1从键盘输入一组数放入数组中,逆序输出数组的所有元素以及元素之和。#include<stdio.h>#definelength5voidmain(){ intarray[length]; inti,total=0;for(i=0;i<=length-1;i++)scanf("%d",&array[i]);for(i=0;i<=length-1;i++)//addeachelement'svaluetototaltotal+=array[i]; printf("Reversedarrayelements:"); for(i=length-1;i>=0;i--)
printf("%-4d",array[i]);printf("\nTotalofarrayelements:%d\n",total);}1020308034Reversedarrayelements:3480302010Totalofarrayelements:184《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第14页。6.2.4用指针访问一维数组一个含有n个元素的数组,在内存将分配n个连续的存储单元,每一个数组元素占用的内存空间大小一样,且与数组的数据类型相关。数组名:代表整个数组的首址(数组的第一个元素的地址)每一个数组元素有一个存储地址(数组元素的指针)。定义一个指针变量指向数组元素(存放数组元素的地址)通过指针变量间接访问数组元素《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第15页。inta[10]={1,3,5,7,9,11,13,15,17,19};
int*p;p=a;//指向数组的首址等价于p=&a[0]等价于int*p=a;
或int*p=&a[0];a[0]a[1]a[9]a[2]a[3]a[4]a[5]a[6]a[7]a[8]p=&a[0]1.指向一维数组元素的指针变量《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第16页。6.2.4用指针访问一维数组定义一维数组元素的指针变量,语法格式:类型*变量名;类型:一维数组的数据类型。*:变量名是指针类型。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第17页。2.对指针进行加减运算
在指针变量指向数组元素时,允许对指针进行如下的加减运算(1)p指向数组元素a[i]p+1指向后一元素a[i+1]p-1指向前一个元素a[i-1]如,a的首址2000,若p=&a[1]则p的值为2004,则p+1的值为2008,则p-1的值为2000。P=&a[i];floata[10],*p;
《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第18页。2.对指针进行加减运算(2)如果p的初值为&a[0],则p+i或a+i:a[i]的地址p+i或a+i:指向a[i]元素
☆通过指针间接存取a[i]的形式:
*(p+i)、*(a+i)和p[i]floata[10],*p;
《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第19页。2.对指针进行加减运算(3)对p指针变量进行加减赋值运算:p=p+i
:p指向当前数组元素往后的第i个元素。p=p-i
:p指向当前数组元素往前的第i个元素。p++或++p:p指向当前数组元素的后一个元素。p—或--p:p指向当前数组元素的前一个元素。数组名是常量指针,它始终指向数组的首址。如:
a=a+1;是错误的。floata[10],*p;
《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第20页。2.对指针进行加减运算(3)
两个指针相减,只有p1和p2都指向同一数组中的元素时才有意义
p1-p2:p2与p1之间有多少个元素例如,floata[10],*p=a;while(p-a<10){//a[9]与a[0]之间相差9个元素printf(“%f“,*p);p++};《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第21页。
例6-2通过指针遍历数组所有元素。#definelength5voidmain(){ inta[length]={1,2,3,4,5};inti,*p=a;
//下标变量法遍历数组元素
for(i=0;i<=length-1;i++)printf("%-4d",a[i]); printf("\n");
//数组名常量指针法遍历数组元素
for(i=0;i<=length-1;i++)
printf("%-4d",*(a+i)); printf("\n");
12345123451234512345123453.通过指针引用数组元素《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第22页。
//变量指针法遍历数组元素,变量指针的值不变p=a
for(i=0;i<=length-1;i++)
printf("%-4d",*(p+i));printf("\n");//变量指针法遍历数组元素,变量指针类似于数组名使用,变量指针的值不变
for(i=0;i<=length-1;i++)
printf("%-4d",p[i]);printf("\n");
//变量指针法遍历数组元素,变量指针的值在变,不断指向下一个元素
for(i=0;i<=length-1;i++){
printf("%-4d",*(p++)); } printf("\n");}1234512345123451234512345《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第23页。6.2.5函数参数为访问一维数组的指针通过函数访问一个通用的一维数组。函数定义中,形参为:f(type*p,intn)或f(typep[],intn)f(typep[len],intn)函数调用:f(a,length)其中typea[length];f1(int
p[],intn)与f2(int
p[2],intn)的区别inta[2],b[3];f1(a,2)f1(b,3)f2(a,2)f2(b,3)错误《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第24页。例6-3完成给一维数组各元素赋值为对应元素的下标值,将此功能定义为函数fvoid
f(int*a,intn){
//或f(inta[],intn)
inti;for(i=0;i<n;i++)
a[i]=i;printf(“%2d”,a[i]);printf("\n");}voidmain(){inta[10],b[5];f(a,10);f(b,5);}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第25页。6.2.6一维数组综合程序设计举例★数组的常用算法:排序插入修改删除查询《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第26页。例6-4用冒泡排序法对数组进行增序
(从小到大)的排序。排序的规则有两种:一种是增序(从小到大);另一种是降序(从大到小)冒泡排序法:模拟水中气泡的排放规则,使重量“较轻”(值较小)的气泡浮到上面,重量“较重”(值较大)的气泡沉到下面。
对每一趟排序,从第1个元素开始,比较相邻元素的大小,按照规则对调两者的位置,最终确定一个最大(或最小)的气泡的位置。
例如:对6个数进行冒泡排序法的过程:《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第27页。985420895420859420854920854290854209大数沉淀,小数起泡a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<=4;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}第1趟排序《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第28页。854209584209548209542809542089a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<=3;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}第2趟排序《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第29页。542089452089425089420589a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<=2;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}第3趟排序420589《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第30页。420589240589204589a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<=1;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}第4趟排序《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第31页。204589024589a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<=0;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}第5趟排序《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第32页。for(i=0;i<=4;i++)if(a[i]>a[i+1]){……}for(i=0;i<=3;i++)if(a[i]>a[i+1]){……}for(i=0;i<=0;i++)if(a[i]>a[i+1]){……}……for(i=0;i<=6-pass-1;i++)if(a[i]>a[i+1]){……}for(pass=1;pass<=5;j++)
pass:趟数从1到5
size个元素时pass:趟数从1到size-1i从0到size-pass-16个元素时pass=1pass=2pass=5《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第33页。voidbubblesort(intvalues[],intsize){intpass,j,temp;for(pass=1;pass<=size-1;pass++){ for(j=0;j<=size-1-pass;j++) if(values[j]>values[j+1]){ temp=values[j]; values[j]=values[j+1]; values[j+1]=temp; }} }将冒泡排序法定义为一函数《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第34页。将冒泡排序法定义为一函数bubbleSort(intvalues[],intn)等同于bubbleSort(int*values,intn)《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第35页。将打印一维数组功能定义为一函数。
voidprint(intvalues[],intsize){ inti; for(i=0;i<size;i++) printf("%4",values[i]); printf("\n");}voidmain(){ intscore1[]={10,3,56,89,80,60}; intscore2[]={78,100,45,12,78,90,3,5}; bubblesort(score1,6); print(score1,6); bubblesort(score2,8); print(score2,8);}31056608089351245787880100形参inta[]与inta[10]区别?《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第36页。例6-5在有序的数组中,用折半查找法查找一个特定的值。在有序的数组中,二分查找法是一种比较快捷的查找方法。折半查找法:先将整个数组作为查找区间,用给定的值与查找区间的中间元素的值相比较,若相等,则查找成功;若不等,则缩小范围,判断该值落在区间的前一部分还是后一部分,再将其所在的部分作为新的查找区间,继续上述过程,一直到找到该值或区间长度小于0表明查找不成功为止。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第37页。例如:用折半查找法查找key=80元素31056608085a[0]a[1]a[2]a[3]a[4]a[5]low=3mid=(low+hight)/2hight=5a[mid]<80low=0hight=5mid=4a[mid]=80仅比较2次即找到关键字。折半查找法是快速查找法。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第38页。inta[size],查找是否含有关键字key的元素,折半查找法的算法描述过程:1.设置查找的最初区间[low,high],low=0,high=size-1,mid=(low+high)/2;found是否找到key的标志,初值0。2.判断a[mid]和key之间的关系:若key=a[mid],则成功找到,置found=1,查找结束。若key<a[mid],设定下一查找范围是左半区间[low,mid-1]。若key>a[mid],设定查找范围是右半区间[mid+1,high]。
重复步骤2条件:(low<=high)且found==03.循环结束时,若found==1则找到,否则找不到key。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第39页。//函数返回找到的key的下标位置,返回-1则找不到intbinarySearch(intarray[],intkey,intsize){intlow,high,found=0,mid;intindex;low=0;high=size-1;while((found==0)&&(low<=high)){ mid=(low+high)/2; if(key==array[mid]){ found=1;index=mid; } elseif(key>array[mid]) low=mid+1; elseif(key<array[mid]) high=mid-1; }if(found)returnindex;elsereturn-1;}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第40页。voidmain(){ intscore1[]={3,10,56,60,80,85}; intloc,key; printf("输入要查找的关键字=?"); scanf("%d",&key); loc=binarySearch(score1,key,6); if(loc==-1) printf("找不到!\n"); elseprintf("成功找到!%d的下标位置为%d\n",key,loc); }输入要查找的关键字=?80成功找到!80的下标位置为4《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第41页。6.3多维数组带有一个下标的数组叫做一维数组。
a[i]带有两个下标的数组叫做二维数组。
a[i][j]带有两个以上的下标的数组叫做多维数组
a[i][j][k]《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第42页。6.3多维数组6.3.1二维数组的声明 6.3.2二维数组的初始化 6.3.3二维数组元素的表示方法 6.3.4声明二级指针 6.3.5用指针访问二维数组 6.3.6函数参数为访问二维数组的指针 6.3.7二维数组综合程序设计举例 《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第43页。6.3.1二维数组的声明二维数组常用于存放矩阵,第一维和第二维分别对应于矩阵的行和列。二维数组声明的格式:
类型数组名[常量表达式1][常量表达式2];常量表达式1:第一维下标的长度常量表达式2:第二维下标的长度类型:数组元素的数据类型《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第44页。6.3.1二维数组的声明例如:inta[2][3];将创建2行*3列的二维数组。各元素的下标变量:在C语言中,二维数组是按行排列的。inta[2][3],每个元素占4个Bytes,整个数组占24个字节的存储空间。二维数组看作是一个特殊的一维数组:一维数组中每一个元素又是一个一维数组。a由a[0]、a[1]
组成《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第45页。6.3.2二维数组的初始化声明二维数组的初始化形式:(1)分行给二维数组赋初值。例如:intb[3][2]={{1,2},{2,3},{3,4}};(2)将所有初值写在一行中。例如:intb[3][2]={1,2,3,4,5,6};(3)只给部分元素赋初值。当{}中值的个数少于元素个数时,只给前面部分元素赋值。后面的元素初值缺省为0。例如:intb[3][2]={{1},{2},{3}};
相当于intb[3][2]={{1,0},{2,0},{3,0}};《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第46页。6.3.2二维数组的初始化(4)声明数组时,第1维的下标的长度可以不确定,但第2维的下标的长度一定要确定。例如:intb[][4]={1,2,3,4,5,6,7,8};相当于intb[2][4]={1,2,3,4,5,6,7,8};《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第47页。6.3.3二维数组元素的表示方法二维数组的每个元素,双下标的表示格式:
数组名[下标1][下标2]下标1、下标2为非负的整型表达式。下标不能越界例如:inta[3][4];表示元素:a[2][3]正确i=1,j=1,a[i+1][j*3]a[3][4]错误
a[i+2][j*3]a[i+1][j*4]《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第48页。6.3.3二维数组元素的表示方法二维数组的遍历访问,需要通过二重循环逐行(或逐列)进行。例如:inta[len1][len2],按行遍历:按列遍历:for(row=0;row<len1;row++)for(col=0;col<len2;col++)a[row][col]
for(col=0;col<len2;col++)for(row=0;row<len1;row++)a[row][col]
《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第49页。例6-6有一个矩阵,要打印出其每一列的最大值位置。解题思路:二维数组存放矩阵,对二维数组按列的次序扫描:对某一列col,用变量k存放这一列的最大值的行号.
开始时,假设第col列的第0行元素为最大值,k=0.该列的其它元素a[row][col]与a[k][col]值比较若当前元素大于目前最大值,则k=此元素的行号。for(col=0;col<len2;col++){k=0;for(row=0;row<len1;row++)if(a[row][col]>a[k][col])k=row;printf("第%d列第%d行的元素为最大值。\n",col,k);} 《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第50页。例6-6有一个矩阵,要打印出其每一列的最大值位置。定义函数,用于二维数组的数据输入:
voidinput(inta[][len2])定义函数,用于二维数组输出:
voidprint(inta[][len2])形数inta[][len2]与inta[len1][len2]区别?inta[][len2]比inta[len1][len2]适用的二维数组范围更广。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第51页。#definelen13#definelen24voidinput(inta[][len2]);voidprint(inta[][len2]);voidmain(){ inta[len1][len2]; introw,col,k; //二维数组数据输入
input(a); //二维数组输出
printf("\n您已经输入的二维数组:\n"); print(a);//输出每一列的最大值
for(col=0;col<len2;col++){ k=0; for(row=0;row<len1;row++) if(a[row][col]>a[k][col])k=row; printf("第%d列第%d行的元素为最大值。\n",col,k); } }《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第52页。voidinput(inta[][len2]){ introw,col; for(row=0;row<len1;row++){ printf("输入第%d行:",row); for(col=0;col<len2;col++) scanf("%d",&a[row][col]); }}voidprint(inta[][len2]){ introw,col; //二维数组输出
for(row=0;row<len1;row++){ for(col=0;col<len2;col++) printf("%5d",a[row][col]); printf("\n"); }}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第53页。例6-7实现N×N矩阵的转置。解题思路:矩阵的转置是指矩阵的上下三角元素以对角线为中轴线对称互换:即原来的i行j列元素在转置后称为j行i列元素。定义二维数组a[N][N]存放矩阵。for(i=0;i<N;i++)for(j=i+1;j<N;j++)
a[i][j]a[j][i];《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第54页。例6-7实现N×N矩阵的转置。随机生成N*N个数据放入二维数组:voidrandoms(inta[][N]){ introw,col;srand((unsigned)time(NULL)); for(row=0;row<N;row++){ for(col=0;col<N;col++) a[row][col]=rand(); }}rand();生成0到32767之间的随机数#include<stdlib.h>#include<time.h>srand((unsigned)time(NULL));《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第55页。#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN4voidmain(){ inta[N][N]; inti,j,t; voidrandoms(inta[][N]);//函数原型
voidprint(inta[][N]);//函数原型
randoms(a); printf("二维数组转置前:\n");
print(a); for(i=0;i<N;i++){//二维数组转置
for(j=i+1;j<N;j++){ t=a[i][j]; a[i][j]=a[j][i]; a[j][i]=t; } } printf("\n二维数组转置后:\n");
print(a);}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第56页。1.声明二级指针
:
type**变量名例如:inta=8;int*p=&a;//一级指针int**q=&p;6.3.4声明二级指针《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第57页。6.3.4声明二级指针2.用二级指针访问对象变量
*q代表p**q代表a**q=**q+1//a=a+1《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第58页。6.3.5用指针访问二维数组1.二维数组元素的地址二维数组可看做是一个一维数组:此一维数组中每一个元素又是一个一维数组。例如:inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};由3行组成:a[0]、a[1]和a[2]
《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第59页。inta[3][4]:由3个一维数组a[0]、a[1]和a[2]组成。a[0]代表第0行,存放第0行的首址二维数组各指针之间的关系:a:是二级指针,指向二维数组的首址,其值为&a[0]或&a[0][0]*a或a[0]:代表第0行,其值为&a[0][0];**a:代表a[0][0]。
6.3.5用指针访问二维数组《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第60页。二维数组各指针之间的关系:(2)a+i:指向第i行(存放第i行的地址),或称行指针,其值等于&a[i][0];*(a+i)或a[i]代表第i行,其值等于&a[i][0],即第i行第0个元素的地址;*(a+i)+j或a[i]+j:指向第i行第j个元素,其值为&a[i][j];*(*(a+i)+j):代表a[i][j]。6.3.5用指针访问二维数组《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第61页。二维数组各指针之间的关系:
取内容运算符*,其结合性为自右至左:
**a相当于*(*a)。
**a是一个二级指针:a存放a[0]的地址,a[0]存放的是a[0][0]的地址,通过a间接地访问a[0][0]的形式是**a6.3.5用指针访问二维数组《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第62页。例6-8输出二维数组的各指针值。voidmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};inti;
//请观察二维数组的各指针的值及其之间的关系printf("a=%d,*a=%d,a[0]=%d,&a[0][0]=%d,a[0][0]=%d\n\n",a,*a,a[0],&a[0][0],a[0][0]);for(i=0;i<3;i++){ printf("a+%d=%d,*(a+%d)=%d,a[%d]=%d,",i,a+i,i,*(a+i),i,a[i]);printf("&a[%d][0]=%d,a[%d][0]=%d\n",i,&a[i][0],i,a[i][0]);
}}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第63页。6.3.5用指针访问二维数组2.定义指向二维数组的指针变量,格式:
类型说明符(*指针变量名)[长度];*:表示其后的变量是指针类型。园括号()不可少,如少括号则表示的指针数组长度:等于二维数组声明时的第二维下标长度。类型说明符:是二维数组的数据类型。定义的指针变量名:是指向二维数组的行指针。例如:定义了一个指向第二维长度为4的二维数组指针变量p:inta[3][4];int(*p)[4];《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第64页。6.3.5用指针访问二维数组例如:定义了一个指向第二维长度为4的二维数组指针变量p:int(*p)[4];intb[4];p=&b;
b
pb[0]b[1]b[3]b[2]《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第65页。例如:inta[3][4];int(*p)[4];p=a;//指向第0行p+1://指向第1行p+i;//指向第i行4.通过二维数组的行指针变量,间接访问数组元素a[i][j]的一般形式:
*(*(p+i)+j)或p[i][j]6.3.5用指针访问二维数组《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第66页。例6-9通过二维数组的行指针变量,输出二维数组元素。voidmain(){ inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; inti,j;int(*p)[4]; //定义二维数组的行指针变量
p=a; for(i=0;i<3;i++){//i表示行号
for(j=0;j<4;j++) printf("%3d",*(*(p+i)+j));printf("\n"); }}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第67页。例6-10将二维数组线性化成一维数组,通过一维数组的指针变量,输出二维数组元素。解题思路:定义一维数组的指针变量
int*p;inta[m][n];
p初值为二维数组的首地址,p=a;
数组元素a[i][j],通过指针变量p的存取形式为:
*(p+i*n+j)其中n是二维数组的第二维的长度。a[i][j]元素的前面有多少个元素?有i行个元素,第i行上有j个元素《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第68页。#include<stdio.h>voidmain(){ inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int(*p);//定义一维数组的指针变量
inti,j; p=a;//或p=a[0];或p=&a[0][0];
for(i=0;i<3;i++){//i表示行号
for(j=0;j<4;j++) printf("%2d",*(p+i*4+j));printf("\n"); }}123456789101112
for(p=a[0];p<a[0]+12;p++){if((p-a[0])%4==0)printf(“\n”);printf(“%4d”,*p);}也可换成《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第69页。6.3.6函数参数为访问二维数组的指针形参:f(type(*a)[colLen)
或f(typea[][colLen)实参:f(b)其中
:typeb[len1][colLen]《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第70页。例6-11:完成给二维数组各元素赋值为对应元素的下标i+j,将此功能定义为函数f。
#definecolLen4f(int(*a)[colLen],intn){
//f(inta[][colLen],intn)inti,j;for(i=0;i<n;i++)for(j=0;j<colLen;j++)a[i][j]=i+j;}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第71页。例6-11:完成给二维数组各元素赋值为对应元素的下标i+j,将此功能定义为函数f。
p(int(*a)[colLen],intn){//或p(inta[][colLen],intn)inti,j;for(i=0;i<n;i++){for(j=0;j<colLen;j++)printf("%3d",*(*(a+i)+j));printf("\n");}}voidmain(){inta[10][colLen],b[5][colLen];f(a,10);f(b,5);p(a,10);p(b,5);}《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第72页。6.3.7二维数组综合程序设计举例例6-12构造杨辉三角形。解题思路:将杨辉三角形放在二维数组yanghui中。杨辉三角形各元素的特点如下:y[i][j]=y[i-1][j-1]+y[i-1][j]当i>0,j>0,j<i=1当j=0或j=i《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第73页。//生成杨辉三角形放入二维数voidmakeYangHui(int(*yanghui)[N]){inti,j; for(i=0;i<N;i++)//外循环控制行数
for(j=0;j<=i;j++){//生成第i行数据
if(j==0||j==i) yanghui[i][j]=1; elseif(j<i) yanghui[i][j]=yanghui[i-1][j-1]+yanghui[i-1][j]; elseyanghui[i][j]=0; } }y[i][j]=y[i-1][j-1]+y[i-1][j]当i>0,j>0,j<i=1当j=0或j=iintyanghui[][N]《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第74页。#defineN6voidprintTriangle(int(*yanghui)[N]){//打印杨辉三角形
inti,j; for(i=0;i<N;i++){//外循环控制打印的行数
for(j=0;j<=i;j++)//内循环控制打印第i行
printf("%d\t",*(*(yanghui+i)+j)); printf("\n"); }}voidmain(){
intyanghui[N][N];makeYangHui(yanghui);
printTriangle(yanghui);}yanghui[i][j]《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第75页。6.4字符数组char字符型数据:用一个字节的ASCII代码存储的。C语言的基本类型中没有字符串类型字符串存放在字符型数组中的。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第76页。6.4字符数组6.4.1字符数组的定义6.4.2字符数组的初始化6.4.3字符数组元素的表示方法6.4.4字符数组的输入与输出6.4.5使用字符串函数处理字符串6.4.6通过指针引用字符串6.4.7字符串的综合程序设计举例《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第77页。6.4.1字符数组的定义用来存放字符类型的数组称为字符数组。例如:charc[10];
定义含有10个char类型的数组元素,每个元素存放一个字符。字符数组也可以是二维或多维数组。例如:二维字符数组charc[5][10];《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第78页。6.4.2字符数组的初始化声明字符数组时,允许对数组元素初始化赋值。
例如:chars[10]={'C','','p','r','o','g','r','a','m'};s的内存分配和各元素的的初值为:其中s[9]在初始化列表中没有被赋初值,则由系统自动赋缺省值0或‘\0’。转义字符‘\0’的机内编码值是0。‘\0’也是字符串的结尾标志《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第79页。6.4.2字符数组的初始化初始化时,将字符串常量赋给字符型数组。例:chars[10]="Cprogram";或
chars[]={"Cprogram"};在声明数组后,不可用赋值语句给字符数组名赋值。例:chars[10];s=“Cprogram”;//错误。char*s;s=“Cprogram”;//正确《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第80页。6.4.2字符数组的初始化定义数组时,省略数组长度,编译系统会自动根据初值个数确定数组长度。例如:chars[]={'C','','p','r','o','g','r','a','m'};s的长度为9,注意这时s没有结尾字符'\0'。例如:chars[]="Cprogram";s的长度为10,s的最后一个字节为‘\0’。用字符串方式赋值比用字符逐个赋值要多占一个字节,用于存放字符串结束标志'\0'。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第81页。6.4.2字符数组的初始化注意:字符型数组存放字符串时,最好多留一个字节存放结尾字符'\0',这对于字符串的输入和输出时用数组名作为参数是必须的。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第82页。6.4.3字符数组元素的表示方法引用字符数组的一个元素同引用一个char型的基本变量。
例6-13输出字符数组中的各个字符和内存存储的Ascii代码。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第83页。voidmain(){ inti; chars[20]="Iamastudent."; for(i=0;i<20;i++) printf("%-4c",s[i]); printf("\n"); for(i=0;i<20;i++) printf("%-4d",s[i]);}s[15]=‘\0’s[19]=0《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第84页。6.4.4字符数组的输入与输出字符数组的输入输出:三种方式:1.在printf函数和scanf函数中,使用格式符为”%c”,结合循环语句对数组逐个地输入输出每个字符。例6-14使用格式符"%c",对字符数组进行输入/输出。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第85页。6.4.4字符数组的输入与输出voidmain(){ inti=0,k; chars[100]; printf("输入:"); do{ scanf("%c",&s[i]); }while(s[i++]!='\n'); //最后一个字符s[i-1]='\n' printf("输出:"); for(k=0;k<i;k++) printf("%c",s[k]);}输入:Stringinput.输出:Stringinput.《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第86页。6.4.4字符数组的输入与输出2.在printf函数和scanf函数中,使用格式符”%s”,对字符数组一次性输入/输出字符串。printf函数:使用格式符“%s”,对应的输出数据项是一维字符数组名。例如:chars1[]="Java\nJava";printf("%s\n",s1);将输出两行“Java”。在执行函数printf("%s",s1)时,按数组名s1找到首地址,然后逐个输出数组中各个字符直到遇到字符串终止标志'\0'为止。《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第87页。6.4.4字符数组的输入与输出2.在printf函数和scanf函数中,使用格式符”%s”,对字符数组一次性输入/输出字符串。scanf函数使用格式符“%s”,输入数据项是数组名。例如:charst[20];scanf("%s",st);输入的字符串长度<=19,最后留一个字节存放`\0`。
scanf(“%s”,&st);
//error《C语言程序设计实用教程》课件第6章-数组、字符串与动态内存分配全文共143页,当前为第88页。注意:(1)scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为输入串的结束。例如:charst[20];scanf("%s",st);输入“Howareyou”
则st=“How”赋给st例如:chars1[20],s2[20],s3[20];scanf("%s%s%s",s1,s2,s3);
当输入一行“Howareyou”,则s1=“How”,s2=“are”,s3=“you”(2)scanf语句中的输入
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 年产xxx气动放大器项目可行性研究报告(创业计划)
- 年产xx硅酸盐水泥项目可行性研究报告(项目说明)
- 小学英语素养展示活动
- 高三地理第一轮复习 3-3 气象灾害(第一、二课时)
- 高考地理一轮复习课件 2.2天气与气候
- 常见地貌类型-河流地貌课件高三地理一轮复习
- 一年级下册数学教案-第六单元两位数加一位数、整十数(3)-人教新课标
- 4.1常见地貌类型-风沙地貌和海岸地貌课件高中地理人教版(2019)必修一
- 1.2 地球运动的地理意义(第2课时 公转的地理意义)课件高中地理人教版(2019)选择性必修1
- 九年级第十六章电流做功与电功率复习学案
- 2024年辅警招聘考试试题库含完整答案(各地真题)
- 设计提案范例
- 小讲课风湿科常用药物
- 湖北省崇阳县浪口温泉地热田地热资源开发利用与生态复绿方案
- 中医食疗药膳学智慧树知到期末考试答案章节答案2024年四川护理职业学院
- 沂蒙红色文化与沂蒙精神智慧树知到期末考试答案2024年
- 国开一体化平台01588《西方行政学说》章节自测(1-23)试题及答案
- 2024氢气长管拖车安全使用技术规范
- 《新疆维吾尔自治区建筑工程施工评标规则》(新建建20107号)
- 纯电动汽车结构与检修
- 保护绿水青山班会课件
评论
0/150
提交评论