目录
一.什么是指针?
指针其实就是个变量,这个变量里面存放地址。
但是指针是有类型的,不同的指针类型决定了指针加减整数移动的步长。
我们来看一段代码
如果是char类型呢
所以,你看,不同的指针类型决定了指针加减整数时候移动的步长
double*改变的则是八个字节,我们可以自己去验证一下。
二.指针类型
2.1字符指针
字符指针的类型一般为“ char* ”。
这里是打印的结果:
那么我们来验证一下pc里面存放的是不是pc的收元素的地址呢?
那我们接下来,来看两串代码打印的结果如何?
打印结果:
为什么呢?
画张图来看看他们之间的关系吧
从图上我们可以看出,arr1和arr2是不同的两块内存,而p1,p2则指向了同一块内存。当然了,这段常量字符穿在内存中存储的时候最后面是‘\0’。
2.2 指针数组
指针数组是个什么鬼东西?
它其实是一个数组,用来存放指针的,而指针也就是一个地址变量嘛。
整型指针数组,用来存放整形指针;字符指针数组,用来存放字符指针。
来看一组代码:
这串代码我们重点要搞清楚,arr1,arr2,arr3是怎么放在parr里面的?
打印的时候,i,j分别控制三行六列,parr[i]找到某一行的首元素地址,+j表示向后移动几个单位,顺利找到arr1-3的地址,解引用操作,并将其打印出来。
2.3 数组指针
什么是数组指针?
这里要和指针数组区分开来,指针数组是一个数组,数组里面存放了指针(也就是地址,整形指针,字符指针什么的);
而数组指针它首先是个指针,是一个指向数组的指针,它可以存放一个数组的地址(这是区别)。
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int(*p) [10] = &arr; //p就是数组指针
//含义:一个指针p ,指向一个数组,数组里面有十个元素,每个元素的类型是int
这里的p如果不加括号(*p),那么p就会先和[]结合,形成一个数组。
这也是指针数组和数组指针写法上的一个差异,要格外注意,加以区分。
2.3.1数组指针怎么用?
数组指针一般要涉及到二维数组以上使用才会带来便利。
来看一组代码
void Print1(int arr[3][5], int x, int y)
{
int i = 0, j = 0;
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void Print2(int(*p)[5], int x, int y)
{
int i = 0;
for (i = 0; i < x; i++)
{
int j = 0;
for (j = 0; j < y; j++)
{
//printf("%d ",*(*(p + i) + j));
printf("%d ",p[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, { 3, 4, 5, 6, 7 } };
Print1(arr, 3, 5);
printf("\n");
Print2(arr, 3, 5);
return 0;
}
代码的分析:
接下来我们来看一看这样一组代码是什么意思
int(* pa[10] )[5]
我们来分析一下这个东西~
2.4 数组参数,指针参数
2.4.1一维数组的传参
我们如果想要把数组或者指针传给函数,那么参数部分该怎么正确的书写呢?
来串代码我们一起分析一下。
void test(int arr1[]) //ok?
{}
void test(int arr1[10]) //ok?
{}
void test(int *arr1) //ok?
{}
void test2(int* arr2[20])//ok?
{}
void test2(int **arr2) //ok?
{}
int main()
{
int arr1[10] = { 0 };
int* arr2[20] = { 0 };
test(arr1);
test2(arr2);
return 0;
}
先上结论,上面这些参数书写形式,是完全正确滴~
分析一下:
总结:
1. 你传来个啥,我就用个啥接待你,你可以省略掉“[]”里面的数字。(数组传参)
2.指针可以用来存放你传来的首元素地址,通过你首元素的地址找到你的余下元素;同时二级指针存放的是一级指针的地址。(指针传参)
2.4.2 二维数组的传参
上个代码一起看一下:
void test1(int[2][3])
{}
void test2(//这里面怎么写呢?)
{}
int main()
{
int arr[2][3] = { 0 };
test1(arr);
test2(arr);
}
我们一起来看一下test2 的参数怎么写才正确?
这样一跑,没有任何问题
为了更好的理解传参,我们来逆向思考一下~
如果函数 的参数是一个一级指针,那我们都可以用什么参数传给它呢?
来一起瞅瞅:
总结:
一级指针参数都可以存放什么呢?
1. 一级指针本身
2. 整型等的地址
那如果函数 的参数是一个二级指针呢,那我们都可以用什么参数传给它呢?
那还有没有什么东西可以穿给二级指针呢?
指针数组里面存放的是不是也是地址啊,存放的是数组的地址
int* arr[10];
test(arr)
这里的arr[10]数组里面存放类型都是int*(整型的地址),也就是一级指针的地址,所以它也可以传给二级指针。
总结
二级指针参数都可以接待什么:
1.二级指针本身
2.一级指针的地址
3.指针数组的地址(本质也是一级指针,存放的是数组的地址)
套娃篇 未完待续..