C语言学习之路--指针篇
创始人
2025-05-31 16:13:36

目录

  • 一、前言
  • 二、指针
    • 一、指针是什么
      • 1、指针的重要理解
      • 2、指针变量
      • 3、其他问题
    • 二、指针和指针类型
      • 1、指针+—整数
      • 2、指针的解引用
    • 三、野指针
      • 1、野指针成因
      • 2、如何规避野指针
    • 四、指针的运算
      • 1、指针—指针
      • 2、指针的关系运算
    • 五、指针和数组
    • 六、二级指针
    • 七、指针数组

一、前言

  • 本人是一名小白,这一篇是记录我C语言学习中的指针的所学所得,仅为简单的认识下C语言中的各个知识。

二、指针

一、指针是什么

  • 指针是什么?

1、指针的重要理解

  1. 指针是内存中一个最小单元(一个字节)的编号,也就是地址。
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量。
  • 那么,我们可以这样理解:
    在这里插入图片描述

2、指针变量

  • 我们可以通过&(取地址操作符)取出变量的内存起始地址,把该地址存放在一个变量中,这个变量就是指针变量。
#include int main()
{int a = 10;    //在内存中开辟一块4个字节的空间int* pa = &a;  //这里我们对变量a,取出它的地址,可以用&(取地址操作符)//整形变量a占用4个字节的内存空间,第7行代码是将a的4个字节的第一个字节的地址存放在变量pa中,pa就是一个指针变量printf("%p", pa); //%p为指针变量的格式化输出return 0;
}

运行结果
在这里插入图片描述

  • 总结
    指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。

3、其他问题

  • 一个小的单元到底是多大?(一个字节)
  • 如何编址?
    经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。
  • 对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电
    平(低电压)就是(1或者0);
    那么32根地址线产生的地址就会是:

00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001

11111111 11111111 11111111 11111111

这里就有2的32次方个地址。
每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB ==
2^32/1024/1024MB ==2^32/1024/1024/1024GB == 4GB) 4G的空间进行编址。
同样的方法,那64位机器,如果给64根地址线,那能编址多大空间,计算亦如此。
这里我们便明白:

  • 32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以
    一个指针变量的大小就应该是4个字节
  • 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地
    址。
    总结
  • 指针变量是用来存放地址的,地址是唯一标识一个内存单元(一个字节)的,
  • 指针的大小在32位平台是4个字节,在64位平台是8个字节。

二、指针和指针类型

  • 我们都知道,我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?
    准确的说:有的。
  • 当有这样的代码
int num = 10;
p = #

要将&num(num的地址)保存到p中,我们知道p就是一个指针变量,那它的类型是怎样的呢?

  • 因此,我们定义以下类型
char  *pc = NULL;
int  *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

这里可以看到,指针的定义方式是: type + * 。
其实:
char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。

  • 那指针类型的意义是什么?

1、指针+—整数

#define  _CRT_SECURE_NO_WARNINGS 1
#include int main()
{int n = 10;char* pc = (char*)&n;int* pi = &n;printf("%p\n", &n);printf("%p\n", pc);printf("%p\n", pc + 1);//输出比pc大1个字节printf("%p\n", pi);printf("%p\n", pi + 1);//输出比pi大4个字节return 0;
}

运行结果
在这里插入图片描述

  • 总结:指针的类型决定了指针向前或者向后走一步有多大(距离)。

2、指针的解引用

#include int main()
{int n = 0x11223344;char* pc = (char*)&n;int* pi = &n;*pc = 0;printf("%x\n", n);*pi = 0;printf("%x\n", n);return 0;
}

运行结果
在这里插入图片描述

  • 我们不难发现,pc只访问了一个字节,pi访问了4个字节。
  • 总结:
    指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
    比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

三、野指针

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

1、野指针成因

1、指针未初始化

#include 
int main()
{
int *p;//局部变量指针未初始化,默认为随机值*p = 20;
return 0;
}

2、指针访问越界

