数组和指针

  • 格式:doc
  • 大小:61.50 KB
  • 文档页数:11

● 数组:数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素。

▲ 每个元素有n个下标的数组称为n维数组。

▲ a[100]:下标从0开始,到99止,不能为100。

▲ a[i][j]:i为行标,j为下标。

● 数组的声明: 数组类型 数组名[表达式1][表达式2]……

● 数组的使用: 数组类型 数组名[表达式1][表达式2]……

● 数组的存储:数组元素在内存中是顺序、连续存储的。

● 数组的初始化:就是在声明数组时给部分或全部元素赋初值。

▲ int a[3]={1,2,3}; 等价于 int[]{1,2,3};

▲ int a[5]={1,2,3}; //部分初始化,必须连续,不能间隔赋初值

▲ int a[2][3]={1,2,3,4,5,6}; 等价于 int a[][3]={1,2,3,4,5,6} //给出全部的初值时,行标可省

▲ int a[2][3]={{1,2},{3,4},{5,6}};

● 数组作为函数参数

▲ 使用数组名传递数据时,传递的是地址

▲ 使用数组名做函数的参数,则实参和形参都应该是数组名,且类型要相同

▲ 对形参数组的修改,也就是对实参数组的修改

▲ int ss(int a[][4],int bb) 调用:ss(b,x); //b是数组,x传递的是第一维的维数

● 对象数组

▲ 声明: 类名 数组名[下标表达式]

▲ 引用: 数组名[下标].成员名

▲ 当一个数组中的元素对象被删除时,系统会调用析构函数来完成扫尾工作。 ● 指针:是对地址直接操作的手段。动态内存分配和管理也离不开指针

● 指针类型:用来存放内存单元地址的变量类型,就是指针类型。

● 指针变量的声明: 数据类型 *标识符;

● 与地址相关的运算——"*"和"&"

▲ "*"称为指针运算符(也称解析(dereference)),表示获取指针所指向的变量的值,是一元操作符。

▲ "&"称为取地址运算符,用来得到一个对象的地址,是一个一元操作符。

▲ int *p; //声明p是一个int型指针

▲ cout*p; //输出指针p所指向地址中的内容

▲ int &ctj; //声明一个int型的引用ctj

▲ int a,b;

int *pa,*pb=&b;

pa=&a;

● 指针的赋值

▲ 指针声明后,必须先赋值后使用。

▲ 在声明指针的同时进行初始化赋值:

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

▲ 在声明指针后,单独使用赋值语句赋值:

指针名=地址;

▲ 可以使多个指针指向同一个变量:

int a,*p1,*p2,*p3;

a=8;

p1=&a;

p2=p1;

p3=p1;

▲ 数组的起始地址就是数组名:

int a[10];

int *p=a;

▲ 可以声明指向常量的指针,此时不能通过指针来改变所指对象的值,但指针本身可以改变,这样可以

确保指针所指向的常量不被意外更改: const char *name1="John";

char s[]="abc";

name1=s; //正确,name1本身的值可以改变

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

▲ char name1="John";

name1='A'; //编译对,运行时错,因为name1所指向的是常量,常量不能被修改

▲ 可以声明指针类型的常量,这时指针本身的值不能被修改:

char *const name1="John";

name1="abc"; //错误,name1是指针常量,值不能改变

▲ 一般情况下,指针的值只能赋给相同类型的指针

▲ void类型的指针,可以存储任何类型的对象地址

void *p; //定义了一个void型的指针变量p

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

▲ 任何类型的指针都可以赋值给void类型的指针变量

void *p;

int *pv="aaab";

int a;

p=&a;

p=pv;

▲ 给指针赋值必须是地址常量(如数组名)或地址变量,不能是非0的整数

▲ 如果给一个指针变量赋值为0,表示该指针是一个空指针,不指向任何地址:

int *p;

p=0; //将p设置为空指针,不指向任何地址

● 指针运算:指针是一种数据类型。也可参加运算,指针可以和整数进行加减运算,但运算规则是比较特殊的。

● 用指针处理数组元素

▲ 数组元素是存储在一段连续内存空间中的。

▲ 数组名就是数组存储的首地址。数组名a也叫数组指针,数组指针a虽然是指针,但它是常量,不能自加,即a++是错误的,而指向数组的指针p却可以自加,即p++。 ▲ 数组中个数的计算:sizeof(a)/sizeof(a[0])

