指针:
1)定义:
地址:内存的基本单位是字节,每个字节都有一个相应的编号,这个编号就是地址。
指针:地址
指针变量:用来保存指针的变量
2)格式:
存储类型 数据类型 *指针变量名 = 地址量;
int a;
int *p = &a;
3)运算符:
*:取地址的内容
&:取变量的地址
直接访问:a &a
间接访问:*p p
4)修饰:
a.const:
const int *p;指针指向的内容不能修改,指针的指向可以修改
int * const p;指针指向的内容可以修改,指针的指向不可以修改
const int * const p;指针的指向和指针指向的内容都不可以修改
b.void:
任意类型的指针,void *p;
在使用时需要强制转换。(强制转换的类型)变量名;
int a = 10;
void *p = &a;
printf("%d\n", *(int *)p);
5)小端存储:低地址存放的是低字节数据
大端存储:低地址存放的是高字节数据
2.指针与一维数组:
直接访问:
元素:a[i] – *(a+i)
地址:&a[i] – a+i
间接访问:
元素:p[i] – *(p+i)
地址:&p[i] – p+i
注意:指针和数组在访问数组元素时,一定条件下具有相同的形式,因为两者都是地址量,
但两者又有本质的区别,数组名是地址常量,不能进行a++(a = a+1)操作,而指针是地址变量,可以进行p++操作。
3.指针与二维数组:
元素:a[i][j] – (a[i]+j)–(*(a+i)+j)
地址:&a[i][j] – a[i]+j – *(a+i)+j
(a+i):相当于对行地址降级为列地址操作,(a+i)+j:可以找到每一个元素的地址
表示第i+1行的首列地址
4.指针数组:
1)定义:本质是数组,数组里的元素是指针,它可以简称为“存储指针的数组”
2)格式:存储类型 数据类型 *指针数组名[下标]; //记忆窍门:跨越一维数组的经度。
int *p[3];p:是指针数组名,3是指指针数组有3个元素
3)int a[2][3] = {1, 2, 3, 4, 5, 6};
int p[2] = {a[0], a[1]};
直接访问:
元素:a[i][j] – (a[i]+j)–((a+i)+j)
地址:&a[i][j] – a[i]+j – *(a+i)+j
间接访问:
元素:p[i][j] – *(p[i]+j) – ((p+i)+j)
地址:&p[i][j] – p[i]+j – (p+i)+j
4)大小:4下标
5.数组指针:
1)定义:本质是一个指针,指向一个特定位数的数组,它简称为“指向数组的指针”
2)格式:存储类型 数据类型 (*数组指针变量名)[下标];
int (p)[3]; p:数组指针变量名,3:跨越数组的维度
3)直接访问:
元素:a[i][j] – (a[i]+j)–((a+i)+j)
地址:&a[i][j] – a[i]+j – *(a+i)+j
间接访问:
元素:p[i][j] – *(p[i]+j) – ((p+i)+j)
地址:&p[i][j] – p[i]+j – *(p+i)+j
4)大小:4字节
指向一维数组时:
main()
{
int a[5],i,*pa;
pa=a;
for(i=0;i<5;i++)
{
*pa=i;
pa++;
}
pa=a;
for(i=0;i<5;i++)
{
printf("a[%d]=%d\n",i,*pa);
pa++;
}
}
指向二维数组时:
设二维数组a[m][n];
定义方法:(*指针变量名)[长度]即(*p)[n]=a;//p=a;
“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数。
5.二级指针:指向指针的指针
格式:存储类型 数据类型 **指针变量名;
int **q;(q存储指针,*q指向该地址内容(还是地址))