前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C】指针——知识点大全(详细,简洁,含例题)

【C】指针——知识点大全(详细,简洁,含例题)

作者头像
YY的秘密代码小屋
发布2024-01-22 20:28:09
发布2024-01-22 20:28:09
22200
代码可运行
举报
文章被收录于专栏:C++系列C++系列
运行总次数:0
代码可运行

前言:大家好,这里是YY;此篇博客主要是指针的知识点;包含【一二级指针】【字符指针】【指针数组】【数组指针】【以上知识的实际应用】【函数指针】【函数指针数组】

PS:创作不易,每个知识点都有例题或者图帮助理解;如果对你有帮助,希望能够得到您的关注,赞,收藏,谢谢!

一.指针的基本概念

  1. 指针就是个变量,用来存放地址(地址唯一标识一块内存空间)
  2. 指针的大小是固定的4/8个字节(32位平台/64位平台)
  3. 指针是有类型的,指针的类型决定了“指针的+-整数的步长”,以及解引用时候的权限
  4. 指针之间存在运算

二.理解一级指针,二级指针

指针:即一个指针变量指向一份普通类型的数据,因为指针保存了那个数据的地址,可以通过解引用找到它(p1找到a)

一级指针图示:


2.二级指针传参

二级指针:即一个指针变量指向指针,因为指针保存了那个数据的地址,可以通过两次解引用找到它(p2解引用找到p1,再解引用找到a)

二级指针图示:


精华.二级指针的实际应用场景: 链表的增删查改(逐步探究)

我们可以观察如图所示的情况: 说明:

  • pphead是函数SLPushBack中接收plist地址的指针
  • 函数SLPuchBack实现的是尾插功能,tail指针变量存储尾指针newnode是malloc一个新节点以后存储新节点的指针
  • 当SLPushBack()函数结束后,会返还空间,此时结构体plist再也找不到在堆上的链表
  • 解决方法:一级指针!让plist指向头指针(如果头指针不可被修改)guard
  • 但是如果头指针不是哨兵位的头节点(guard),而是可以被删除的结点呢?
  • 解决方法:二级指针!每一次调用函数,都会把plist指向头指针

三.字符指针


1.字符指针指向常量字符串

字符指针指向常量字符串原理:指针指向字符串首元素的地址

理解图示:

PS:为满足“常量字符串不可修改”,需改进:“指针前加上const”


*加上const后的数据在内存中存储的情况

编译器从内存优化的角度处理,数据只会存放到同一个地址


2.利用字符指针打印字符串

打印原理:打印字符串只需要首元素地址

代码语言:javascript
代码运行次数:0
运行
复制
const char*ps="abcdef";
printf("%s\n",ps);

四.指针数组

指针数组类型:类型 * [ n ]


1.应用:存储字符串组


2.应用:模拟二维数组


五.&数组名 / &数组名[ ] / 数组名

引入:我们知道arr是数组名即首元素地址,那&arr是什么?

结论:

  • 除了在sizeof()中,在&arr中,arr(数组名)指的不是数组首元素的地址
  • &arr的类型是数组指针(例:int(*pa)[10])
  • &arr[0]与arr的类型是指针(例:int*)

六.指针类型决定步长(演示)

要点:&arr取出的是整个数组的地址,+1后则跳过整个数组


七.数组指针


1.基本概念与形式

数组指针类型:int(*)[10]

代码语言:javascript
代码运行次数:0
运行
复制
int arr[10]={1,2,3,4,5};
int (*pa)[10]=&arr;  取出的是数组的地址存放到pa中,pa是数组指针变量

2.区分指针数组与数组指针

  • int*p1[10]:指针数组
  • int(*p)[10]:数组指针

3.数组指针的使用


一.(数组传参,数组形式接收)

  • 数组传参传数组名的本质:也是传首元素地址
  • 【数组的地址=首元素的地址=数组的起始位置】


二.(首元素地址传参)

PS:数组名是首元素地址:只有两个例外:sizeof(数组名)/&数组名


*三.(数组指针传参)——较繁琐,在一维数组上用的比较少


八.指针在二维数组的应用


