一级指针:存放变量的地址
二级指针:存放一级指针的地址
格式:存储类型 数据类型 **指针变量名
int a=10;
int *p = &a;
int **q = &p;
访问a的值:
a *p **q
访问a的地址:
&a p *q
访问p的地址:
&p q

指针和一维数组
直接访问:按变量的地址存取变量的值(通过数组名访问)
间接访问:通过存放变量地址的变量去访问变量(通过指针访问)
1. 指针和一维数组
int a[5]={1,2,3,4,5};//a是数组名也是首地址
int *p = a;
直接访问:


a和p本质上不同,a是地址常量,p是变量,a不能执行++操作,但是p可以
访问数组元素a[i]的值:
直接访问:a[i] *(a+i)
间接访问:p[i] *(p+i)
访问数组元素a[i]的地址:
直接访问:&a[i] a+i
间接访问:&p[i] p+i
2. 指针和二维数组
int a[2][3]={1,2,3,4,5,6};//a:数组名,表示第一行首地址,a+1:第二行首地址
在a前面加*,表示将行地址降级成为列地址
*a://第一行第一列的地址
*a+1//第一行第二列的地址
*(a+1)//第二行第一列的地址
*(a+1)+1//第二行第二列的地址

访问数组元素地址(a[i][j]的地址)
&a[i][j] *(a+i)+j a[i]+j
访问数组元素值:
a[i][j] *(*(a+i)+j) *(a[i]+j)
3.数组指针
定义:本质是指针,指向的是数组(又称为行指针)
格式:存储类型 数据类型 ( * 指针变量名) [列数]
int a[2][3]={1,2,3,4,5,6};
int (*p)[3] = a;
p:int (*)[3];运算要3个3个运算
p可以代替a进行元素访问,但是本质不同
访问a[i][j]地址:
*(p+i)+j p[i]+j
访问a[i][j]内容:
*(*(p+i)+j) *(p[i]+j)
大小?
sizeof(p)=4;
4.指针数组
1)定义:本质是数组,里面存放的是指针
2) 格式:存储类型 数据类型 *数组名[元素个数]
int *arr[2];
应用示例:
1) 用于存放普通变量的地址
int a=10,b=20,c=30;
int *p[3]={&a,&b,&c};
访问b的值:
*p[1] *(*(p+1))
访问b的地址;
p[1] *(p+1)

2) 用于存放二维数组的每行第一个元素的地址(列地址)
int a[2][3]={1,2,3,4,5,6};
int *p[2]={a[0],a[1]};
访问a[1][2]的值:
*(p[1]+2) *(*(p+1)+2)
访问a[1][2]的地址:
p[1]+2 *(p+1)+2
sizeof(p)=8;//因为p中包含了两个指针
3)用于存放字符串
char *p[3]={"hello","world","hqyj"};
打印"world"字符串
printf("%s\n",p[1]);
printf("%s\n",*(p+1));
打印’d’这个字符:
printf("%c\n",*(p[1]+4));
printf("%c\n",*(*(p+1)+4));
//printf("%c\n",p[1][4]);
4)命令行参数
int main(int argc, char const *argv[])
{
printf("%s\n",argv[0]);
}
argv:就是一个指针数组,里面存放的是命令行传递的字符串
argc:表示argv指针数组里面存储数据的个数,即命令行传递字符串的个数