#include 
int main()
{int arr[10] = {0};int *p = arr;int i = 0;for(i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}

3、指针指向的空间释放

2、如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放,及时置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性
#include 
int main()
{int *p = NULL;//....int a = 10;p = &a;if(p != NULL){*p = 20;}return 0;
}

四、指针的运算

1、指针—指针

#include int my_strlen(char* s)
{char* p = s;while (*p != '\0')p++;return p - s;
}int main()
{char arr[] = "abc";int a = my_strlen(arr);printf("%d\n", a);return 0;
}

运行结果
在这里插入图片描述

2、指针的关系运算

for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{*vp = 0;
}
  • 实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证
    它可行。
    标准规定:
    允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
    指向第一个元素之前的那个内存位置的指针进行比较。(上述代码中的value[0]与它前面的地址进行了比较)

五、指针和数组

#include int main()
{int arr[3] = { 1,2,3 };printf("%p\n", arr);printf("%p\n", &arr[0]);return 0;
}

运行结果
在这里插入图片描述

  • 可见数组名和数组首元素的地址是一样的。
    结论:数组名表示的是数组首元素的地址。但两种情况除外
  1. sizeof(数组名),这里的数组名是表示整个数组,计算的是整个数组的大小,单位是字节
  2. &数组名,这里的数组名是表示整个数组,&数组名取出的是数组的地址,这是arr+1会跳过这个数组。
  • 那么这样写代码是可行的:
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是数组首元素的地址
  • 指针访问数组
#include int main()
{int arr[3] = { 1,2,3 };int* p = arr; //指针存放数组首元素的地址int sz = sizeof(arr) / sizeof(arr[0]);//计算数组大小for (int i = 0; i < sz; i++){printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p + i);}for (int j = 0; j < sz; j++){printf("%d ", *(p + j));}return 0;
}

运行结果
在这里插入图片描述
总结: p+i 其实计算的是数组 arr 下标为i的地址。那我们就可以直接通过指针来访问数组。

六、二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
那就是 二级指针 。
在这里插入图片描述
对于二级指针的运算有:

  • *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa

int b = 20;
*ppa = &b;//等价于 pa = &b;

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

**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

七、指针数组

  • 指针数组是指针还是数组?
    答案:是数组。是存放指针的数组。
  • 数组我们已经知道整形数组,字符数组。

int arr1[5];
char arr2[6];

在这里插入图片描述

  • 那指针数组是怎样的呢?

int* arr3[5];//是什么?

在这里插入图片描述

即arr3是一个数组,有五个元素,每个元素是一个整形指针。

相关内容

热门资讯

湾财周报|大事记 比亚迪驳斥“... 一周大事记(5月26日-6月1日) 头条 比亚迪驳斥! 长城“车圈恒大论”是行业警示还是危言耸听?...
通源石油跌1.96%,成交额1... 5月30日,通源石油跌1.96%,成交额1.03亿元,换手率4.40%,总市值23.54亿元。 异动...
中国邮储银行浙江分行2025校... 点这里 ↑ 老满说高考 作者 l 老满 生涯规划师l 升学顾问l 拆书家 这是 老满说高考公众号 的...
公募基金规模首次突破33万亿元... 每经记者:肖芮冬 每经编辑:叶峰 天赐良基日报第654期 一、今日基金新闻速览 1、华润元大基金贾...
湾财周报 大事记 比亚迪驳斥“... 一周大事记(5月26日-6月1日)头条比亚迪驳斥!长城“车圈恒大论”是行业警示还是危言耸听?近日,关...
EL表达式JSTL标签库 EL表达式     EL:Expression Language 表达式语言     ...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
工信部、中汽协紧急发声!汽车“... 文/刘育英新一轮汽车价格战再起。近日,工信部、中汽协纷纷发声表示反对。工业和信息化部表示,将加大对汽...
3 ROS1通讯编程提高(1) 3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
募资39亿,全亏光了,账上不到... 关于天然气,用户的感觉是价格一直在上涨,但很奇怪,不管怎么涨,天然气企业仍然亏,还亏得一塌糊涂。这是...
资阳房产评估公司 这是(tel-15828298733)整理的信息,希望能帮助到大家 在当今社会,随着经济的发展和城...
华桥汇利(中国)投资基金管理有... 今年第一季度,美国企业利润出现大幅下降,且面临着来自关税上升的持续压力,这一局面可能会在今年进一步加...
ESG 报告合规与鉴证:全球政... 在当下全球经济格局里,ESG(环境、社会和公司治理)已然成为衡量企业可持续发展能力的关键指标。随着全...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...
与锤巨子生物的大嘴博士持股同一... 医美龙头巨子生物“成分争议”风波持续发酵。日前,美妆博主大嘴博士(香港大学化学博士郝宇)发文,质疑巨...
Linux之进程间通信 目录 进程间通信介绍 一、为什么要进行进程间通信? 二、进程间通信目的 三、进程间通信...
从“造城”到“留客”,文旅局长... 你有没有刷到最近各地文旅局局长全体“尬舞”的视频?领导们放下架子开始跳魔性舞蹈,这场舞的背后啊,可不...
Hazel引擎学习(十一) 我自己维护引擎的github地址在这里,里面加了不少注释,有需要的可以看...
孩子的教育金,分享3个「有效」... 点击 “简七读财” ,发送消息“ 理财小工具 ”免费领取“40个赚钱工具资源包”晚上好,我是简七编...
iZotope RX 10(专... iZotope RX 10是一款专业的音频修复和增强软件,具有音频修复工具、音频增强工...
我的docker随笔40:cl... 本文介绍 clickhouse 数据库的容器化部署。 起因 某项目需生产环境数据库,因...
透视一周牛熊股:最牛股路桥信息... 过去一周(5月26日—5月30日)A股三大指数集体下跌。截至5月30日收盘,上证指数报3347.49...
基于matlab创建地面固定雷... 一、前言此示例演示如何创建和显示包含地面固定雷达、转弯飞机、等速飞机和移动地面车辆的多平台方案。二、...
暗夜发光,独自闪耀,盘点网页暗... 众所周知,网页的暗黑模式可以减少屏幕反射和蓝光辐射,减少眼睛的疲劳感&#...
C语言-程序环境和预处理(2) 文章目录预处理详解1.预定义符号2.#define2.1#define定义的标识符2.2#defin...
MySQL数据库知识整理 MySQL数据库知识整理 MySQL事务详解 事务四大特性ACID 原子性(Atomi...
Docker基础篇——最全讲解 文章目录一、CentOS安装docker二、启动帮助类命令三、镜像命令1.名词概念2.常用命令2.1...
五问“恒大论”,比亚迪回应车圈... “车圈恒大”引发的舆论风暴还在进一步发酵。近日,比亚迪集团品牌及公关处总经理李云飞在微博发文,引用多...
javafx实现聚光灯效果,圆... 系列文章专栏:javafx图形绘制、桌面录屏录音源码合集 目录 一、实现的效果 二、实现思路
300左右哪款蓝牙耳机适合学生... 近年来,随着蓝牙耳机的发展,不管是音质、外观、佩戴还是降噪都有了很大的提...