Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >指针的深入解读笔记

指针的深入解读笔记

作者头像
发布于 2024-04-30 13:14:22
发布于 2024-04-30 13:14:22
1170
举报
文章被收录于专栏:转自CSDN转自CSDN

指针是什么

指针是指向内存单元的编号(地址),可以快速访问地址,加快程序运行速度.

在指针中一般用到两个操作符:

* 解引用操作符 也是定义指针时候的操作符

int *p;//定义一个类型为 int 的 指针 *p = 0;解引用p指向的地址 并且赋值为0

& 取地址操作符

int a; int *p; p = &a;//把a的地址给p

int * p 中 *说明p是指针变量 int 说明 p 指向的类型是整型

而且p中存储的是地址 *p是解引用p指向了 变量 也就是 p(地址) --> a(变量)

指针本身也占有大小,而且在32位平台下是4字节 64位平台下是8字节 而且指针大小与它所指向的东西无关,只于它运行的平台有关

指针类型意义

指针变量的类型虽然与大小无关,但是却决定每次或下次访问时访问的字节大小有关

比如char*类型的指针,每次只访问一个字节

int*类型的指针,每次访问四个字节

而且它也决定 与 + - 运算时访问字节的大小 也就是指针的类型决定了指针向前或者向后走一步有多大距离.

比如char*类型的指针每次 +1 跳过1个字节

int*类型的指针每次 +1 跳过四个字节

而且指针的地址是可以求差的,用差除去每个元素的长度可以得到两个地址之间的元素个数

而且还有一种特殊指针 void* 它是无具体类型的指针(泛型指针),这种指针可以接收任何类型的地址,但是不可以与 + - 和 解引用 因为它无法确定 步长.

一般情况下void*指针是使用在函数参数的部分,用于接收不同类型的地址,可以实现泛型编程的效果,例如

qsort使用-CSDN博客 中 qsort模拟部分

而且指针使用可以和 const(不可修改) 来修饰 而且 const的位置决定可改变和不可改变的位置

const int * p;//决定的是*p不能改变 int const *p;//同理

int * const p;//决定的是p指向的地址不可更改,但是地址包含的东西可以更改

野指针是指向未知位置的指针,一般是由于没有初始化,越界访问,指向了已经被释放的空间等.我们要规避野指针的存在,可以初始化的时候赋值NULL(空地址0) ,在使用完不使用指针的时候及时赋NULL,避免返回局部变量的地址等方法.

也可以使用assert断言 也就是assert.h的头文件包含的assert(),用于在运行时确保程序符合指定条件,如果不符合就报错并且终止运行程序

assert(p != NULL);//如果p不是空指针就报错

如果assert接收的返回值是0就回报错,不是0就继续运行,而且要关闭断言可以使用

#define NDEBUG

数组名指针

首先举个小例子

int arr[5] = {1,2,3,4,5}; int *pp = &arr[1];//取到了元素2的首地址 每次 + 1 会跳过一个元素 int *ppp = arr;//取到了数组第一个元素的首地址 每次 + 1会跳过一个元素 int *pppp = &arr;//取到了整个数组首元素地址 每次+1会跳过一个数组

我们根据例子也可以倒推如何使用指针去找元素,就和+1 -1和取得是什么类型的指针有关

