版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第四章数组、指针、字符串和自定义数据类型1本章主要内容数组指针动态存储分配指针与数组指针与函数字符串2数组的概念数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。数组属于构造类型。数组3一维数组的声明与引用一维数组的声明类型说明符数组名[常量表达式];
例如:inta[10];
表示a为整型数组,有10个元素:a[0]...a[9]引用必须先声明,后使用。只能逐个引用数组元素,而不能一次引用整个数组
例如:a[0]=a[5]+a[7]-a[2*3]数组名的构成方法与一般变量名相同。数组4例一维数组的声明与引用#include<iostream>usingnamespacestd;intmain(){ int
A[10],B[10];
inti; for(i=0;i<10;i++) {
A[i]=i*2-1;
B[10-i-1]=A[i]; }数组
for(i=0;i<10;i++){
cout<<"A["<<i<<"]="<<A[i];
cout<<"B["<<i<<"]="<<B[i]<<endl; }}5一维数组的存储顺序数组元素在内存中顺次存放,它们的地址是连续的。例如:具有10个元素的数组a,在内存中的存放次序如下:数组名字是数组首元素的内存地址。数组名是一个常量,不能被赋值。a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]a数组6一维数组的初始化可以在编译阶段使数组得到初值:在声明数组时对数组元素赋以初值。
例如:staticinta[10]={0,1,2,3,4,5,6,7,8,9};可以只给一部分元素赋初值。
例如:staticinta[10]={0,1,2,3,4};在对全部数组元素赋初值时,可以不指定数组长度。
例如:staticinta[]={1,2,3,4,5}数组7#include<iostream>usingnamespacestd;intmain(){inti;staticintf[20]={1,1};//初始化第0、1个数
for(i=2;i<20;i++)f[i]=f[i-2]+f[i-1];//求第2~19个数
for(i=0;i<20;i++)//输出,每行5个数//{if(i%5==0)cout<<endl; cout.width(12);//设置输出宽度为12
cout<<f[i];}}例:用数组来处理求Fibonacci数列问题8例:用数组来处理求Fibonacci数列问题运行结果:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 67659一维数组应用举例循环从键盘读入若干组选择题答案,计算并输出每组答案的正确率,直到输入ctrl+z为止。每组连续输入5个答案,每个答案可以是'a'..'d'。数组10#include<iostream>usingnamespacestd;intmain(){
charkey[]={'a','c','b','a','d'}; charc; int ques=0,numques=5,numcorrect=0; cout<<"Enterthe"<<numques<<"questiontests:"<<endl;
while(cin.get(c)) {if(c!='\n') if(c==key[ques]) {numcorrect++; cout<<""; } else cout<<"*"; else{
cout<<"Score"<<float(numcorrect)/numques*100<<"%"; ques=0; //resetvariables numcorrect=0; cout<<endl; continue; } ques++; }return0;}1111运行结果:acbba**Score60%acbadScore100%abbda***Score40%bdcba*****Score0%1212二维数组的声明及引用数据类型标识符[常量表达式1][常量表达式2]…;例:
inta[5][3];
表示a为整型二维数组,其中第一维有5个下标(0~4),第二维有3个下标(0~2),数组的元素个数为15,可以用于存放5行3列的整型数据表格。数组13存储顺序按行存放,上例中数组a的存储顺序为:
二维数组的声明类型说明符数组名[常量表达式][常量表达式]例如:floata[3][4];a00a01a02a03a10a11a12a13a20a21a22a23a[0]——a00a01a02a03a[1]——a10a11a12a13
a[2]——a20a21a22a23a可以理解为:引用例如:b[1][2]=a[2][3]/2
下标不要越界二维数组的声明及引用数组14将所有数据写在一个{}内,按顺序赋值例如:staticinta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};分行给二维数组赋初值例如:staticinta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};可以对部分元素赋初值例如:staticinta[3][4]={{1},{0,6},{0,0,11}};二维数组的初始化数组15数组作为函数参数数组元素作实参,与单个变量一样。数组名作参数,形、实参数都应是数组名,类型要一样,传送的是数组首地址。对形参数组的改变会直接影响到实参数组。数组16例
使用数组名作为函数参数主函数中初始化一个矩阵并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第一个元素中,返回主函数之后输出各行元素的和。数组17#include<iostream>usingnamespacestd;voidRowSum(intA[][4],intnrow){ intsum; for(inti=0;i<nrow;i++) { sum=0;
for(intj=0;j<4;j++)
sum+=A[i][j]; cout<<"Sumofrow"<<i
<<"is"<<sum<<endl;A[i][0]=sum; }}1818intmain(){ intTable[3][4]={{1,2,3,4},{2,3,4,5},{3,4,5,6}}; for(inti=0;i<3;i++) { for(intj=0;j<4;j++) cout<<Table[i][j]<<""; cout<<endl; } RowSum(Table,3);
for(inti=0;i<3;i++)
cout<<Table[i][0]}1919运行结果:123423453456Sumofrow0is10Sumofrow1is14Sumofrow2is181014182020关于内存地址内存空间的访问方式通过变量名访问通过地址访问地址运算符:&例:int
var;则&var
表示变量var在内存中的起始地址21声明例:staticinti;staticint*i_pointer=&i;
指向整型变量的指针指针变量的概念概念指针:内存地址,用于
间接访问内存单元指针变量:
用于存放地址的变量20003i_pointer*i_pointeri2000内存用户数据区变量i变量j变量
i_pointer362000200020043010引用例1:i=3;例2:*i_pointer=3;指针22指针变量的初始化语法形式
存储类型数据类型*指针名=初始地址;例:int*pa=&a;注意事项用变量地址作为初值时,该变量必须在指针初始化之前已说明过,且变量类型应与指针类型一致。可以用一个已赋初值的指针去初始化另一个指针变量。不要用一个内部auto变量去初始化static指针。指针23指针变量的赋值运算指针名=地址“地址”中存放的数据类型与指针类型必须相符。向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsignedlongint型。允许声明指向void类型的指针。该指针可以被赋予任何类型对象的地址。例:void*general;指针24例
指针的声明、赋值与使用#include<iostream>usingnamespacestd;intmain(){ int*i_pointer; //声明int型指针i_pointer
inti; //声明int型数i
i_pointer=&i; //取i的地址赋给i_pointer i=10; //int型数赋初值
cout<<"Outputinti="<<i<<endl;//输出int型数的值
cout<<"Outputintpointeri="<<*i_pointer<<endl;//输出int型指针所指地址的内容}指针25程序运行的结果是:Outputinti=10Outputintpointeri=102626例
void类型指针的使用voidvobject;//错,不能声明void类型的变量void*pv; //对,可以声明void类型的指针int*pint;inti;intmain(){
pv=&i; //void类型指针指向整型变量
//void指针赋值给int指针需要类型强制转换:pint=(int*)pv;}指针27指向常量的指针不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。例1char*name1="John";//name1是一般指针*name1='A';//编译正确,运行出错例2constchar*name1="John";//指向常量的指针chars[]="abc";name1=s;//正确,name1本身的值可以改变*name1='1';//编译时指出错误指针28指针类型的常量若声明指针常量,则指针本身的值不能被改变。例:char*constname2="John";name2="abc";//错误,指针常量值不能改变29指针变量的算术运算指针与整数的加减运算指针p加上或减去n,其意义是指针当前指向位置的前方或后方第n个数据的地址。这种运算的结果值取决于指针指向的数据类型。指针加一,减一运算指向下一个或前一个数据。例如:y=*px++相当于y=*(px++)
(*和++优先级相同,自右向左运算)指针30papa-2pa-1pa+1pa+2pa+3*(pa-2)*pa*(pa+1)*(pa+2)*(pa+3)*(pa-1)short*pa3131pb-1pbpb+1pb+2*(pb-1)*pb*(pb+1)*(pb+2)long*pb3232关系运算指向相同类型数据的指针之间可以进行各种关系运算。指向不同数据类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。指针可以和零之间进行等于或不等于的关系运算。例如:p==0或p!=0赋值运算向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。指针变量的关系运算指针33指针例:
(1)int*p=NULL和*p=NULL有什么区别?(2)int*p;*p=NULL;正确吗?(3)如何对内存地址为0x12ff7c的单元赋值?34指向数组元素的指针声明与赋值例:inta[10],*pa;pa=&a[0];或pa=a;通过指针引用数组元素经过上述声明及赋值后:*pa就是a[0],*(pa+1)就是a[1],...,*(pa+i)就是a[i].a[i],*(pa+i),*(a+i),pa[i]都是等效的。不能写a++,因为a是数组首地址是常量。指针35例设有一个int型数组a,有10个元素。用三种方法输出各元素:使用数组名和下标使用数组名和指针运算使用指针变量指针36intmain(){
inta[10];
inti;for(i=0;i<10;i++)
cin>>a[i];
cout<<endl;for(i=0;i<10;i++)
cout<<a[i];return0;}使用数组名和下标3737intmain(){
inta[10];
inti;for(i=0;i<10;i++)
cin>>a[i];
cout<<endl;for(i=0;i<10;i++)
cout<<*(a+i);return0;}使用数组名指针运算38使用指针变量intmain(){
inta[10];
int*p,i;
for(i=0;i<10;i++)
cin>>a[i];
cout<<endl;for(p=a;p<(a+10);p++)
cout<<*p;return0;}39指针数组数组的元素是指针型例:Point*pa[2];
由pa[0],pa[1]两个指针组成指针40例
利用指针数组存放单位矩阵#include<iostream>usingnamespacestd;intmain(){ intline1[]={1,0,0};//声明数组,矩阵的第一行
intline2[]={0,1,0};//声明数组,矩阵的第二行
intline3[]={0,0,1};//声明数组,矩阵的第三行
int*p_line[3]; //声明整型指针数组
p_line[0]=line1; //初始化指针数组元素
p_line[1]=line2; p_line[2]=line3;指针41
//输出单位矩阵
cout<<"Matrixtest:"<<endl;
for(inti=0;i<3;i++) //对指针数组元素循环
{
for(intj=0;j<3;j++) //对矩阵每一行循环
{cout<<p_line[i][j]<<"";}
cout<<endl; }return0;}输出结果为:Matrixtest:1,0,00,1,00,0,14242例
二维数组举例#include<iostream>usingnamespacestd;intmain(){ intarray2[2][3]={{11,12,13},{21,22,23}};
for(inti=0;i<2;i++){cout<<*(array2+i)<<endl;
for(intj=0;j<3;j++){cout<<*(*(array2+i)+j)<<"";//或者cout<<array2[i][j]<<"";}
cout<<endl; }return0;}指针43在某次运行之后,程序的输出结果为:0X0065FDE011,12,130X0065FDEC21,22,234444以指针作为函数参数以地址方式传递数据,可以用来返回函数处理结果。实参是数组名时形参可以是指针。
指针与函数45例题目:读入三个浮点数,将整数部分和小数部分分别输出#include<iostream>usingnamespacestd;voidsplitfloat(floatx,int*intpart,
float*fracpart){//形参intpart、fracpart是指针
*intpart=int(x); //取x的整数部分
*fracpart=x-*intpart;//取x的小数部分}
指针与函数46intmain(){ inti,n; floatx,f;
cout<<"Enterthree(3)floatingpointnumbers"
<<endl; for(i=0;i<3;i++) { cin>>x; splitfloat(x,&n,&f);//变量地址做实参 cout<<"IntegerPartis"<<n
<<"FractionPartis"<<f<<endl; }return0;}4747运行结果:Enterthree(3)floatingpointnumbers4.7IntegerPartis4FractionPartis0.78.913IntegerPartis8FractionPartis0.913-4.7518IntegerPartis-4FractionPartis-0.75184848例:
输出数组元素的内容和地址#include<iostream>#include<iomanip>usingnamespacestd;voidArray_Ptr(long*P,intn){ inti; cout<<"Infunc,addressofarrayis"
<<unsignedlong(P)<<endl; cout<<"Accessingarrayinthefunctionusingpointers"
<<endl; for(i=0;i<n;i++) { cout<<"Addressforindex"<<i<<"is"
<<unsignedlong(P+i); cout<<"Valueis"<<*(P+i)<<endl; }}
指针与函数49intmain(){ longlist[5]={50,60,70,80,90};
cout<<"Inmain,addressofarrayis"<<unsignedlong(list)<<endl; cout<<endl;
Array_Ptr(list,5);return0;}50运行结果:Inmain,addressofarrayis6684132Infunc,addressofarrayis6684132AccessingarrayinthefunctionusingpointersAddressforindex0is6684132Valueis50Addressforindex1is6684136Valueis60Addressforindex2is6684140Valueis70Addressforindex3is6684144Valueis80Addressforindex4is6684148Valueis905151指针型函数当函数的返回值是地址时,该函数就是指针形函数。声明形式存储类型数据类型*函数名()
指针与函数52声明形式存储类型数据类型(*函数指针名)();
含义:数据指针指向数据存储区,而函数指针指向的是程序代码存储区。指向函数的指针
指针与函数53例函数指针#include<iostream>usingnamespacestd;void(*function_pointer)(float); intmain() { floatpi=(float)3.14159; floattwo_pi=(float)2.0*pi;
function_pointer=print_stuff;
function_pointer(pi);
function_pointer=print_message;
function_pointer(two_pi);return0;}
指针与函数54voidprint_stuff(float
data_to_ignore){ cout<<"Thisistheprintstufffunction.\n";}voidprint_message(float
list_this_data){ cout<<"Thedatatobelistedis"<<list_this_data<<endl;}5555运行结果:Thisistheprintstufffunction.Thedatatobelistedis6.283180Thedatatobelistedis13.0000005656动态申请内存操作符newnew类型名T(初值列表)功能:在程序执行期间,申请用于存放T类型的内存空间,并依初值列表赋以初值。结果值:成功:T类型的指针,指向新分配的内存。失败:0(NULL)
动态存储分配57释放内存操作符deletedelete[]指针P功能:释放指针P所指向的内存。P必须是new操作的返回值。加括号表对数组操作,不是数组则不加。
动态存储分配58动态存储分配函数void*malloc(size);参数size:欲分配的字节数返回值:成功,则返回void型指针。
失败,则返回空指针。头文件:<cstdlib>和<cmalloc>
动态存储分配59动态内存释放函数voidfree(void*memblock);参数memblock:
指针,指向需释放的内存。返回值:无头文件:<cstdlib>和<cmalloc>
动态存储分配60用字符数组存储和处理字符串字符数组的声明和引用例:staticcharstr[8]={112,114,111,103,114,97,109,0};
staticcharstr[8]={'p','r','o','g','r','a','m','\0'};
staticcharstr[8]="program";
staticcharstr[8]={"program"}; staticcharstr[]="program";字符串字符串常量,例如:"china"没有字符串变量,用字符数组来存放字符串字符串以'\0'为结束标志字符数组的初始化
字符串61字符串的输入/输出方法逐个字符输入输出将整个字符串一次输入或输出
例:charc[]="China";
cout<<c;注意输出字符不包括'\0'输出字符串时,输出项是字符数组名,输出时遇到'\0'结束。输入多个字符串时,以空格分隔;输入单个字符串时其中不能有空格。
字符串62例
输出一个字符串#include<iostream>usingnamespacestd;intmain(){charc[10]={'I','','a','m','','a','','b','o','y'};
inti;
for(i=0;i<10;i++)//
cout<<c[i];
cout<<endl;return0;}运行结果:
Iamaboy
字符串63例
输出一个字符串#include<iostream>#include<string>usingnamespacestd;intmain(){stringc="Iamaboy";
cout<<c<<endl;return0;}运行结果:
Iamaboy
字符串64例
输出一个字符串#include<iostream>usingnamespacestd;intmain(){char*c="Iamaboy";
cout<<c<<endl;return0;}运行结果:
Iamaboy
字符串65整行输入字符串cin.getline(字符数组名St,字符个数N,结束符);功能:一次连续读入多个字符(可以包括空格),直到读满N个,或遇到指定的结束符(默认为'\n')。读入的字符串存放于字符数组St中。读取但不存储结束符。cin.get(字符数组名St,字符个数N,结束符);功能:一次连续读入多个字符(可以包括空格),直到读满N个,或遇到指定的结束符(默认为'\n')。读入的字符串存放于字符数组St中。
既不读取也不存储结束符。
字符串66整行输入字符串举例#include<iostream>usingnamespacestd;intmain(void){ charcity[80]; charstate[80];
inti; for(i=0;i<2;i++) {cin.getline(city,80,',');
cin.getline(state,80,'\n');
cout<<"City:"<<city<<"State:"
<<state<<endl; }return0;}
字符串67运行结果Beijing,ChinaCity:BeijingCountry:ChinaShanghai,ChinaCity:ShanghaiCountry:China68字符串处理函数strcat(连接),strcpy(复制),
strcmp(比较),strlen(求长度),
strlwr(转换为小写),
strupr(转换为大写)头文件<cstring>
字符串69typedef语句为一个已有的数据类型另外命名语法形式typedef
已有类型名新类型名表;例如typedefdoublearea,volume;typedef
int
natural;naturali1,i2;areaa;volumev;自定义数据类型70枚举类型—enum只要将需要的变量值一一列举出来,便构成了一个枚举类型。枚举类型的声明形式如下:enum
枚举类型名{变量值列表};例如:enumweekday{sun,mon,tue,wed,thu,fri,sat};自定义数据类型71枚举类型—enum枚举类型应用说明:对枚举元素按常量处理,不能对它们赋值。例如,不能写:sun=0;
枚举元素具有缺省值,它们依次为:0,1,2,......。也可以在声明时另行指定枚举元素的值,如:enumweekday{sun=7,mon=1,tue,wed,thu,fri,sat};枚举值可以进行关系运算。整数值不能直接赋给枚举变量,如需
要将整数赋值给枚举变量,应进行强
制类型转换。自定义数据类型72例设某次体育比赛的结果有四种可能:胜(win)、负(lose)、平局(tie)、比赛取消(cancel),编写程序顺序输出这四种情况。分析:由于比赛结果只有四种可能,所以可以声明一个枚举类型,声明一个枚举类型的变量来存放比赛结果。自定义数据类型73#include<iostream>usingnamespacestd;enumgame_result{WIN,LOSE,TIE,CANCEL};intmain(){game_resultresult;
enumgame_resultomit=CANCEL;
intcount;for(count=WIN;count<=CANCEL;count++){result=(game_result)count;if(result==omit){cout<<"Thegamewascancelled\n";}else{cout<<"Thegamewasplayed";if(result==WIN)cout<<"andwewon!";if(result==LOSE)cout<<"andwelost.";
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 护工和病人协议合同书(2篇)
- 2025年孝感b2货运资格证多少道题
- 2024年物业电梯紧急救援协议3篇
- 2025年临沂货运资格证考试题库
- 2024年度精准岗位聘任合同范本2篇
- 2025年延边下载货运从业资格证模拟考试
- 2025年西宁货运从业资格证网上考试
- 2025年运城货运从业资格证网上考试答案
- 2025年深圳货运从业资格证考试模拟
- 《轮胎生产流程》课件
- 华为经营管理-华为供应链管理(6版)
- 冲床吊装施工方案
- JGT491-2016 建筑用网格式金属电缆桥架
- 白蚁监测控制装置施工方案
- 2019北师大版高中英语选择性必修三单词表
- 音乐表演职业生涯规划书
- (新插图)人教版三年级上册数学全册期末复习知识点梳理课件
- 中华鳖生态养殖技术-中华鳖的生态养殖技术
- 残疾人与特殊群体服务项目设计方案
- 2023中建西部建设股份限公司公开招聘上岸笔试历年难、易错点考题附带参考答案与详解
- 考试中心全国计算机等级调整方案
评论
0/150
提交评论