6 第6章 数组指针与字符串一.docx

上传人:b****7 文档编号:23309065 上传时间:2023-05-16 格式:DOCX 页数:18 大小:437.41KB
下载 相关 举报
6 第6章 数组指针与字符串一.docx_第1页
第1页 / 共18页
6 第6章 数组指针与字符串一.docx_第2页
第2页 / 共18页
6 第6章 数组指针与字符串一.docx_第3页
第3页 / 共18页
6 第6章 数组指针与字符串一.docx_第4页
第4页 / 共18页
6 第6章 数组指针与字符串一.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

6 第6章 数组指针与字符串一.docx

《6 第6章 数组指针与字符串一.docx》由会员分享,可在线阅读,更多相关《6 第6章 数组指针与字符串一.docx(18页珍藏版)》请在冰豆网上搜索。

6 第6章 数组指针与字符串一.docx

6第6章数组指针与字符串一

第6章数组、指针与字符串

(一)

6.1数组的定义与初始化

6.1.1数组的定义与使用

●数组是具有一定顺序关系的若干相同类型变量的集合体,组成数组的变量称为该数组的元素。

数组的定义

●例如:

inta[10]; 

表示a为整型数组,有10个元素:

a[0]...a[9]

●例如:

inta[5][3];

表示a为整型二维数组,其中第一维有5个下标(0~4),第二维有3个下标(0~2),数组的元素个数为15,可以用于存放5行3列的整型数据表格。

数组的使用

●使用数组元素

必须先声明,后使用。

只能逐个引用数组元素,而不能一次引用整个数组

例如:

a[0]=a[5]+a[7]-a[2*3]

例如:

b[1][2]=a[2][3]/2

例6-1数组的声明与使用

//例6_1数组的声明与使用.cpp

#include

usingnamespacestd;

intmain(){

inta[10],b[10];

for(inti=0;i<10;i++){

a[i]=i*2-1;

b[10-i-1]=a[i];

}

for(inti=0;i<10;i++){//如果i=1;i<=10;i++会造成数组越界

cout<<"a["<

cout<<"b["<

}

return0;

}

运行结果:

6.1.2数组的存储与初始化

一维数组的存储

 数组元素在内存中顺次存放,它们的地址是连续的。

元素间物理地址上的相邻,对应着逻辑次序上的相邻。

 例如:

一维数组的初始化

在定义数组时给出数组元素的初始值。

●列出全部元素的初始值

例如:

staticinta[10]={0,1,2,3,4,5,6,7,8,9};

●可以只给一部分元素赋初值

例如:

staticinta[10]={0,1,2,3,4};

●在对全部数组元素赋初值时,可以不指定数组长度

例如:

staticinta[]={0,1,2,3,4,5,6,7,8,9}

二维数组的存储

●按行存放

例如:

 floata[3][4];

可以理解为:

其中数组a的存储顺序为:

a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23

二维数组的初始化

●将所有初值写在一个{}内,按顺序初始化

例如:

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}};

●列出全部初始值时,第1维下标个数可以省略

例如:

staticinta[][4]={1,2,3,4,5,6,7,8,9,10,11,12};

或:

staticinta[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

注意:

●如果不作任何初始化,内部auto型数组中会存在垃圾数据,static数组中的数据默认初始化为0;

●如果只对部分元素初始化,剩下的未显式初始化的元素,将自动被初始化为零;

●现在我们来看一个用数组存放Fibonacci数列的例子。

例:

 求Fibonacci数列的前20项

//例6_1_2求Fibonacci数列的前20项.cpp

#include

usingnamespacestd;

intmain(){

intf[20]={1,1};//初始化第0、1个数

for(inti=2;i<20;i++)//求第2~19个数

f[i]=f[i-2]+f[i-1];

for(inti=0;i<20;i++){//输出,每行5个数

if(i%5==0)cout<

cout.width(12);//设置输出宽度为12

cout<

}

return0;

}

运行结果:

一维数组应用举例

循环从键盘读入若干组选择题答案,计算并输出每组答案的正确率,直到输入ctrl+z为止。

每组连续输入5个答案,每个答案可以是'a'..'d'。

例6-1-3:

 一维数组应用举例

//例6_1_3一维数组应用举例.cpp

#include

usingnamespacestd;

intmain(){

constcharkey[]={'a','c','b','a','d'};

constintNUM_QUES=5;

charc;

intques=0,numCorrect=0;

cout<<"Enterthe"<

"<

while(cin.get(c)){

if(c!

='\n'){

if(c==key[ques]){

numCorrect++;cout<<"";

}else

cout<<"*";

ques++;

}else{

cout<<"Score"<(numCorrect)/NUM_QUES*100<<"%";

ques=0;numCorrect=0;cout<

}

}

return0;

}

运行结果:

6.1.3数组作为函数参数

●数组元素作实参,与单个变量一样。

●数组名作参数,形、实参数都应是数组名(实质上是地址.关于地址详见6.2)。

类型要—样,传送的是数组首地址,对形参数组的改变会直接影响到实参数组。

例6-2使用数组名作为函数参数

主函数中初始化一个二维数组,表示—个矩阵,并将每个元素都输出,然后调用子函数,分别计算每一行的元素之和,将和直接存放在每行的第—个元素中.返回主函数之后输出各行元素的和。

//例6_2使用数组名作为函数参数.cpp(P193)

#include

usingnamespacestd;

voidrowSum(inta[][4],intnRow){//计算二维数组A每行元素的值的和,nrow是行数

for(inti=0;i

for(intj=1;j<4;j++)

a[i][0]+=a[i][j];

}

}

intmain(){//主函数

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<

cout<

}

rowSum(table,3);//调用子函数,计算各行和

for(inti=0;i<3;i++)//输出计算结果

cout<<"Sumofrow"<

return0;

}

