C语言:指针详解

article/2025/8/29 7:12:10

目录

指针就是地址,口语中说的指针通常指的是指针变量

指针的定义以及指针类型

野指针

指针运算

a.指针+/-整数

b.指针只能-指针,不能+指针

指针与数组

二级指针

指针数组

指针的大小是固定的4/8个字节(32位平台/64位平台)

字符指针

指针数组

数组指针

数组指针的使用

数组指针和指针数组的区分

数组名与&数组名的区别

数组传参和指针传参

一维数组传参

二维数组传参

一维指针传参

二维指针传参

函数指针

函数指针数组

回调函数


  • 指针就是地址,口语中说的指针通常指的是指针变量

  • 指针的定义以及指针类型

例如:int* p;

p的类型并不是int,而是int*

当然的,除了int类型的指针还有short*的float*,double*等等的类型的

当然这里值得一提的是,这里的3个printf,都是打印4.

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以

一个指针变量的大小就应该是4个字节。

那这样指针的类型不一样但都是4个字节,那指针的类型有什么用呢?答案在下面

由图中可以知道,第一个图int类型的a的地址由int*来存储

第二个图int的a的地址由char*来存储。可以看到第一个图更改了4个字节的地址,但第二个图只更改了1个字节的地址。

所以要用相同类型的指针变量来存储相同类型的变量地址,就像第一个图一样。

其实:

char* 类型的指针是为了存放 char 类型变量的地址。

short* 类型的指针是为了存放 short 类型变量的地址。

int* 类型的指针是为了存放 int 类型变量的地址。

而指针类型的例外一个作用:指针的类型决定了指针向前或者向后走一步有多大(距离)

  • 野指针

定义:野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

比较常见的成因是:指针未定义,以及数组越界访问,形参或者其他原因造成的指针指向的空间释放

我们在编写代码时,需要努力的规避野指针,来避免程序出错

  • 指针运算

a.指针+/-整数

例如:

int arr[10]={1,2,3,4,5,6,7,8,9,10};

int *p=arr;

*p+1;

这里*p+1访问的是arr[1];

这里,++的运算级别比*高,所以先进行vp++,再加*,因为是后置++所以*vp++是访问的是*vp,然后再进行++,进入到下一个。

下图红色区域为数组地址的位置。

这里当数组减到values[0]的时候,因为判断条件是vp>=values[0],所以还会进行一次循环判断,这里就会超出数组的范围啦。

这样的话,能不能成功运行取决于编译器,所以最好不要这样写。

标准规定:

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与

指向第一个元素之前的那个内存位置的指针进行比较。

这里我给翻译一下,就是可以跟数组后面的指针作比较,但不可以跟数组前面的的指针作比较。

b.指针只能-指针,不能+指针

  • 指针与数组

当数组的首地址(数组名)定义给了指针的话。

.p+i 其实计算的是数组 arr 下标为i的地址。(p为指针)

  • 二级指针

二级指针其实就是将一个指针的地址再将其放在一个指针中,类似于套娃。.

**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .

  • 指针数组

int arr[10]其实就是存有int类型数据的数组

同理可得,指针数组也是一个数组,是一个存有指针的数组.

例如:int* arr[10];

指针的大小是固定的4/8个字节(32位平台/64位平台)

  • 字符指针

字符指针简单来说就是存放字符变量的指针

我们来研究一下这个代码:

从这里我们可以看到,p2存放的是一个字符串,所以字符指针不止可以存放字符还可以存放字符串

我们将p2解引用打印出来发现打印出a,所以如果存放的是字符串,字符串存到p2(指针)中存放的是字符串首元素的地址

我们要打印首元素的话需要解引用,也就是*p2

如果我们要打印字符串的时候,我们只要给字符串首元素的地址就好,也就是p2

这里p2存放的是常量字符串,常量字符串不允许修改

而如果我们想要修改的话,就得利用可以修改的空间,用数组来存储的时候就可以修改了

  • 指针数组

说白了,就是存放指针的数组

  • 数组指针

存放数组变量的地址的指针

  • 数组指针的使用

我们看一下这个代码,我们会发现这个代码很别扭

这个代码奇怪的地方就在print传过去的&arr和print接受的指针类型,以及打印的写法。

首先说明不建议这么写。

这里传过的&arr是一个地址,而地址就是指针,这个指针指向数组,所以是数组指针

p是&arr,而p不就是&arr,和&不就相互抵消了嘛,所以p=arr

二维数组传参(写成指针)

arr1为二维数组,而arr1这个数组名表示二维数组的首地址,而二维数组的首地址是第一行的地址。

所以二维数组的数组名是指向二维数组的第一行的,这个第一行相当于一个一维数组

相当二维数组的首地址是一个指针,然后它指向一个一维数组,所以写成数组指针。

而这个我解释一下,p1+i相当于访问第i行的地址,*(p1+i)解引用相当于第i行,然后再加j然后解引用,相当于找第i行第j列的那一个。

  • 数组指针和指针数组的区分

  • 数组名与&数组名的区别

我们来看一个例子

