指针的主题:
指针就是一个变量,用来存放地址,地址唯一标识一块内存空间。
指针的大小时固定4/8字节(32位平台/64位平台)
指针是由类型的,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限
指针的运算
字符指针:
char*
一般用法如下:
char ch = 'w';
char* pc = &ch;
还有一种用法:
const char* p = "abcdef";
后面的常量字符串赋值给这个字符整型的指针,但是常量字符串出现时,这个常量字符串的值是常量字符串的首字符的地址,也就是说以上这条代码,是将a的地址传给p这个指针变量。
因为常量字符串是不能被修改的,所以在这个指针变量前要加一个const。
#include <stdio.h>
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
char *str3 = "hello bit.";
char *str4 = "hello bit.";
if(str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
str1和str2是两个数组,数组的操作方式是将右边常量字符串的内容拷贝进来,所以他们是两个空间,只是内容相同,所以str1 != str2。而str3和str4是两个指针,编译器在处理的时候,会将相同的常量字符串做成同一个地址,所以,str3和str4指向的是同一个常量字符串,所以str3 == str4。
指针数组:存放指针(地址)的数组
int* arr1[10];//整型指针的数组
char *arr2[4];//一级字符指针的数组
char **arr3[5];//二级字符指针的数组
数组指针:存放数组地址的指针---指向数组的指针.
int (*p)[10];
解释:p先和*结合,说明了p是一个指针变量,然后指向的是一个大小为10个整型的数组,所以p是一个指针,指向一个数组,叫数组指针。
PS:[ ]的优先级是高于*的,所以一定要加上()来保证p先和*结合
&arr和arr的区别:
数组名---数组首元素的地址
&数组名---拿到的是数组的地址
数组首元素的地址和数组的地址从值的角度来看是一样的,但是意义不一样
二维数组的传参:
二维数组传参,函数形参的设计只能忽略第一个[ ]的数字,因为对一个二维数组,可以不知道有多少行,但是必须要知道一行有多少个元素,这样才方便运算
函数指针:指向函数的指针
int Add(int x, int y)
{
return x + y;
}
int main()
{
int (*pf)(int, int) = &Add;
return 0;
}
诸如此类。
PS:&函数名和函数名都是函数的地址
int (*pf)(int, int) = &Add;
int (*pf)(int, int) = Add;
以上两条代码的意义是一样的。
函数指针数组:存放函数指针的数组
主要用途:转移表
int(*parr1[10])(int,int)就是一个函数指针数组,parr1先和[ ]结合,说明parr1是数组,数组的内容是int(*)(int,int)的函数指针
回调函数:
回调函数就是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指的函数时,我们就说这是回调函数,回调函数不是由该函数的实现方直接调用,而是在特定的时间或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。