【C语言进阶】④指针归纳总结,这些指针你都认识吗?

一、指针的概念
  1. 指针就是一个变量,只不过这个变量比较特别,是用来存放地址的,而地址是计算机内部唯一标识的一块内存空间,即:地址是存储空间的编号!;其实忽略这个变量的特殊性(表示地址),那么它就和其他变量没什么区别,都是变量,都存储了一个值,仅此而已!

  2. 指针的大小是固定的4bit(32位操作系统)或者8bit(64位操作系统);

  3. 指针是有类型的,指针的类型决定了:

(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. 概念:数组指针是一个指向数组的指针

  1. 问:数组指针是数组还是指针?

答:指针,是指向数组的指针;如同之前的字符指针和整型指针类似,数组指针是指向一个数组,存放的是数组的地址;

例如:
int * p[10]; //这是一个整型指针数组,是一个指针数组,是装着指针的数组
int(*p2)[10]; //这是一个数组指针, * 号先和p2结合,说明了p2是一个指针变量,然后指向一个大小为10的数组;所以p2先是一个指针,一个指向数组的指针

3.4指针函数
  1. 概念:指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
  2. 举个例子:
    int *test (int x,int y);
    简单点说:指针函数就是比平常的函数相比就多了一个*;其返回值是一个 int 类型的指针,即返回一个地址。简单来说,指针函数和普通函数也没有多大区别,只不过指针函数返回的是一个地址,仅此而已!
3.5函数指针
  1. 概念:函数指针,简单点说,就是一个指针,只不过这个指针指向一个函数,仅此而已!
  2. 举个例子:
    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. 函数指针,本质上是一个指针,一个指向函数的指针;

四、感谢与预告
  1. 本次学习分享到此就结束了,如果本文对你有所帮助,请帮忙点赞+收藏,你的支持就是小编更新的最大动力!
  2. 看完了本文对指针有所了解了,但是不是还是不知道该怎么用?关注小编,下一篇文章小编带你深度解析指针!😘
  • 43
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白杨Cc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值