1、数组
1.1 基本数组
- 数组声明
int a[10];
- 声明时方括号内是元素个数。下标从0开始。
- 第一个元素是
a[0]
,最后一个元素是a[9]
a[n]
表示的是第n+1
个元素
- 二维数组
int b[3][4];
- 数组可以为任何类型,但不能为void类型
- 数组名是一个指针常量
- 存储
- 数组元素在内存中是顺序、连续存储的
- 行优先存储
- 初始化
-
一维数组初始化
int arr[3]; //声明数组,未初始化,无法访问 int arr[3]; //在文件作用域声明数组,默认初始化为0 static int arr[3]; //静态数组,默认初始化为0 int arr[3]={1,2,3}; //给长度,给完整元素 int arr[]={1,2,3}; //不给长度,给完整元素 int arr[10]={1,2,3}; //给长度,给部分元素,则缺省元素值为0 int arr[10]={}; //初始化一个数组,其中元素值均为0
-
二维数组初始化
//1、给大小,给完整元素值。以下写法等价 int arr[2][3]={1,2,3,4,5,6}; int arr[2][3]={{1,2,3},{4,5,6}}; int arr[][3]={{1,2,3},{4,5,6}};//第一个大小能省,第二个大小不能省
-
- 数组作为函数参数,传递的是地址
-
//不加const,说明arr是个指针变量 void test_arr(int arr[5]) {//函数体内无法通过sizeof(arr)获取传入数组的真实大小,方括号里写了大小也没用 } void test_arr(int arr[]) {//函数体内无法通过sizeof(arr)获取传入数组的真实大小 } void test_arr(int *arr) {//函数体内无法通过sizeof(arr)获取传入数组的真实大小 } //加const,说明arr是个常量指针,表示无法在函数体内通过arr修改数组中元素的值 //const在*前面,表示arr是常量指针 void test_arr(const int arr[]) {//函数体内无法通过sizeof(arr)获取传入数组的真实大小 a[0]=2;//编译错误 }
-
函数体内无法通过sizeof(arr)获取传入数组的真实大小
-
解决1:将数组长度传进函数
- 解决2:在函数内部不调用超出数组范围的元素
-
-
1.2 对象数组
-
Point p[5];//每个数组元素都是一个Point类的对象 p[2].x;//通过“.”访问元素的成员
-
Point p[2] = {Point(4,5),Point(3,2)};//调用构造函数 Point p[2] = {Point(4,5)};//第一个元素调用构造函数,第二个元素调用默认构造函数 //若类中没有默认构造函数(不带参的构造函数),则会报错
- 数组中每一个对象被删除时,系统都要调用一次析构函数初始化
-
2、 指针(简述)
- 指针是一种数据类型,具有指针类型的变量称为指针变量。指针变量的作用是存放内存单元地址。
-
int a=10; //定义int类型变量a,值为10 int *ptr=&a; //定义int*类型变量ptr,值为&a(a的地址) //此时ptr是个指针变量,*ptr在内存中找到与ptr值相同的地址,返回那个地址上存储的值 cout<<ptr<<endl; //ptr表示i在内存空间中的地址 cout<<*ptr<<endl; //*ptr表示的就是i的值, cout<<i<<endl;
- 地址相关的运算
*
指针运算符,获取指针所指向的变量的值&
取地址运算符,获取一个对象的地址
- 一般情况下,指针的值只能赋给相同类型的指针
- void类型指针,可以存储任何类型的对象地址
- 经过类型显示转换,通过void类型的指针可以访问任何类型的数据
- 指针运算(加减)
- 同一类型的指针与指针之间
- 计算结果:数据单元个数,而不是字节数、
-
int a[10]; int *p=a; int *q=a+6; p-q //值为6,表示从p开始,到q之前的数据单元个数(包含p,不包含q)
- 指针与整数之间
- 计算结果:指针
-
int a[3]; int *p=a; p //表示a[0]的地址 p+1 //表示a[1]的地址 *(p+1) //表示a[1]的值
- 指针和0的关系运算
-
if(p==0){} if(p!=0){} if(p){}
-
- 同一类型的指针与指针之间
- 指针传参:速度快
- 函数指针与指针函数
- 函数指针:指向一个函数的指针
-
数据类型 (*函数指针名)(形参表)
-
- 指针函数:返回值是指针的一个函数
-
数据类型 * 函数名(参数表) { 函数体 }
-
- 函数指针:指向一个函数的指针
- 对象指针
- 对象指针是用来存放对象地址的变量
Point *pointPtr; Point p1; pointPtr = &p1;
- 对象指针是用来存放对象地址的变量
- this指针
- this指针是一个隐含于每一个类的非静态成员函数中的特殊指针,用于指向正在被成员函数操作的对象
- 解决了类中函数形参与类中成员的同名问题
- 动态内存分配返回一个指针
-
申请对象空间
int *p; p=new int(2); //p指向一个int类型的变量,这变量值为2 p=new int(); //p指向一个int类型的变量,这变量值为0 //上一行代码没有调用构造函数,基本数据类型没有构造函数,new一个对象会调用构造函数 p=new int; //p指向一个int类型的变量,这变量无初始值 /*=====================================================================*/ //若用户定义了默认构造函数,下面程序的效果相同,都调用用户定义了的默认构造函数 new T; //若用户未定义默认构造函数,则这个会调用隐含的默认构造函数 new T(); //若用户未定义默认构造函数,这个会对基本数据类型的成员和指针类型成员用0初始化
- 申请数组空间
int *p; p=new int[6];
- 释放空间
delete ptr;//释放对象空间 delete []ptr;//释放数组空间
-
3、字符串
- 字符串常量是用一对双引号括起来的字符序列,如
hello world!
- 存储时在字符后面加
'\0'
,它的ASCII码值为0
。要记得多申请1个空间 -
//以下写法等效 char str[13] = { 'h', 'e ', 'l', 'l' , 'o', 'w ', 'o' , 'r' , 'l' , 'd' , '\0'}; char str[13] = "hello world!"; //这时末尾会自动加'\0' char str[] = "hello world!";