printf("%d",arr[1]); printf("%d",*pp); printf("%d",pp[0]); printf("%d",*(pp+0);

这四个代码的效果是一样的 其实[]可以和*一样有解引用的功能

在本质上pp[i]和*(p+i)是等价的 同理arr[i]和*(arr+i)也是等价的

数组元素的访问在编译器处理的时候,也是转换成首元素的地址 + 偏移量 然后求出元素的地址,然后再解引用访问.

一维数组的本质

本质上素组窜惨本质上传递的是首元素(或者选择的元素)的地址,因为传过去的仅仅只是地址,所以在自定义函数里面无法直接用sizeof求出数组的大小,只能求出这个地址的大小.而且可以用指针的形式接收数组,因为是地址.

二级指针

指针变量也是变量,所以指针本身也有地址,而且这个地址也可以由其它指针接收,也就是二级指针.

int a; int *p = a; int * *pp = a;

在这种情况下 pp解引用调用p的内容(a的地址) 再对pp二次解引用才能找到a pp中存放的是p的地址 p中存放的是a的地址.

指针数组(与数组指针区分一下)

对于普通的数组 它存放的是int类型的内容

int a[5] == { int,int.......}

对于指针数组 他存放的是是int*类型的内容 也就是存放的全是地址 而且每个地址由可以单独指向一个区域

int* a[5] == { int*,int*,....}

指针数组模拟二维数组

以下两个东西是等价的

int arr[3][3];

int arr1 [3]; int arr2 [3]; int arr3 [3]; int* arr[3] = {arr1,arr2,arr3}

其中的arr的效果是相同的,而且根据 arr[i]和*(arr+i)是等价的 可以用相同的方式访问某个元素

也就是 arr[1][1] 等于 *(arr[1] + 1) 等于 *(*(arr + 1) + 1)

字符指针变量

再指针的类型中 还有 char* 的类型 ,它每次访问一个字节,可以逐字节访问

char a = 'w'; char *p = a;//那么p指向a的地址 解引用就是字符w

const char * pw ="wwww";//这个pw指向的是在内存中的字符串"wwww"的首地址 const char * pa ="wwww";//这个pa指向的首地址和pw相同

数组指针变量

int *pa[10];这个是指针数组 int (*pb)[10]; 这个是数组指针

int (*pb)[10] pa与*结合说明p是一个指针变量变量,然后指向的是一个大小为10个的整型的素组,p是指针,指向数组,所以是数组指针,( []的优先级高于*,所以要用()保证*先于P结合.

int arr[10] = {0}; int (*p)[10] = &arr;//这里的p就是arr的地址了

&arr 和 p的类型都是 int[10]*

其中 int是p指向的数组的元素类型, p是数组指针的变量名 [10]是p指向数组的元素个数

二维数组的传参本质

首先理解二维数组,二维数组可以看作是每个元素是一维数组的数组,这个数组中的每个元素都是一个一维数组,那么二维数组的首元素就是一个一维数组,取二维数组的数组名时,二维数组的数组名就是第一行的地址,取出来是一个一维数组.

第一行的地址类型是 int(*)[i],那就意味着二维数组传参本质上是传递了地址,传递的是第一行这个以为新数组的地址,那么形参也可以写成指针形式

void test(int (*p)[5]);//用这个来接收有五行的二维数组arr[5][i]

函数指针变量

在内存中创建的自定义函数本身也是有地址的,可以通过 &函数名 的方式得到函数的地址,如果我们要把函数的地址存起来,就要创建函数指针变量,函数指针变量的写法和数组指针类似

void test() { return 0; } void (*pf1)() = &text; void (*pf2)() = test; int add(int x,int y) { return x + y; } int(*pf3)(int,int) = add; int(*pf4)(int x, int y) = &add;

对于 int(*pf3)(int,int) = add; 解析 int 是pf3指向的函数的返回类型 (*pf3)是函数指针变量名

(int,int)是主席昂的函数的阐述类型和个数

这个指针的类型是 int(*)(int,int)

而且用的方法和之间用函数一样的

a = (*pf3)(1,1); a = pf3(1,1);

这两行结果相同

typedef关键字

typedef是重命名例如把 unsigned int 重命名成 unit

typedef unsigned int uint;

函数指针数组

int (*p[5])(int,int);

这是定义了一个 有五个元素,返回类型是int 参数是两个int 的 函数指针数组

类型是 int(*)(int,int)

这个结合到使用的时候也就是转移表了

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
轻松拿捏C语言——【保姆级·指针讲解】期末C语言<指针>急救包,全是干货,诚意满满!
有一栋楼,里有200个房间,假如我们要去某个房间找某个人,然后他说他在C304,我们就能通过门牌号C304快速找到他所在房间。
用户11162265
2024/06/14
1430
轻松拿捏C语言——【保姆级·指针讲解】期末C语言<指针>急救包,全是干货,诚意满满!
指针的梳理
在探讨指针之前,我们首先明确它的定义:指针是一种特殊的变量,它存储了另一个变量的内存地址。指针在编程过程中有着不可或缺的作用,不仅能提高编程的速率,指针的使用也能增加代码的灵活性,能够深入程序员对代码的理解。
用户11029103
2024/03/19
1010
指针的梳理
拿下大怪兽——指针
parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型一维数组,parr[i][j]就是整型一维数组中的元素。
用户11328191
2024/10/23
950
拿下大怪兽——指针
C语言——指针(四)
我们都知道数组中**首地址[下标]**的形式可以实现对元素的查找,其实字符串也可以用同样的形式来查找字符串中的内容。
用户11029137
2024/03/19
1090
C语言——指针(四)
指针(3)
除了二级指针,还有三级指针,四级指针,(不过三级指针,四级指针用的很少,到后面更是);
E绵绵
2024/04/08
1350
指针(3)
深入浅出C语言指针(进阶篇)
在C语言中,指针是至关重要的一部分,掌握指针的用法对于编写高效、简洁的代码具有极大帮助。本文将带您深入了解C语言指针的高级用法,助您迈向编程高手之路。
平凡之路.
2024/10/09
1590
深入浅出C语言指针(进阶篇)
指针小总结
代码输出的结果是:40,如果arr是数组首元素的地址,那输出应该的应该是4/8才对。 其实数组名就是数组首元素(第⼀个元素)的地址是对的,但是有两个例外: • sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节 • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的) 除此之外,任何地⽅使用数组名,数组名都表示首元素的地址
ljw695
2024/10/18
730
指针小总结
关于我、重生到500年前凭借C语言改变世界科技vlog.13——深入理解指针(3)
字符指针变量,顾名思义就是字符类型的指针,即 char* 常见的输出格式是这样的:
DARLING Zero two
2024/11/19
430
关于我、重生到500年前凭借C语言改变世界科技vlog.13——深入理解指针(3)
拿捏指针(二)
前面我们已经讲了,C语言的第一篇《拿捏指针(一)》,接下里我们继续深入的来了解指针。
秋邱
2024/10/09
850
拿捏指针(二)
指针(3)---不同指针变量
在这行代码中,貌似将hello bit.这个字符串放进了字符指针变量pstr中,但事实真的如此吗?
Skrrapper
2024/06/18
1010
指针(3)---不同指针变量
指针详解(二级指针、指针数组和数组指针、字符指针、二维数组传参、函数指针变量)(二)
走在努力路上的自己
2024/01/26
7630
指针详解(二级指针、指针数组和数组指针、字符指针、二维数组传参、函数指针变量)(二)
C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷三)
迷迭所归处
2025/03/20
760
C语言 —— 此去经年梦浪荡魂音 - 深入理解指针(卷三)
【C语言】(指针系列3)数组指针+函数指针+typedef+函数数组指针+转移表
答案是:指针数组是一个数组是数组,储存的是地址(首元素),数组指针是数组还是指针哪?答案是--------指针变量
用户11367452
2024/11/21
1390
【C语言】(指针系列3)数组指针+函数指针+typedef+函数数组指针+转移表
手撕指针(三)
*ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa , *ppa 其实访问的就是 pa .
用户11367247
2024/11/20
410
手撕指针(三)
C语言----深入理解指针(3)
char* p = "abcdef";//这里的赋值是讲字符串中首字符的地址存在p中
Undoom
2024/09/23
1110
c语言从入门到实战——数组指针与函数指针
数组指针和函数指针是C语言中的两种重要指针类型。数组指针指向一个数组,可以用来访问和修改数组中的元素;而函数指针则指向一个函数,可以用来调用该函数。两者在语法和用法上有所不同,需要仔细区分。正确理解和使用它们可以提高程序的效率和可维护性。
鲜于言悠
2024/03/20
1840
c语言从入门到实战——数组指针与函数指针
【C语言】指针&&二级指针&&数组指针&&指针数组详解
我们可以通过&(取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量
用户10925563
2024/06/04
1.5K0
【C语言】指针&&二级指针&&数组指针&&指针数组详解
【C语言】指针进阶:字符指针&&数组指针&&函数指针
✨作者:@平凡的人1 ✨专栏:《C语言从0到1》 ✨一句话:凡是过往,皆为序章 ✨说明: 过去无可挽回, 未来可以改变 ---- 🌹感谢您的点赞与关注,同时欢迎各位有空来访我的🍁平凡舍 ---- 文章目录 @[toc] 🚀前言 🚀字符指针 🚀指针数组 🚀数组指针 🍁&数组名 与 数组名 🍁数组指针的使用 🚀数组传参、指针参数 🍁一维数组传参 🍁二维数组传参 🍁一级指针传参 🍁二级指针传参 🚀函数指针 🚀结语 🚀前言 回想之前,我们学了指针的一些基础👉 指针与结构体 我们知道了指针的概念
平凡的人1
2022/11/15
3.3K0
【C语言】指针进阶:字符指针&&数组指针&&函数指针
指针详解(3)
在使用上,由于pstr存放的是字符串第一个字符的地址所以 对pstr解引用就可以打印第一个字符,打印整个操作符只需提供首元素的地址,使用%s就可以打印出来。
技匠晓晨
2024/11/26
940
指针详解(3)
C语言指针深度解剖
指针是C语言的灵魂,深入理解指针,是学好学会C语言的重要前提。因此,本文将重点讲解C语言指针的深度内容。
二肥是只大懒蓝猫
2023/03/30
5020
C语言指针深度解剖
推荐阅读
相关推荐
轻松拿捏C语言——【保姆级·指针讲解】期末C语言<指针>急救包,全是干货,诚意满满!
更多 >
LV.0
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档