一.野指针和悬空指针
1.定义
野指针;指针指向的空间未分配
悬空指针;指针指向的空间已分配,但是被释放了
2.举例
由int *p2=p1+1,p2为野指针,因为p1+1所代表的地址所存放的数据未知(野指针)
int*p3=method(num,p); 此处的p3为悬空指针,因为此处的p3记录的地址是method函数中的局 int*method(){ 部变量num,函数调用过后,
int num=10;
int*p=#
return p;
}
二.二级指针
1.二级指针的定义
int a=10; 一级指针
int*p=&a;
int**pp=&p; 二级指针
*pp表示解引,得到的结果是一级指针,**p表示对一级指针解引 ,得到的结果是一个具体的数值
2.二级指针的修改
*pp=&b;(更改*pp的一级指针&a为&b)
三,数组和指针
1.数组指针;指向数组的指针
作用;方便操作数组中的各种数据
2.举例:
int *p=arr也可以用int*p=&arr[0] 替代。
3.数组指针的细节
arr为首地址,只表示数组中第一个元素的地址(&arr则是表示整个数组的地址,也是用数组的第一个元素的地址表示;但是当arr+i(i为常数)时,移动的步长为数据类型的字节数,比如int是4,当&arr+i时,移动的步长字节数为数据类型表示的字节数*i)。
四.二维数组
1.定义;把多个小数组,放到一个大的数组里
2.定义格式:
m:表示二维数组的长度
n:表示每一个一维数组的长度
第一种定义格式: 第二种定义格式:
数据类型 arr[m][n]={ int arr1[3]={1,2,3};
{1,2,3,4,5}, int arr2[5]={1,2,3,4,5};
{1,2,3,4,5}, int arr3[9]={1,2,3,4,5,6,7,8,9};
{1,2,3,4,5} int*arr[3]={arr1,arr2,arr3};
};
调用元素方式:arr[m][n],比如arr[1][1]表示二维数组中的第二个数组中的第二个元素。
2.利用索引遍历第一种格式的二维数组
举例
3.利用索引遍历第二种格式的二维数组
二维数组的定义格式二:事先把所有的一维数组定义完毕,再放入二维数组
举例
错误操作:使用int len=(sizeof(arr[i]))/(sizeof(int))得到数组长度:arr[i]是二维数组中的指针,所以用sizeof取长度并且printf("%d\n",len)的话,答案是指针的长度,在64位系统中,指针占8个字节,除以int的4个字节后,输出为2 。
4.利用指针遍历第一种格式的二维数组
举例:
注:定义一维数组的指针:int[5]*p=arr ==> int(*p)[5]
int[5]*p=arr表示定义一个指向数组arr中的第一个一维数组的地址
*p+1则表示遍历一维数组中的每一个元素,移动步长为1,4个字节
p++表示遍历二维数组,每一次移动一个步长,4*5=20个字节
5.利用指针遍历第二种格式二维数组
举例:
注:使用二维数组:*p为指针型,*p的初始值为arr数组的第一个一维数组的指针
*p是一维数组的地址,但是使用时退化为一维数组的第一个元素的地址
五.数组指针和指针数组
数组指针;本质上是指针。作用;方便操作数组中的各种数据
举例:int*p=arr 步长:int 4
举例:int (*p)[5]=&arr 步长:int 乘5(20字节)
指针数组:用来存放指针的数组。作用:用来存放指针
举例:int*p[5],这个数组里面存放着int类型的指针
六.函数指针
1.格式:返回值类型(*指针名)(形参列表)
注:形参列表中只有数据类型,没有变量名 ,如:int(*p)(int,int)=method1;
作用:利用函数指针,可以动态地调用函数
2.举例:
3.练习
定义加,减,乘,除四个函数,用户键盘录入三个数字,前两个表示参与计算的数字,第三个数字表示调用的函数
1;加法;2;减法;3;乘法;除法
函数指针数组:数据类型(*指针数组名[数组大小])(参数列表)
注;只有形参完全相同而且范湖职业一样的函数,才能被放到同一个函数指针数组