文章目录
一、指针的概念
指针就是一个变量,只不过这个变量比较特别,是用来存放地址的,而地址是计算机内部唯一标识的一块内存空间,即:地址是存储空间的编号!;其实忽略这个变量的特殊性(表示地址),那么它就和其他变量没什么区别,都是变量,都存储了一个值,仅此而已!
指针的大小是固定的4bit(32位操作系统)或者8bit(64位操作系统);
指针是有类型的,指针的类型决定了:
(1) 指针解引用的权限有多大:
例如:char * 类型的指针只能解引用一位,即只能访问一个字节,int* 类型可以解引用四位,即可以访问四个字节。
(2)指针加减整数时,能走多远,即在内存中移动几个字节;
例如:char* +1时,地址加1;int* +1时,地址加4;
二、野指针
1. 概念:
野指针就是指针指向的位置是不可逆的,是随机的、不正确的、没有明确限制的;
2. 为什么会出现野指针?
(1) 指针未初始化:
如:int *p;// 定义指针却没初始化 *p = 3;
(2)指针越界访问:
如:int arr[7] = {0}; int* p = arr; int i = 0; for(i =0;i<12;i++) { *(p++) = i; //当i=11时,发生越界访问; }
(3)指针指向的内存空间提前已经释放了
注:这里在动态内存开辟是在详解!
3. 如何避免野指针的出现?
(1)指针定义时就初始化;
(2)避免指针越界;
(3)指针指向的空间释放时即立刻设置为NULL;
(4)指针使用前检查一下有效性;
(5)避免返回局部变量的地址;
三、指针类型总结
3.1字符指针
1. 定义:指向字符类型的指针变量;如:char*
2. 使用方法:方法一:
int main() { char ch = 'w'; char *pc = &ch; *pc = 'w'; return 0; }
方法二:
int main() { const char* p ="hello world"; //这里是指针p指向字符串的首字母的地址 printf("%s\n",p); return 0; }
3.2指针数组
1. 概念:指针数组是一个存放指针的数组;
2. 问:指针数组是指针还是数组?答:数组,是存放指针的数组;如同我们所学的整型数组,字符数组相似,指针数组在内存的的存放是指针,即某个变量的地址;
例如: int* arr[10] = {0}; //整型指针数组 char* arr2[10] = {0}; //字符指针数组 char** arr3[10] = {0};//二级指针数组
3.3数组指针
1. 概念:数组指针是一个指向数组的指针;
- 问:数组指针是数组还是指针?
答:指针,是指向数组的指针;如同之前的字符指针和整型指针类似,数组指针是指向一个数组,存放的是数组的地址;
例如:
int * p[10]; //这是一个整型指针数组,是一个指针数组,是装着指针的数组;
int(*p2)[10]; //这是一个数组指针, * 号先和p2结合,说明了p2是一个指针变量,然后指向一个大小为10的数组;所以p2先是一个指针,一个指向数组的指针;
3.4指针函数
- 概念:指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
- 举个例子:
int *test (int x,int y);
简单点说:指针函数就是比平常的函数相比就多了一个*;其返回值是一个 int 类型的指针,即返回一个地址。简单来说,指针函数和普通函数也没有多大区别,只不过指针函数返回的是一个地址,仅此而已!
3.5函数指针
- 概念:函数指针,简单点说,就是一个指针,只不过这个指针指向一个函数,仅此而已!
- 举个例子:
int (*test)(int x,int y)
;
简单点说:*先和test结合表示指针,指向函数test(int x,int y);
用法:
(1)函数指针使用时就是需要把一个函数的地址赋值给它;int (*test)(int x,int y); void Test2(int x,int y); test = &Test2; //方法一 test = Test2; //方法二 注:取地址&不是必须的,因为一个函数名已经表示了它的地址;
(2)调用函数指针:
T = (*test)(); T = test(); 注:这两种方式都可以,但建议第一种; 因为第二种和普通函数没啥区别,不易区分; 而第一种就可以清楚的看到是通过指针的方式来调用;
3.6.看一段代码,想一想打印的结果是什么?
#include <stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
return 0; }
3.7.输出的是两个地址,这两个地址是 test 函数的地址 为什么呢?
请看下面代码:
void test()
{
printf("hehe\n");
}
//下面pfun1和pfun2哪个有能力存放test函数的地址?
void (*pfun1)();
void *pfun2();
解:
首先,能储存地址,那么pfun1或者pfun2就必须是指针变量,那么哪一个是指针变量呢?1.pfun1可以存放地址,因为*先和pfun1结合,则说明pfun1是指针,指针指向的是一个函数(),指向的函数无参数,返回值类型为void,是一个函数指针;
2.而pfun2则是一个指针函数,本质上还是一个函数,但它的返回值是地址;
3.8指针函数和函数指针总结
1. 指针函数,本质上还是一个函数,但它的返回值是一个地址;
2. 函数指针,本质上是一个指针,一个指向函数的指针;
四、感谢与预告
- 本次学习分享到此就结束了,如果本文对你有所帮助,请帮忙点赞+收藏,你的支持就是小编更新的最大动力!
- 看完了本文对指针有所了解了,但是不是还是不知道该怎么用?关注小编,下一篇文章小编带你深度解析指针!😘