运行结果:

6.1.4对象数组

对象数组的定义与访问

●定义对象数组

类名数组名[元素个数];

●访问对象数组元素

通过下标访问

数组名[下标].成员名

对象数组初始化

●数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象。

●通过初始化列表赋值。

例:

Pointa[2]={Point(1,2),Point(3,4)};

●如果没有为数组元素指定显式初始值,数组元素便使用默认值初始化(调用默认构造函数)。

数组元素所属类的构造函数

●元素所属的类不声明构造函数,则采用默认构造函数。

●各元素对象的初值要求为相同的值时,可以声明具有默认形参值的构造函数。

●各元素对象的初值要求为不同的值时,需要声明带形参的构造函数。

●当数组中每一个对象被删除时,系统都要调用一次析构函数。

例6-3 对象数组应用举例

//Point.h

#ifndef_POINT_H

#define_POINT_H

classPoint{//类的定义

public:

//外部接口

Point();

Point(intx,inty);

~Point();

voidmove(intnewX,intnewY);

intgetX()const{returnx;}

intgetY()const{returny;}

staticvoidshowCount();//静态函数成员

private:

//私有数据成员

intx,y;

};

#endif//_POINT_H防止头文件被加载两次或以上

//Point.cpp

#include

#include"Point.h"

usingnamespacestd;

Point:

:

Point(){

x=y=0;

cout<<"DefaultConstructorcalled."<

}

Point:

:

Point(intx,inty):

x(x),y(y){

cout<<"Constructorcalled."<

}

Point:

:

~Point(){

cout<<"Destructorcalled."<

}

voidPoint:

:

move(intnewX,intnewY){

cout<<"Movingthepointto("<

x=newX;

y=newY;

}

//例6_3对象数组应用举例.cpp(P194)

#include"Point.h"

#include

usingnamespacestd;

intmain(){

cout<<"Enteringmain..."<

Pointa[2];

for(inti=0;i<2;i++)

a[i].move(i+10,i+20);

cout<<"Exitingmain..."<

return0;

}

运行结果:

6.1.5基于范围的for循环

intmain()

