一、指针与二维数组
1.二维数组
eg:
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
a[0][0]
a[0][1]
a[0] a[0][2]
a[0][3]
a[1][0]
a a[1] a[1][1]
a[1][2]
a[1][3]
a[2] a[2][0]
a[2][1]
a[2][2]
a[2][3]
结论:
a <=> &a[0]
a+1 <=> &a[1]
a[0] <=> &a[0][0]
a[1] <=> &a[1][0]
a[2] <=> &a[2][0]
例:
printf("a[0][2]=%d %d\n",a[0][2],*(a[0]+2));//3 由a[0]得到a[0][2]
printf("a[0][2]=%d \n",*(*a+2));//3 由数组名a 得到a[0][2]
二、数组指针(行指针)
本质:是指针,只不过指针指向的内容是数组;
1.形式
存储类型 数据类型 (*数组指针变量名)[列数];
eg1:
int(*p)[10];//定义了数组指针p,p指针指向有10个int型元素的一维数组
p+1:向地址大的方向偏移1个数据类型;
eg2:
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*p)[4] = a;//初始化
int (*q)[4]; //先定义数组指针,再去赋值
q = a;
结论:
1> 二维数组中第i,j个元素的表示:(i为行:0,1,... j为列:0,1,....)
a[i][j] p[i][j] *(*(a+i)+j) *(*(p+i)+j)
2> 二维数组中第i,j个元素的地址表示:(i为行:0,1,... j为列:0,1,....)
&a[i][j] &p[i][j] *(a+i)+j *(p+i)+j
练习:
使用行指针实现二维数组中各个元素之和;
三、指针数组
本质:是数组,只不过数组中各个元素是指针;
1、形式
存储类型 数据类型* 数组名[元素个数];
eg1:
int *a[5];//定义了一个有5个元素的指针数组a,每个元素的数据类型为int *
int i,j,m,n,k;
a[0] = &i;
a[1] = &j;
a[2] = &m;
a[3] = &n;
a[4] = &k;
eg2:
int i,j,m,n,k;
int *a[5]={&i,&j,&m,&n,&k};//定义了一个有5个元素的指针数组a,每个元素的数据类型为int *
eg3:指针数组操作二维数组
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *b[3] = {a[0],a[1],a[2]};
总结:
一维数组名相当于一级指针;
二维数组名相当于行指针;
指针数组名相当于二级指针;
四、多级指针变量
1.多级指针概念
指向指针变量的指针变量,叫多级指针变量;
eg:
int **p;
2.一级指针变量
指向处理数据的指针变量称为一级指针变量,简称一级指针;
eg:
int i = 10;
int *p = &i;//p为一级指针变量
3.二级指针变量
指向一级指针变量的指针变量,叫二级指针变量;
eg:
int i = 10;
int *p = &i;
int **q = &p;//q为二级指针
4.二级指针变量的形式
存储类型 数据类型 **指针变量;
eg:
int i = 10;
int *p = &i;
int **q = &p;//q为二级指针
printf("%d\n",*p);
printf("%d\n",**q);
五、void型指针
1.不确定数据类型的指针;
2.形式
void *指针变量名;
eg:
void *p;//p是不确定数据类型的指针;
3.运算
对于void型的指针变量,实际使用时,一般需通过强制类型转换才能使void型指针变量得到具体变量或数组地址。
在没有强制类型转换之前,void型指针变量不能进行任何指针的算术运算。
注意:
可以将任意数据类型的指针赋给void型指针;
绝不可以将void型指针赋给确定数据类型的指针;
练习:
void型指针变量一维数组;
int a[10] = {1,2,3,4,5,6,7,8,9,10};
void *p = a;
int i;
for(i=0;i<10;i++)
printf("%d ",((int *)p)[i]);
六.const 指针
1.形式
1> const 修饰指针指向空间的值
const 数据类型 *指针变量名;
等价:数据类型 const *指针变量名;
含义:
不能通过指针变量去修改指针变量指向空间的值,但变量本身的值可以被修改;
eg:
int i = 10;
const int *p = &i;//
*p = 20;(×)//不能通过指针变量修改指针变量指向空间的值;
i = 20;(√)
2> const 修饰指针本身
形式:
数据类型 * const 指针变量名;
含义:
不能修改指针的指向,但可以通过指针修改指针指向空间的值;
eg:
int i,j;
i = 20;
j = 30;
int * const p = &i;
p = &j;(×)//不能修改指针变量p的指向
*p = 50;(√)
3> const 既修饰指针指向空间的值又修饰指针变量本身
形式:
const 数据类型 * const 指针变量名;
含义:
既不能通过指针变量修改指针变量指向空间值,也不能修改指针的指向;
eg:
int i,j;
i = 20;
j = 30;
const int * const p = &i;
i = 30;(√)
*p = 30;(×)//不能通过指针变量修改指针变量指向空间的值
p = &j;(×)//不能修改指针的指向