初阶指针C

news/2025/2/21 6:55:49/

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰指针是什么

🐰指针和指针类型

🌸指针+-整数

🌸指针的解引用

🐰野指针

🌸野指针的成因

🌸如何规避野指针

🐰指针运算

🌸指针+-整数

🌸指针-指针

🌸指针的关系运算

🐰指针和数组

🐰二级指针

🐰指针数组


🐰指针是什么

1.指针是内存中一个最小单元的编号,也就是地址

2.平时口语上所说的指针,通常指的是指针变量,是用来存放地址的变量

3.把内存划分为一个个的内存单元,这个内存单元大小是1字节,从概念上讲:编号 == 地址 == 指针

指针变量:

我们可以通过& (取地址操作符) 取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量

int main
{int a=10;//a是整形,占用4个字节的内存空间,没个字节都有对应的空间int* pa=&a;//&a  得到的是a的地址(指针),其实得到的是a所占内存中4字节中第一个字节的地址;pa是指针变量
}

‼️注:指针变量是用来存放地址的,存在指针中的值都会被当作地址,(锤子的眼里都是钉子)

🐰指针和指针类型

指针的类型为一个类型名和字符“ * ” 的组合,我们平时说“一个int 类型的指针”,其实是在说“一个类型为 int*的指针”。编译器认为这样的一个指针指向的内存单元为4 字节,并将其内容解释为 int 类型的值。

指针的类型有很多种,但指针类型大小是相同的:

    printf("%lu\n",sizeof(int*));printf("%lu\n",sizeof(char*));printf("%lu\n",sizeof(double*));printf("%lu\n",sizeof(short*));
他们所打印的值都是,都是8

‼️注:不同类型的指针大小相同,x86环境下大小是8,x64环境下大小是4

🌸指针+-整数

#include<stdio.h>
int main()
{int a=10;int* pa=&a;char* pc=&a;printf("%p\n",&a);printf("%p\n",pa+1);printf("%p\n",pc+1);return 0;
}

其运行结果为:

0x7ffeefbff3e8

0x7ffeefbff3ec

0x7ffeefbff3e9

&a:     0x7ffeefbff3e8
pa+1    0x7ffeefbff3ec
ppc+1   0x7ffeefbff3e9
可以看出来pa+1移动了4个内存单元即4个字节,而pc+1移动了1个内存单元即一个字节,因为pa是int类型的指针变量,所以需要移动1*sizeof(int),pc是char类型的指针变量,所以需要移动1*sizeof(char).

总结:指针类型决定了,指针进行+1,-1的时候,一步走多远

🌸指针的解引用

#include<stdio.h>
int main(){
int a=1000,b=1000;;
int* pa=&a;*pa=20;
char* pb=&b;*pb=20;
printf("a=%d b=%d\n",a,b);
}

其运行结果为:

a=20 b=788

大家就会奇怪,明明*pa=20,*pb=20一样,为什么a,b的值不一样呢?分析如下

int a=1000,b=1000;;
int* pa=&a;*pa=20;
char* pb=&b;*pb=20;
因为pa是整形的指针变量,可以访问4个字节的存储空间,刚好a也是整形变量,pa可以访问a中的所有值,而pb是字符型的指针变量,可以访问1个字节的存储空间,而b是整形变量,pb只能访问b中一个字节的内容

总结:指针类型就决定了,在解引用指针的时候能访问几个字节

🐰野指针

🌸野指针的成因

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

(1)指针未初始化

int*p;未初始化

(2)当指针指向的范围超出数组arr的范围时,p就是野指针

int arr[10]={0};
int* p=arr;
*(p+10)=1;*(p+10)就是arr[10],这已经越界了

(3)指针指向空间释放

