C++数组与指针

一、一维数组

1.1声明数组

  • 类型 数组名[数组长度];
  • 数组长度必须是整型常量表达式

1.2声明并初始化数组

  • 类型 数组名[数组长度] = {初始化列表};
  • 声明时可以不指明数组长度,编译器将根据初始化列表的长度作为数组长度
  • 若初始化列表的初始值数少于数组长度,则其余元素均初始化为0

1.3访问数组元素

  • 数组名[下标];
  • 从0开始,不能越界访问,否则报错
  • 数组不能进行整体赋值,整体比较以及char除外的整体I/O操作
  • 遍历数组:for循环

1.4数组作为函数参数

  • 要将数组名和数组长度作为实参

1.5从函数返回数组

  • 返回数组名或指针

二、二维数组

2.1声明二维数组

  • 类型 数组名[行数][列数];
  • 行数和列数必须是整型常量表达式

2.2声明并初始化二维数组

  • 类型 数组名[行数][列数] = {{初始化列表},{},..};    //内部嵌套的花括号是可选的
  • 声明时可以不指定行数
  • 数组在内存中一行一行存放

2.3访问二维数组元素

  • 数组名[下标][下标];
  • 遍历二维数组:for循环内再嵌套一个for循环

2.4二维数组作为函数参数

  • 数组作为函数参数时,要将数组名和行数作为实参;被调用函数的第一个形参必须给出第二维的长度(即列数),且该列数需与实参的列数一致,第二个形参接收行数

2.5从函数返回二维数组

  • 返回数组名或指针

三、指针

3.1指针常量(指针类型的常量,即指针本身就是一个常量)

  • &变量名/常量名,代表存放该变量/常量的内存地址
  • 数组名,数值上arr=&arr[0]
//指向变量XX的指针常量
//可以通过*ptr修改var1,*ptr也会随着var1的改变而改变,ptr不可以指向其他变量/常量
int var1 = 10;
int var2 = 20;
const int var3 = 30;
int* const ptr = &var1;
*ptr = 40;    //valid,now var1=40
var1 = 50;    //valid,now *ptr=50
ptr = &var2;  //invalid
ptr = &var3;  //invalid      
//指向常量XX的指针常量
//不可以通过*ptr修改var1,var1本身也是常量,ptr不可以指向其他变量/常量
const int var1 = 10;
int var2 = 20;
const int var3 = 30;
const int* const ptr = &var1;
*ptr = 40;    //invalid
var1 = 50;    //invalid
ptr = &var2;  //invalid
ptr = &var3;  //invalid    

3.2指针变量(指针类型的变量,即指针本身是一个变量)

int* ptr;    //基数据类型* 指针变量名;强调ptr是一个指向int的指针(复合类型) 

int *ptr;    //基数据类型 *指针变量名;强调*ptr是一个int类型的值,常用于定义多个指针变量
//指向XX型变量的指针变量
//可以通过*ptr修改var1,*ptr也会随着var1的改变而改变,ptr可以指向其他变量,ptr不可以指向其他常量    
int var1 = 10;
int var2 = 20;
const int var3 = 30;
int* ptr = &var1;
*ptr = 40;    //valid,now var1=40
var1 = 50;    //valid,now *ptr=50
ptr = &var2;  //valid
ptr = &var3;  //invalid   
//指向XX型常量的指针变量
//不可以通过*ptr修改var1,var1本身也是常量,ptr可以指向其他变量/常量
const int var1 = 10;
int var2 = 20;
const int var3 = 30;
const int* ptr = &var1;
*ptr = 40;    //invalid
var = 50;     //invalid
ptr = &var2;  //valid
ptr = &var3;  //valid

3.3void* 类型指针

  • 任何类型的指针都可以赋值给void*指针
  • void*指针要赋值给其他类型的指针需要强制类型转换
  • malloc得到的指针是void*类型

3.4NULL指针

  • #define NULL ((void*)0)
  • 当不清楚指针指向何处时,将其初始化为NULL
  • 当对指针进行解引用时,判断其是否为NULL

3.5解引用操作符*

  • 一定要先为指针变量赋值再使用
  • *指针变量就是该指针指向的变量/常量

3.6从编译器角度

  • 使用变量名是间接访问indirect access
  • 使用指针是直接访问direct access

3.7指针运算

  • 自加、自减,加/减常数
  • 做差:ptrdiff_t diff=p2-p1;    // 指针的减法可以计算两个指针之间相隔的元素个数,所得结果是一个 ptrdiff_t 类型
  • 比较:==  !=  >   >=  <   <=

3.8指针与函数

  • 指针变量作为函数参数,是使被调函数获得某变量的地址,从而使用这个地址访问这个变量
  • 引用变量作为函数参数,形参和实参是同一个变量,形参是实参的别名

