1.普通的指针:
实际上指针就是存放地址的变量,eg:
int a=10;
int *p=&a;
拆分一下int *中的*说明p是一个指针,int是它所指向的类型;
2.字符串指针和字符串数组
char*str1="abcd";
先看这一个,这个就是一个字符串指针,它是一个常量指针,在c中才能这么定义,如果是cpp中,
它会强制要求你用 const char* str1="abcd";
这个指针是让"abcd"这个字符串的地址赋予给了str1,而它们的地址是处于静态内存区的,你是无法进行修改的。
而字符串数组,eg
char str[20]="abcd";
这个就是生成了一个空间用于存放这个字符串,这个空间中的内容是可以修改的,所以一般的str函数操作的字符串都是在操作这一个。
3.指针与数组相互联系:
int arr[10]={0};
int *p=arr;
这里的arr指的是arr数组的首元素的地址 既为arr[0]的地址;
&arr则指的是整个数组,让我们验证一下这件事:
从16进制的转换可以得知,这里跳过了40个字节,也就是10个int,说明&arr确实指向的是arr这整一个数组;说到这里,让我们拓展一下,sizeof中出现arr时,代表的也是整一个数组,
int sz = sizeof(arr) / sizeof(arr[0]);
所以我们总是会使用这种方式去求取整型数组中元素的个数;总结一下:
只有在sizeof(arr)和&arr时arr代表的是整个数组,否则都是数组首元素的地址;
这个在二维数组也是成立的,让我们来证明这件事。eg:
1:
跳过了20个字节,也就是5个int;
2:
int arr[3][5]={0};
int (*pf)[5]=arr;这里需要使用(数组指针才能够接受它的地址)
4.数组指针,指针数组等的讲解
char* arr[10]={0};
这个就是一个指针数组(也就是存放指针的数组),char* 代表了是一个char类型的指针,[10]说明了是一个数组;为什么不是数组指针呢?因为数组指针是长这样的 char (*arr)[10](一般是用于处理二维数组比较常用);上面那个是先跟数组组合的,说明是一个数组。
这里附上指针数组使用的例子,数组指针容易错误使用的例子和正确使用的例子。
1.指针数组的使用例子
打印的那个也可以换成arr[j][i]也没有关系,相当于模拟了一个二维数组的效果;
2.数组指针的错误使用
3.数组指针的正确使用例子
5.函数指针
5.1简单介绍
void add(int a,int b){
return a+b;
}
int (*pf)(int a, int b)=add;
这里相当于定义了一个函数指针,让add函数的首地址赋值给了pf,(*pf)()这个格式说明了是一个函数指针,但是有一点要注意的就是在调用的时候,可以不用解引用符号,pf(2,3)即可,为什么呢?因为你没发现函数在调用的时候也是add(2,3)吗,但是如果为了思维上更严谨,你当然也可以加
既 (*pf)(2,3)注意要用括号;
5.2函数指针在函数声明方面的引用
void (*(*pf)(int a,void (*)(int a)))(int a)
这个是个函数指针,怎么看呢?
A=(*pf)(int a,void (*)(int a))
首先把 void(*A)()
这样你是不是就看出来了呢
怎么理解这件事情呢?请看下面
typedef void(*)(int a) pf_t 这样重命名是错误的,要用下面的方式
typedef void(*pf_t)(int a); 既把void(*)(int a) 简化为pf_t
pf_t (pf(int a,pf_t)
与 int add(int a, int b)这样的函数声明是不是就能联系上了呢?