就是指针p之前指向的是一个有效的内存空间,现在那个空间被销毁了,这个指针p也就成为了野指针(这就好比张三以前有个女朋友,但是现在分手了,张三就成为了单身汪,因此单身汪是不能联系前女友的

(4)避免返回局部变量的地址

int* fun(int arr[]){int* p=arr;return str
}
int main(){int arr[10]={0};int* parr=fun(arr);这里返回的地址,已经在函数调用完成时销毁了
}

(5)指针的使用之前检查有效性

‼️注:一个指针不知道指向哪里时,暂时可以初始化NULL

🌸如何规避野指针

注意造成野指针的成因,就可以有效避免野指针的形成。

‼️注:一个指针不知道指向哪里时,暂时可以初始化NULL

🐰指针运算

🌸指针+-整数

🌸指针-指针

🌸指针的关系运算

🐰指针和数组

🐰二级指针

🐰指针数组

🐶🐶🐶由于课程问题,有些许内容还没有更新,请各位观众老爷们见谅🐶🐶🐶

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  


http://www.ppmy.cn/news/23735.html

相关文章

程序环境--翻译+执行

ANSI C标准下&#xff0c;有两种程序环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 翻译环境包括&#xff1a;预处理&#xff08;预编译&#xff09;编译汇编链接。四个步骤。 第2种是执行/运行环境&#xff0c;它用于实际执行代码。 链接…

【PyTorch】教程:Transfer learning

Transfer learning 实际工作中&#xff0c;只有很少的人从头开始训练 CNN&#xff0c;因为很难获得大量的样本。一般情况下&#xff0c;会通过调用预训练模型&#xff0c;例如 ConvNet 在 ImageNet&#xff08;1.2 M 图像 1000 个类别&#xff09;,可以用 ConvNet 初始化&#…

每日go语言面试题一

1.Redis Multi实现原理 redis中的multi是为了实现redis独特的事务而存在的&#xff0c;底层是有一个队列&#xff0c;将Multi后面的命令先进先出的顺序加入队列&#xff0c;在执行exce命令&#xff0c;将队列中的命令取出执行。配合redis完成事务的命令还有watch&#xff08;会…

并发线程、锁、ThreadLocal

并发编程并发编程Java内存模型&#xff08;JMM&#xff09;并发编程核心问题—可见性、原子性、有序性volatile关键字原子性原子类CAS(Compare-And-Swap 比较并交换)ABA问题Java中的锁乐观锁和悲观锁可重入锁读写锁分段锁自旋锁共享锁/独占锁公平锁/非公平锁偏向锁/轻量级锁/重…

08讲 | 基于STM32单片机NBIOT定位实战项目

前言 绘制基于 STM32 单片机的 NBIOT 实战开发板。 文章目录前言一、原理图1、绘制1&#xff09;电源供电a、USB 转 TTL 电路b、锂电池充电管理电路c、3.3V电压转换电路d、一键开关机电路2&#xff09;单片机最小系统3&#xff09;ADC电压转换电路4&#xff09;NBIOT 模组串口电…

【C++】类和对象(第一篇)

文章目录1. 面向过程和面向对象初步认识2.类的引入3.类的定义3.1 类的两种定义方式3.2 成员变量命名规则建议4. 类的访问限定符及封装4.1 访问限定符4.2 封装5. 类的作用域6. 类的实例化7. 类对象模型7.1 类对象大小的计算7.2 类对象的存储方式猜测7.3 结构体内存对齐规则复习8…

python(15)--函数设计

前言 函数是可重用的程序代码块。 函数的作用&#xff0c;不仅可以实现代码的复用&#xff0c;还可以保证修改函数的代码时&#xff0c;所有调用该函数的地方都能得到体现。目前我已知函数的作用是&#xff1a;对代码实现了封装、函数调用、传递参数、返回计算结果等。 正文 …

软件测试标准流程

软件测试的基本流程大概要经历四个阶段&#xff0c;分别是制定测试计划、测试需求分析、测试用例设计与编写以及测试用例评审。因此软件测试的工作内容&#xff0c;远远没有许多人想象的只是找出bug那么简单。准确的说&#xff0c;从一个项目立项以后&#xff0c;软件测试从业者…