3.9指针与一维数组

  • 数组名是指针常量,可以赋值给指针变量,此时指针变量可以代替数组名访问数组。二者均可用下标法:arr[i]和指针法:*(arr+i)
float score[5];
float* p = score; 
float* p = &score[0];
  • 数组作为函数参数时,形参是指针变量
foo( int arr[], int n)
foo( int* arr, int n)
  • 指针本身并没有指出数组的长度,所以必要时还要增加参数传入数组的长度
  • 对数组名使用sizeof运算符,得到的是数组的长度;对指针应用sizeof得到的是指针的长度,即使指针指向的是一个数组
short tell[10];
cout << tell << endl;
cout << &tell << endl;
cout << &tell + 1 << endl;
//两个输出地址相同,但是&tell[0](即tell)是一个2字节的内存块的地址,
//而&tell是一个20字节内存块的地址,所以tell+1将地址加2,而&tell+1是将地址加20;

3.10指针与二维数组

  • 二维数组名是一个指向一维数组的指针常量,指向整个二维数组的地址,它的值正好等于一维数组arr[0],即第0行的地址
  • 下标法arr[i][j],指针法*(*(arr+i)+j)
  • 传递二维数组时,列数通过指针类型确定,如void print(int arr[][5],int row)
  • 指向指针的指针
//type (*p)[col] 定义p为指向“由col个type型元素组成的一维数组”的指针
short (*p)[10] = &tell;
//pas指向包含10个元素的short数组
//pas的类型为short (*)[10]
//*pas与tell是等价的

int* arr[4];    //声明一个由4个指向int的指针组成的数组
int (*arr)[4];  //声明一个指向由4个int组成的数组的指针
//指针与二维数组 
int arrt[2][3] = { {1,2,3},{4,5,6} };
cout << "arrt=" << arrt << endl;     //二维数组名
cout << "arrt[0]=" << arrt[0] << endl;          //第0行元素第0列的地址
cout << "*(arrt+0)=" << *(arrt + 0) << endl;   //第0行元素第0列的地址
cout << "*arrt=" << *arrt << endl;             //第0行元素第0列的地址
cout << "arrt+1=" << arrt + 1 << endl;      //第一行的地址
cout << "&arrt[1]=" << &arrt[1] << endl;   //第一行的地址
cout << "arrt[1]=" << arrt[1] << endl;        //arr2[1][0]的地址
cout << "*(arrt+1)=" << *(arrt + 1) << endl;  //arr2[1][0]的地址
cout << "arrt[1]+2=" << arrt[1] + 2 << endl;         //arr2[1][2]的地址
cout << "*(arrt+1)+2=" << *(arrt + 1) + 2 << endl;   //arr2[1][2]的地址
cout << "&arrt[1][2]=" << &arrt[1][2] << endl;       //arr2[1][2]的地址
cout << "*(arrt[1]+2)=" << *(arrt[1] + 2) << endl;             //arr2[1][2]
cout << "*(*(arrt+1)+2)=" << *(*(arrt + 1) + 2) << endl;   //arr2[1][2]
cout << "arrt[1][2]=" << arrt[1][2] << endl;               //arr2[1][2]

3.11创建动态数组

//malloc和free
指针变量 = (type*)malloc(sizeof(type)*length);
free(指针变量);

//new和delete
type* arr;    //一维数组
arr = new type[length];
delete[]arr;

type **arr;    //二维数组
arr = new type*[col];
for (i = 0; i < col; i++)
    arr[i] = new type[row];

for (int i = 0; i < col; i++)
    delete[]arr[i];
delete[]arr;

3.12指针与结构

structname* pointer = &a_struct;
pointer->member == (*pointer).member == a_struct.member;

structname* pointer = new structname;
delete pointer;

3.13指针与对象

classname *pointer = &object;
pointer->member = (*pointer).member = object.member;

classname *pointer = new classname(arguments);
delete pointer;

3.14传递指针给函数

3.15从函数返回指针

3.16函数指针

  • !=返回指针的函数
  • type *函数名(形参列表);返回指向type型的指针
  • 函数名是一个指针常量,可以赋给指针变量,然后指针变量可以代替函数名被调用
  • type (*指针变量)(形参列表);type就是指针变量要指向的函数的返回值类型,形参列表也要和指针变量指向的函数的形参列表一致,可以没有形参名字
  • 实现晚绑定
bool min(int a,int b);
bool (*p)(int,int);
p = min;
p(3,4) = (*p)(3,4) = min(3,4);

typedef bool (*ptr)(int,int);
ptr p1 = min;

 

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值