这里我们发现arr和&arr是一样,而arr是首元素地址,&arr是整个数组的地址,但整个数组的地址也得从首元素一样啊。

我们看下面两个,这两个的后两位一个是2C一个是50,2C是2x16+12x1=44. 50是5x16=80,这两个的差值是36加上第一个的地址的4刚好是40,跳过一整个数组的大小。

  • 数组传参和指针传参

数组传参时,形参可以是数组也可以是指针。

一维数组传参

这里比较有困惑的应该是第五个,我们的arr2是一个存放整形指针(地址)的数组,而我们的int**arr是二级指针

二级指针就是存放着一级指针的指针,这两个不就是相同的嘛,所以可以传过去。

二维数组传参

一维指针传参

一级指针传参只能用一级指针来接收

二维指针传参

二级指针传参只能用二级指针来接收

当形参确定为一级指针时,可以将什么变量传过去呢?

一级指针(*p),一级数组(arrp[10]),&a

当形参确定为二级指针时,可以将什么变量传过去呢?

二级指针(**p),对一级指针取地址(&p2)(p2为一级指针),指针数组(int*p[10])

  • 函数指针

我们先来看一个例子:

我们通过这个例子我们可以知道,原来函数名也等于函数的地址啊

函数指针的定义方法:int(*p)(int x,int y)=Add;

调用函数指针的时候,函数指针的传过去的值可以写名字也可以不写名字

下面这个例子要理解一下

  • 函数指针数组

说白了就是存放了函数指针的数组

int(*p[5])(int x, int y) = { 0, add, sub, mul, div };

  • 回调函数

回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个

函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数

的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进

行响应。

简单来说就是:一个函数指针(或者地址)作为一个函数参数被另外一个函数调用,这个函数就叫做回调函数

