1. 指针类型决定了指针进行解引用操作时,能够访问空间的大小
int* p;*p能够访问4个字节
char* p;*p能够访问1个字节
double* p;*p能够访问8个字节
2. 指针类型决定了:指针向前或向后走一步走多远(指针的步长)
int* p; p+1 --->4
char* p; p+1 --->1
double* p; p+1 --->8
3. 野指针:指针指向的位置是不可知的(随机、不正确、没有明确限制的)
(1)指针未初始化。局部变量不初始化,默认是随机值,则局部的指针变量就被初始化为随机值。
(2)指针访问越界。当指针指向的范围超出数组的范围时,越出的指针就是野指针。
(3)指针指向的内存空间被释放。
4.如何避免野指针?
(1)指针初始化
(2)小心指针越界
(3)指针指向空间释放即使置NULL
(4)指针使用之前检查有效性
5. 指针减去指针,得到的是中间的元素个数(前提是大地址减去小地址)
6. 打印数组名与打印数组首元素的地址结果相同
(1)&arr —— &数组名- 数组名不是首元素的地址 - 数组名表示整个数组
&数组名 取出的是整个数组的地址
arr+1——第二个元素(下标为1)地址
&arr+1——跳过整个数组之后的地址
(2)sizeof(arr) —— sizeof(数组名) - 数组名表示的整个数组
sizeof(数组名) 计算的是整个数组的大小
7. 指针数组是指针还是数组?
是数组。存放指针的数组。
int arr[10]={0}; 整形数组
char ch[5]={0}; 字符数组
int* parr[4]; 存放整形指针的数组 - 指针数组
int* pch[5]; 存放字符指针的数组 - 指针数组
8. 数组指针是数组还是指针?
是指针。
int* p=NULL;p是整形指针 - 指向整形的指针 - 可以存放整形的地址。
9. int arr[5];整型数组,每个元素是整形类型,有5个元素
int *parr1[10] 指针数组,首先parr1先和[]结合,是一个数组,有10个元素,每个元素是int*
int (*parr2)[10] 数组指针,parr2先和*结合,是指针,指针指向数组,数组每个元素是10
int (*parr3[10])[5]; parr3[10]是一个数组,它的每个元素是一个数组指针
10. int main {
int arr[3][5]={0};
test(arr); //数组名为数组首地址,该首地址是一维数组arr[1][5]的地址
}
× void test(int *arr){} //整型类型的指针,只能存放整型的地址 ,不能存放一维数组的地址
× void test(int *arr[5]){} //arr先和[]结合为数组,指针数组为存放指针的数组,每个数组的类型 为int*,不能存放一维数组的地址
√ void test(int (*arr)[5]){} // arr先和*结合,为指针,数组指针用来存放数组的指针,一个数组 为5个元素,每个元素为int型
× void test(int **arr){} //二级指针,用来存放一级指针的地址,不能存放一维数组的地址
11. 函数指针,用来存放函数的指针
&函数名 和 函数名 都是函数的地址
12. 数组是一个存放相同类型数据的存储空间,要把函数的地址存到一个数组中,那这个数组就叫函数指针数组。
13.回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其他所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用,用于对该事件或条件进行响应。
14. int main()
{
int arr[10] = {0};
int (*p)[10]= &arr;//取出数组的地址4
int(*pf)(int,int);//函数指针
int(*pfArr[4])(int,int);//pfArr是一个数组-函数指针的数组
//pfArr是一个指向 [函数指针数组] 的指针
int(*(*ppfArr)[4])(int,int)=&pfArr;
//ppfArr是一个数组指针,指针指向的数组有4个元素,每个元素类型是int(*)(int,int)
return 0;
}
15. int sum (int x , int y)
{
return x+y;
}
int main
{
//指针数组
int* arr[10];
//数组指针
int* (*pa)[10]=&arr;
//函数指针
int (*pAdd)( int , int) = sum; //*pAdd是指向函数的指针,输入两个变量的参数类型是 int,返回值类型为int
//函数指针的数组
int (*pArr[10]) ( int , int);
//指向 [函数指针数组] 的指针
int(* (*ppArr)[10]) (int , int) = &pArr;
}
16. qsort - 快速排序 - 库函数
17. void* 类型的指针 可以接收任意类型的地址
void* 类型的指针 不能进行解引用操作
void* 类型的指针 不能进行+-整数的操作,因为不知道接收的类型是什么,所以不能确定+-多少个字节。
18. 字符串比较,不能直接用> < =比较,要用strcmp函数
19. 指针类型的意义:
1.指针类型决定了指针解引用操作符能访问几个字节
eg. char* p; *p访问了一个字节。int* p; *p访问了4个字节。
2. 指针类型决定了指针+1-1时,加或减几个字节。
eg. char* p; p+1跳过一个字节。int* p; p+1跳过四个字节。
20. 在内存中的数字用4个字节表示,32个bit,使用二进制表示。4个二进制转化为一个16进制,两个16进制为一个字节,不论大端存储还是小端存储,两个16进制表示的字节顺序不能反。