1.常规写法(数组传参,数组形式接收)

代码图示:


2.指针写法(数组传参,数组指针形式接收)

原理:

  • *所以当二维数组的首元素+1时,直接跳过一行,来到下一行
  • *变化以后,可以视作(一维数组)首元素的地址”+j”后,访问数组

原理图示:

代码图示:


九.小总结:区分下列表达式


1.基础部分

  • int*parr1[10]:指针数组类型
  • int(*parr2)[10]:数组指针类型
  • int(*parr3[10])[5]:存放数组指针的数组

PS: int (* ) [5] 是 数组指针 类型, parr3[10] 是 数组 类型


2.拓展部分

  • (*(void(*) ( ) )0 ) ( );函数类型

  • void(*signal(int,void(*)(int)))(int);函数声明
  • 可改写为
代码语言:javascript
代码运行次数:0
运行
复制
typedef void(*pf_t)(int);

pt_f signal(int,pf_t);


十.数组参数,指针参数要点


1.一维数组传参要点


一.数组形式接收

要点:数组传参本质上传的是地址,所以不用专门创建一个数组接受——不用规定大小

代码演示:

代码语言:javascript
代码运行次数:0
运行
复制
void test1(int arr[]);
void test1(int arr[10];  均可以顺利传参
int main()
{
  int arr[10]={0};
  test1(arr);
  test1(arr);   
}

二.用指针形式接收

代码演示:

代码语言:javascript
代码运行次数:0
运行
复制
void test1(int*arr);
int main()
{
  int arr[10]={0};
  test1(arr); 
}

2.二维数组传参要点


一.数组形式接收

要点:二维数组的列不能省略,即“列”需要规定大小

代码演示:

代码语言:javascript
代码运行次数:0
运行
复制
正确写法
void test1(int arr[3][5]);
void test1(int arr[ ][5]);
错误写法:
void test1(int arr[ ][ ]); 
void test1(int arr[3][ ]); 

int main()
{
  int arr[3][5]={0};
  test1(arr); 
}

二.用数组指针形式接收

要点:必须要用数组指针接收

代码演示:

代码语言:javascript
代码运行次数:0
运行
复制
正确写法:
void test1(int(*arr)[5]);
错误写法:
void test1(int*arr);

int main()
{
  int arr[10]={0};
  test1(arr); 
}

十一.函数指针

函数指针类型:int(*pf)(int,int)


十二.函数指针数组

函数指针数组:int(* pfArr[4] )(int,int)


1.作用与使用演示:

函数指针数组作用:可以存放多个【参数相同,返回类型相同】的函数的地址

使用演示:


2. 应用场景:替代switch case语句

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.指针的基本概念
  • 二.理解一级指针,二级指针
    • 2.二级指针传参
      • 精华.二级指针的实际应用场景: 链表的增删查改(逐步探究)
  • 三.字符指针
    • 1.字符指针指向常量字符串
      • *加上const后的数据在内存中存储的情况
    • 2.利用字符指针打印字符串
  • 四.指针数组
    • 1.应用:存储字符串组
    • 2.应用:模拟二维数组
  • 五.&数组名 / &数组名[ ] / 数组名
  • 六.指针类型决定步长(演示)
  • 七.数组指针
    • 1.基本概念与形式
    • 2.区分指针数组与数组指针
    • 3.数组指针的使用
      • 一.(数组传参,数组形式接收)
      • 二.(首元素地址传参)
      • *三.(数组指针传参)——较繁琐,在一维数组上用的比较少
  • 八.指针在二维数组的应用
    • 1.常规写法(数组传参,数组形式接收)
    • 2.指针写法(数组传参,数组指针形式接收)
  • 九.小总结:区分下列表达式
    • 1.基础部分
    • 2.拓展部分
  • 十.数组参数,指针参数要点
    • 1.一维数组传参要点
      • 一.数组形式接收
      • 二.用指针形式接收
    • 2.二维数组传参要点
      • 一.数组形式接收
      • 二.用数组指针形式接收
  • 十一.函数指针
  • 十二.函数指针数组
    • 1.作用与使用演示:
    • 2. 应用场景:替代switch case语句
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档