我们先来看一个库函数qsort(只是一个排列函数)(头文件#include)

代码完整实现

void*类型的指针很宽容,什么类型的指针都可以放进去,但应用的时候不好运用

void型时你p+1访问的几个字节的长度不清楚

如果我们利用冒泡排序的方法写一个与qsort类似的函数呢

不同类型的数据,比较方法也不一样,用冒泡排序来举例子就是

如果我们利用冒泡排序的方法的话

我们就需要找到要比较的两个值的地址,但void*不可以进行+/-等操作。所以要下面这样

完整代码如下


http://chatgpt.dhexx.cn/article/NqT5KEwg.shtml

相关文章

C语言,指针详解

1. 指针是什么&#xff1f; 1. 指针是内存中一个最小单元的编号 2. 口头上的“指针”&#xff0c;指的是指针变量 #include<stdio.h>int main() {int a10;int * pa&a;// pa 是一个指针变量,用来存放 a 的地址//int ——> pa 所指向对象的类型//* 代表 pa是个指针…

C语言指针详细解析

C语言指针详细解析 概述指针指针运算符示例 指针类型示例 指针变量的初始化关系运算示例 数组一维数组示例 二维数组示例 字符串指针示例示例 指针函数示例 函数指针示例 指针函数和函数指针定义写法用途 最后 概述 指针也就是内存地址&#xff0c;指针变量是用来存放内存地址…

C语言:详解指针

本人录制技术视频地址&#xff1a;https://edu.csdn.net/lecturer/1899 欢迎观看。 指针应该算得上是c语言的精华&#xff0c;但也是难点。很多教程或者博客都有对其详细的讲解与分析。我这一节的内容&#xff0c;也是讲解指针&#xff0c;但我会尽量使用图解的方式&#xff0…

【C语言】指针(详解)

文章目录 前言1.字符指针2. 指针数组3. 数组指针3.1 数组指针的定义3.2 &数组名VS数组名3.3 数组指针的使用 4. 数组参数、指针参数4.1 一维数组传参4.2 二维数组传参4.3 一级指针传参4.4 二级指针传参 5. 函数指针6. 函数指针数组7. 指向函数指针数组的指针8. 回调函数8.1…

【c语言】 指针详解 【图文+代码】

指针 前言一、指针是什么&#xff1f;1.1 认识指针1.2 变量1.3 变量放在哪&#xff1f;1.4 指针的本质1.5 解引用 二、指针类型2.1指针有类型吗&#xff1f;2.2指针类型的意义是什么&#xff1f; 三. 野指针3.1什么是野指针3.2野指针成因3.2.1指针未初始化3.2.2 指针越界访问3.…

【初阶】C语言指针详解——指针必备的7大知识点

文章目录 前言一、指针是什么&#x1f351;1、浅谈指针&#x1f351;2、内存&#x1f351;3、指针变量 二、指针和指针类型&#x1f351;1、指针类型&#x1f351;2、指针-整数&#x1f351;3、指针的解引用 三、野指针&#x1f351;1、野指针成因&#x1f333;(1) 指针未初始化…

详解C语言指针

文章目录 1.字符指针2.指针数组3.数组指针3.1 数组指针的定义3.2 &数组名和数组名的区别3.3 数组指针的使用 4.数组参数&#xff0c;指针参数4.1 一维数组传参4.2 二维数组传参4.3 一级指针传参4.4 二级指针传参 5.函数指针6.函数指针数组7.指向函数指针数组的指针8.回调函…

C语言——指针(入门详解)

文章目录 1.什么是指针&#xff1f;1.1.理解指针的两个要点&#xff1a;1.2.指针变量&#xff1a;1.3.内存是如何编址&#xff1f; 2.指针和指针类型2.1指针的创建与初始化2.2.指针类型 3.野指针3.1.什么视野指针&#xff1f;3.2.野指针成因3.3.规避野指针 4.指针运算4.1.指针-…

c语言指针用法详解,通俗易懂超详细!

文章转自&#xff1a;无际单片机 大家好&#xff0c;我是无际。 今天给大家来讲解一下指针。 我会由浅到深&#xff0c;最后结合实际应用讲解&#xff0c;让大家学会指针的同时&#xff0c;知道大佬们都用指针来干嘛&#xff01; 长文预警&#xff01;全文大约5200多字&#xf…

C语言指针详解(超级详细)

C语言指针精解 前言 这不是我第一次写关于C指针的文章了&#xff0c;只是因为指针对于C来说太重要&#xff0c;而且随着自己编程经历越多&#xff0c;对指针的理解越多&#xff0c;因此有了本文。然而&#xff0c;想要全面理解指针&#xff0c;除了要对C语言有熟练的掌握外&…

C语言中的指针详解

1. 什么是指针 C语言中指针是一种数据类型,指针是存放数据的内存单元地址。 计算机系统的内存拥有大量的存储单元,每个存储单元的大小为1字节,为了便于管理,必须为每个存储单元编号,该编号就是存储单元的“地址”,每个存储单元拥有一个唯一的地址。 指针变量除了可以存…

C语言——指针详解(必收藏)

目录 1.什么是指针&#xff1f; 1.1概念 1.2指针的大小 ​ 1.3指针类型的作用 2.野指针 2.1野指针产生的原因 2.2 如何规避野指针 3.指针运算 3.1指针-整数 3.2指针-指针 3.3 指针的关系运算 4. 二级指针 5. 数组名 *6.指针数组和数组指针 6.1指针数组 *6.…

C语言指针详解

一、什么是指针 C语言里&#xff0c;变量存放在内存中&#xff0c;而内存其实就是一组有序字节组成的数组&#xff0c;每个字节有唯一的内存地址。CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里&#xff0c;数据对象是指存储在内存中的一个指定数据类…

C语言之指针详解

文章目录 1 指针1.1 简介1.2 什么是指针1.2.1 定义1.2.2 指针表示1.2.3 为什么*p&a不正确 1.3 使用指针1.3.1 简单使用1.3.2 NULL 指针1.3.3 指针算术运算1.3.3.1 定义1.3.3.2 遍历数组&#xff1a;递增一个指针1.3.3.3 遍历数组&#xff1a;递减一个指针1.3.3.4 指针的比较…

c语言—指针详解

文章目录 一、指针是什么二、指针和指针变量1.左值与右值2.两者的区别 三、指针和指针类型1.定义指针2.大小端3.指针的解引用 四、野指针野指针成因如何规避野指针 五、指针运算1.指针- 整数2.指针-指针3.指针的关系运算 六、指针和数组七、二级指针八、指针数组和数组指针1.指…

机器学习主动学习和半监督学习

一、主动学习&#xff08;active learning&#xff09; 学习器能够主动选择包含信息量大的未标注的样例并将其交由专家进行标注&#xff0c;然后置入训练集进行训练&#xff0c;从而在训练集较小的情况下获得较高的分类正确率&#xff0c;这样可以有效的降低构建高性能分类器的…

active learning主动学习

active learning 是半监督式的机器学习的一种&#xff0c;这种机器学习算法能够交互式地查询用户或者信息源&#xff0c;从而对于一个新的数据样例得到可人的输出。在统计学文献中&#xff0c;它有时也被称为最佳实验设计。 在这样的一种情形下&#xff1a;无标签的数据量很大…

深度主动学习综述2020

A Survey of Deep Active Learning 中文版仅作参考&#xff0c;以正式的pdf版为主。 https://arxiv.org/pdf/2009.00236.pdf 西北大学等最新《深度主动学习》全面综述论文&#xff0c;30页pdf abstract 主动学习试图通过标记最少量的样本使得模型的性能收益最大化。而深度学习…

每日一学-- 主动学习(active learning)

1. 在机器学习中&#xff0c;有监督学习、半监督学习、无监督学习。 在使用监督学习时&#xff0c;模型在标注的数据中学习信息&#xff0c;而存在的问题就是有大量的数据需要标注&#xff0c;非常费时费力。so主动学习为我们提供了方法&#xff0c;通过一定的算法找出最有用的…

一张图展示被动学习与主动学习的效率差距

一张图展示被动学习与主动学习的效率差距 起因一张图 起因 由于工作原因。最近的一段时间&#xff0c;又回到了大量的学习实践当中。之前的主观感受是&#xff0c;通过文字语音视频结合的多渠道信息获取方式学到的东西&#xff0c;记忆会比自己只是看文字&#xff0c;读文字&a…