▲ 数组元素用数组指针和指针的表示方法:

int a[100],b[100][100];

int *pa=a, *pb=b;

☆ 一维数组:

a[i] //下标法

*(a+i) //数组指针法表示数组元素a[i]

*a //相当于*(a+0),表示数组a[0]

*(p+i) //指针法表示数组元素a[i]

p=a; //把数组a的首地址给指针p,使指针p指向数组a

p=&a[5] //使指针p指针数组元素a[5]

☆ 二维数组:

b[i][j] //下标法

b[0] //二维数组的0行首地址

b[1] //二维数组的1行首地址

b[i] //二维数组的i行首地址

*(b+0) //二维数组的0行首地址

*(b+1) //二维数组的1行首地址

*(b+i) //二维数组的i行首地址

*(*(b+i)+j) //数组指针法表示二维数组的元素(又叫二级指针表示

(*(b+i))[j] //行用指针,列用下标表示

*(b[i]+j) //行用下标,列用指针表示

*(&a[0][0]+i*j+j) //一级指针表示

● 指针数组:如果一个数组的每个元素都是指针,这个数组就是指针数组:

数据类型 *数组名[下标表达式]

例:int *p[10];

▲ 数组名是指针数组的名称,也是首地址。 ▲ 必须先赋值,后使用。

▲ 一般与二维数组配合使用。

● 用指针作为函数参数

▲ 当需要在不同的函数之间传送存放在一个连续的内存区域中的大量数据时,就可只传递数据的起始地址。

▲ 指针作函数形参有三个作用:

第一个作用:是使实参和形参指针指向共同的内存空间,以达到参数双向传递的目的。

第二个作用:就是减少函数调用时数据传递的开销。

第三个作用:是通过指向函数的指针传递函数代码的首地址。

● 指针型函数:

指针函数的一般定义:

返回值的数据类型 *函数名(参数表)

函数体

▲ 函数结束后都要有返回值,指针也可以是函数的返回值。

▲ 当一个函数的返回值是指针类型时,这个函数就是指针型函数。

▲ 使用指针型函数的最主要目的就是要 在函数结束时把大量的数据从被调函数返回到主调函数中。

▲ 通常非指针函数调用结束后,只能返回一个变量或者对象。

● 指向函数的指针

声明: 返回值数据类型 (*函数指针名)(形参表) //函数指针在使用前也要赋值

赋值:函数指针名=函数名;

▲ 函数名表示函数的代码在内存中的起始地址。

▲ 调用函数的通常形式:"函数名(参数表)"的实质就是"函数代码首地址(参数表)"。

▲ 函数指针:就是专门用来存放函数代码首地址的变量。

▲ 在程序中可以像使用函数名一样使用指向函数的指针来调用函数。

▲ 一旦函数指针指向了某个函数,它与函数名具有同样的作用

● 对象指针:就是用于存放对象地址的变量。

声明: 类名 *对象指针名

例 : Point *p_Point; //声明Point类的对象指针变量p_Point

Point p1; //声明Point类的对象p1

p_Point=&p1; //使对象指针p_Point指向对象p1

使用: 对象指针名—>成员名 //成员是公有成员(函数)

cout<

cout

▲ 对象在初始化后都会在内存中占有一定空间(用于存储数据成员,函数成员不在每一个对象中存储副本)。

▲ 可以通过对象名,也可以通过对象地址来访问一个对象。

▲ 通过对象指针,可以访问到对象的公有成员

● this指针:一个隐含于每一个类的成员函数中的特殊指针(包括构造函数和析构函数),它用于指向正在被成员函数操作的对象。

▲ 构造函数初始化时:

X=xx;

Y=yy;

相当于执行了 this—>X=xx;

this—>Y=yy;

▲ this指针明确指出了成员函数当前所操作的数据所属的对象。

▲ 当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。

▲ 可使用*this来标识正在调用该函数的对象。

● 指向类的非静态成员的指针

▲ 类的成员自身也是一些变量、函数或者对象等,因此也可以直接将它们的地址存放到一个指针变量中,

这样,就可以使指针直接指向对象的成员,进行相应的操作。

▲ 也必须要先声明,再赋值,然后引用。

▲ 通过指向成员的指针,只能访问到公有成员。

▲ 声明: 类型说明符 类名∷*指针名; //声明指针公有数据成员的指针