要说指针首先要说什么是指针,在C语言中指针可以理解为地址,即指针==地址,而我们口头上说的指针实际上是指针变量. 接着我们还要介绍一点前言就是,也就是最简单的一些代码.那么看下面这段代码
首先看&操作符,这是取地址操作符,就是把a的地址取出来,放到指针变量p里面,p左边的int*,其中 * 在说明p是指针变量,int说面p指向整型类型的对象.
那么要是char类型的要怎么写呢?代码如下
指针的分类
1.void* 指针
viod*指针,可以理解为无具体类型的指针,可以接收任意类型的地址,当然不会有完美的东西,野指针缺点是不能进行指针的加减整数和解引用.指针的加减整数在后面会讲,现在知道有这回事就行了.
2.野指针
野指针就是指针指向的位置是不可知的.
造成野指针的原因如下
1.指针未初始化
2.指针越界访问
3.指针指向的空间释放
那么怎么规避野指针其实很简单
1.初始化指针
2.小心指针越界
3.指针变量不使用时,及时置为NULL,使用之前检查有效性.有一个规定就是,只要指针置为NULL,指针就不会去访问.
下面的代码很好诠释了规避野指针的第三条
因为野指针指向的位置是位置的,所以在使用时要极为小心,不使用时及时置为NULL.
3.数组指针变量(包括指针数组)
说到数组指针变量,那要先说指针数组.从字面意思理解指针数组是数组,是存放指针的数组,语法是 int *p1[5] 这就是一个指针数组如下图
我们来看一段代码理解一下指针数组(指针数组模拟实现二维数组)
这里提一下,数组名就是首元素地址,这里的ptr存的是arr1,arr2,arr3,首元素的地址.如果你是刚接触指针,上面的代码可能看不懂,别着急,接着往下看,先知道有这个东西.
那么接下来说数组指针,数组指针从字面意思来看是它不是数组而是指针变量,存放的是数组的地址,能够指向数组的指针的变量.语法为 int (*p2)[10]
下面解释一下:
p先和*结合,说明p是⼀个指针变量变量,然后指着指向的是⼀个⼤⼩为10个整型的数组。所以p是⼀个指针,指向⼀个数组,叫数组指针。
数组指针初始化下图 :
数组类型解析如下图:
知道数组指针后那么就可以理解二维数组传参的本质了;
二维数组可以看为每个元素是一个一维数组,也就是说二维数组没个元素是一个一维数组,那么二维数组的首元素就是第一行,一个一维数组如下图:
所以根据数组名是首元素地址,二维数组的数组名就是第一行的地址,是一个一维数组的地址,所以第一行的地址类型就是数组指针类型为int (*)arr[5].
那么可以用该方法打印一个二维数组代码如下:
#include <stdio.h>
void test(int (*p)[5], int r, int c)
{
int i = 0;
int j = 0;
for(i=0; i<r; i++)
{
for(j=0; j<c; 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}};
test(arr, 3, 5);
return 0;
}
那么还有一个函数指针变量,下次再说.