{

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

int*p;

for(p=array;p

{

   *p+=2;

   std:

:

cout<<*p<

:

endl;

}

 

return0;

}

 

intmain()

{

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

for(int&e:

array)

{

   e+=2;

   std:

:

cout<

:

endl;

}

 

return0;

}

例6_4利用Point类进行点的线性拟合

//例6_4利用Point类进行点的线性拟合.cpp(P196)

//Point.h

#ifndef_POINT_H

#define_POINT_H

classPoint{//Point类的定义

public:

//外部接口

Point(floatx=0,floaty=0):

x(x),y(y){}

floatgetX()const{returnx;}

floatgetY()const{returny;}

private:

//私有数据成员

floatx,y;

};

#endif//_POINT_H

//例6_4利用Point类进行点的线性拟合.cpp(P196)

#include"Point.h"

#include

#include

usingnamespacestd;

//直线线性拟合,points为各点,nPoint为点数

floatlineFit(constPointpoints[],intnPoint){

floatavgX=0,avgY=0;

floatlxx=0,lyy=0,lxy=0;

for(inti=0;i

avgX+=points[i].getX()/nPoint;

avgY+=points[i].getY()/nPoint;

}

for(inti=0;i

lxx+=(points[i].getX()-avgX)*(points[i].getX()-avgX);

lyy+=(points[i].getY()-avgY)*(points[i].getY()-avgY);

lxy+=(points[i].getX()-avgX)*(points[i].getY()-avgY);

}

cout<<"Thislinecanbefittedbyy=ax+b."<

cout<<"a="<

cout<<"b="<

returnstatic_cast(lxy/sqrt(lxx*lyy));//返回相关系数r

}

intmain(){

Pointp[10]={Point(6,10),Point(14,20),Point(26,30),Point(33,40),Point(46,50),

Point(54,60),Point(67,70),Point(75,80),Point(84,90),Point(100,100)};//初始化数据点

floatr=lineFit(p,10);//进行线性回归计算

cout<<"Linecoefficientr="<

return0;

}

运行结果:

6.2指针

6.2.1指针的概念、定义和指针运算

内存空间的访问方式

●通过变量名访问

●通过地址访问

指针的概念

●指针:

内存地址,用于间接访问内存单元

●指针变量:

用于存放地址的变量

指针变量的定义

●例:

staticinti;

staticint*ptr=&i;

●例:

*ptr=3;

6.2.3与地址相关的运算——“*”和“&”

●指针运算符

●地址运算符:

&

6.2.4指针的初始化和赋值

6.2.4.1指针变量的初始化

●语法形式

存储类型数据类型 *指针名=初始地址;

●例:

int*pa=&a;

●注意事项

■用变量地址作为初值时,该变量必须在指针初始化之前已声明过,且变量类型应与指针类型一致。

■可以用一个已有合法值的指针去初始化另一个指针变量。

■不要用一个内部非静态变量去初始化 static 指针。

6.2.4.2指针变量的赋值运算

●语法形式

指针名=地址

注意:

“地址”中存放的数据类型与指针类型必须相符

●向指针变量赋的值必须是地址常量或变量,不能是普通整数,例如:

■通过地址运算“&”求得已定义的变量和对象的起始地址

■动态内存分配成功时返回的地址

●例外:

整数0可以赋给指针,表示空指针。

●允许定义或声明指向 void 类型的指针。

该指针可以被赋予任何类型对象的地址。

例:

 void*general;

6.2.4.3指针空值nullptr

●以往用0或者NULL去表达空指针的问题:

■C/C++的NULL宏是个被有很多潜在BUG的宏。

因为有的库把其定义成整数0,有的定义成 (void*)0。

在C的时代还好。

但是在C++的时代,这就会引发很多问题。

●C++11使用nullptr关键字,是表达更准确,类型安全的空指针

例6-5 指针的定义、赋值与使用

//例6_5指针的定义、赋值与使用.cpp(P202)

#include

usingnamespacestd;

intmain(){

inti;//定义int型数i

int*ptr=&i;//取i的地址赋给ptr

i=10;//int型数赋初值

cout<<"i="<

cout<<"*ptr="<<*ptr<

return0;

}

运行结果:

例6-6void类型指针的使用

//例6_6void类型指针的使用源.cpp(P203)

#include

usingnamespacestd;

intmain(){

//!

voidvoidObject;//错,不能声明void类型的变量

void*pv;//对,可以声明void类型的指针

inti=5;

pv=&i;//void类型指针指向整型变量

int*pint=static_cast(pv);//void类型指针赋值给int类型指针

cout<<"*pint="<<*pint<

return0;

}

运行结果:

6.2.4.5指向常量的指针

●不能通过指向常量的指针改变所指对象的值,但指针本身可以改变,可以指向另外的对象。

●例

 inta;

constint*p1=&a;//p1是指向常量的指针

intb;

p1=&b;//正确,p1本身的值可以改变

 *p1=1;//编译时出错,不能通过p1改变所指的对象

6.2.4.6指针类型的常量

●若声明指针常量,则指针本身的值不能被改变。

●例

inta;

int*const p2 =&a;

p2 =&b;//错误,p2是指针常量,值不能改变

6.2.5指针的算术运算、关系运算

6.2.5.1指针类型的算术运算

●指针与整数的加减运算

●指针++,--运算

指针类型的算术运算

●指针p加上或减去n

■其意义是指针当前指向位置的前方或后方第n个数据的起始位置。

●指针的++、--运算

■意义是指向下一个或前一个完整数据的起始。

●运算的结果值取决于指针指向的数据类型,总是指向一个完整数据的起始位置。

●当指针指向连续存储的同类型数据时,指针与整数的加减运和自增自减算才有意义。

指针与整数相加的意义

6.2.5.2指针类型的关系运算

●指向相同类型数据的指针之间可以进行各种关系运算。

●指向不同数据类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。

●指针可以和零之间进行等于或不等于的关系运算。

例如:

p==0或p!

=0 

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 财会金融考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1