C语言小白急救 指针初级讲解(四千字教程)

news2024/11/18 17:33:38

系列文章目录

C语言小白急救 表达式求值(两千字教程)
C语言小白急救 操作符详解(8千字保姆级教程)
C语言小白急救 扫雷游戏(万字保姆级教程)
C语言小白急救 使用C语言编写‘三子棋‘

文章目录

  • 系列文章目录
    • [C语言小白急救 表达式求值(两千字教程)](https://editor.csdn.net/md/?articleId=132312494) [C语言小白急救 操作符详解(8千字保姆级教程)](https://editor.csdn.net/md/?articleId=132269381) [C语言小白急救 扫雷游戏(万字保姆级教程)](https://editor.csdn.net/md/?articleId=132259410) [C语言小白急救 使用C语言编写‘三子棋‘](https://mp.csdn.net/mp_blog/creation/editor/132240688)
  • 前言
  • 一、指针介绍
    • 1.指针介绍
    • 2.指针变量
  • 二、 指针和指针类型
    • 1.指针的解引用
    • 2.指针与整数
  • 三、野指针
    • 1. 野指针成因
    • 2.如何规避野指针
  • 四、指针和数组
  • 五、指针的运算
  • 1.指针+- 整数
  • 2.指针-指针
  • 3.指针的关系运算
  • 六、二级指针
  • 七、指针数组
  • 总结


前言


一、指针介绍

1.指针介绍

(1)指针是内存中一个最小内存单元(字节)的一个编号,也就是地址(我们平常所用的二进制位就是其中的一种表现形式)
(2)我们平常口语中所说的指针一般指的是指针变量,是用于存放地址的
总结:指针就是地址,我们平常口语中所说的指针其实是指针变量

2.指针变量

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

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

二、 指针和指针类型

我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?
准确的说:有的。
那么,为什么要有指针类型呢,它有什么作用?

1.指针的解引用

指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:

    int a = 0x11223344;//将a的地址设置为11223344
	int* m = &a;//设置一个指针变量来存储a的地址
	*m = 0;//解应用m,对m中的地址进行操作,使地址变为0

在这里插入图片描述
当Int* 改为 char* 时

int a = 0x11223344;//将a的地址设置为11223344
	char* m = (char*)&a;//设置一个指针变量来存储a的地址
	//因为a是int型的若想要用char作为指针变量,需要转换
	*m = 0;//解应用m,对m中的地址进行操作,使地址变为0

在这里插入图片描述

所以说,不同的指针类型,对指针解引用的时候的权限也不同

2.指针与整数

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

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);
 printf("%p\n", pi);
 printf("%p\n", pi+1);
 return  0;
}

在这里插入图片描述
从结果(16进制)可以看出,char* 类型的,向后移动了1个字节;int* 类型的向后移动了4个字节。这样的区别在于我们对元素进行比如遍历之类的操作中十分有用
比如:

int arr[] = { 1,2,3,4 };
	int* m = arr;
	char* n = (char*)arr;
	int i = 0;
	for (i=0;i<4;i++)
	{
		printf("%p ",m + i);
	}
	printf("\n");
	for (i = 0; i < 4; i++)
	{
		printf("%p ", n + i);
	}

在这里插入图片描述
除打印首元素地址外,一共执行了3次,char* 类型的,向后移动了3个字节,离到第二个元素的位置还差一个字节;int* 类型的向后移动了8个字节,已经到了第三个元素的位置;如果是对元素进行遍历,那么肯定int* 类型更快。

三、野指针

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

1. 野指针成因

(1)指针未初始化

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

这种情况编译器会报错,无法执行
(2) 指针越界访问

int arr[10] = { 0 };
	int* p = arr;
	for (int i=0;i<=10;i++)//循环了11次,但数组中只有十个数
	{
		*p = 1;
		p++;
	}

这种情况下属于越界访问,编译器会报错,无法执行

(3) 指针指向的空间释放

int* tset()
{
	int a = 10;
	return &a;
}

int main()
{
    int* p = tset();
	printf("%d\n",*p);
	return  0;
}

函数 test() 在作用后以及将空间释放,当时你还知道他的地址,这就属于非法访问,也是野指针的一种。比如说:一个陌生人不知道从哪里知道了你的电话号码,整天打电话给你。

2.如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放,及时置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性(指针没有明确指向是设为空NULL)

四、指针和数组

大部分情况下数组名表示的是数组首元素的地址
2个例外:
(1)sizeof(数组名),数组名单独放在sizeof内部,此时数组名表示整个数组,计算的是整个数组的大小,单位是字节
(2)&数组名,此时数组名表示整个数组,取出的是整个数组的地址,数组的地址和数组首元素地址,值是一样的,但是类型和意义不一样
例1:数组名表示的是数组首元素的地址

int arr[] = {1,2,3,4,5 };
printf("%p\n",arr);
printf("%p\n",&arr[0]);

在这里插入图片描述
打印出的地址一样,所以数组名是数组首元素的地址。
例2:sizeof(数组名)

int arr[] = { 1,2,3,4,5 };
	printf("%zd\n",sizeof(arr));

在这里插入图片描述
例3:&数组名

int arr[] = { 1,2,3,4,5 };
	printf("%p\n", &arr);
	printf("%p\n", &arr+1);

在这里插入图片描述

五、指针的运算

1.指针± 整数

指针±整数是跳过多少个元素

    int arr[] = { 1,2,3,4,5 };
	int* p = arr;//数组名的是数组首元素的地址
	//arr+i == p+i
	//*(arr+i) == *(p+i) == arr[i]
	//*(arr+i) == arr[i]
	//*(i+arr) == i[arr]
	for (int i=0;i<5;i++)
	{
		printf("%d ",*(p+i));
		//p+i 是数组中下标为i的值
		//p+i 是跳过了i*sizeof(int)个字节
	}

在这里插入图片描述

2.指针-指针

指针相减的前提:指向同一块区域,指针类型相同
指针相减的结果的绝对值是中间的元素个数

    int arr[10] = { 0 };
    //指针相减的前提:指向同一块区域,指针类型相同
	printf("%d",&arr[9]-&arr[0]);
	//指针相减的结果是中间的元素个数

在这里插入图片描述

3.指针的关系运算

size_t My_strelen(char* str)
{
	char* a = str;//设置一个指针来存储首地址
	while (*str != '\0')//这个地址存储的值不等于'\0'
	{
		str++;//指针+1
	}
	return str-a;
}

int main()
{
	char arr[] = "abcdef";
	size_t count=My_strelen(arr);
	printf("%zd ",count);
	return 0;
}

标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

简单点讲就是尽量从前往后比较,不要从后往前

六、二级指针

二级指针就是用来存储一级指针的地址的

int a = 10;
	int* p = &a;//p是指针变量,一级指针变量
	int** pp = &p;//pp是指针变量,二级指针变量
	//二级指针变量前面有两颗* 是指这个二级指针变量指向一个指针变量的
	//二级指针需要解引用两次

七、指针数组

指针数组是数组,里面存放的是指针,根据数组内存放的不同的指针类型,可以分为不同类型的指针数组;如int * char* 等

应用:

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

	for (int i = 0; i < 3;i++)//访问arr1 arr2 arr3
	{
		for (int j = 0; j < 4;j++)//访问三数组中的元素
		{
			printf("%d ",arr[i][j]);
		}
		printf("\n");
	}

总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/905723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv5、YOLOv8改进:SOCA注意力机制

目录 简介 2.YOLOv5使用SOCA注意力机制 2.1增加以下SOCA.yaml文件 2.2common.py配置 2.3yolo.py配置 简介 注意力机制&#xff08;Attention Mechanism&#xff09;源于对人类视觉的研究。在认知科学中&#xff0c;由于信息处理的瓶颈&#xff0c;人类会选择性地关注所有…

五款拿来就能用的炫酷表白代码

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 五款炫酷表白代码 1、无限弹窗表白2、做我女朋友好吗&#xff0c;不同意就关机3、…

增长黑武器|LTD营销SaaS荣获“2023亚太杰出营销数字化供应商”

LTD受邀与全球五百强企业数字化创新决策人&#xff0c;共同交流探讨信息化管理与数字化变革。 盛夏未央&#xff0c;八月笙箫已起&#xff0c;初秋登场。 在这烂漫的金秋时节&#xff0c;杭州乐通达网络有限公司&#xff08;简称&#xff1a;LTD&#xff09;受邀参加了“重建信…

【VS Code插件开发】Webview面板(三)

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域优质作者、阿里云专家博主&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4e2; 资料领取&#xff1a;前端…

嵌入式设备应用开发(其他第三方库)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 前面我们介绍的qt、boost这些都是通用库。也就是说,不管什么样的场景,这些库都可以拿过来使用。然而在实际开发中还有一些第三方库,它是需要和实际场景联系在一起的。也就是说,…

百度千帆大模型初体验,接入30+大模型、100+提示词模版、插件最丰富,国内最强

大家好&#xff0c;我是二哥呀。 作为国内的头部大厂&#xff0c;百度在大模型这块的投入力度可以说非常大&#xff0c;3 月 16 号发布的大模型——文心一言可以说在业界激起了巨浪。 有支持的&#xff0c;当然也有怀疑的&#xff0c;但无论如何&#xff0c;百度勇敢的迈出去…

致敬,“编辑器之神”Vim的开发者Bram Moolenaar去世

编辑器之神Vim之父Bram Moolenaar逝世&#xff0c;享年62岁。其家人称&#xff0c;因过去几周里病情迅速恶化&#xff0c;Bram Moolenaar于8月3日去世。Bram的一生将大部分时间都奉献给了Vim&#xff0c;甚至在一个月前&#xff0c;他还在对Vim做着更新、修改工作。 Vim 是一个…

数据在内存中的储存·大小端(文字+画图详解)(c语言·超详细入门必看)

前言&#xff1a;Hello&#xff0c;大家好&#xff0c;我是心跳sy&#x1f618;&#xff0c;本节我们介绍c语言的两种基本的内置数据类型&#xff1a;数值类型和字符类型在内存中的储存方法&#xff0c;并对大小端进行详细介绍&#xff08;附两种大小端判断方法&#xff09;&am…

操作系统——进程和线程

文章目录 1.进程和线程的区别2.进程有哪几种状态?3.进程间的通信方式4.线程间的同步的方式5.进程的调度算法 1.进程和线程的区别 从上图可以看出&#xff1a;一个进程中可以有多个线程&#xff0c;多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源&#xff0c;但是每个…

块/ if else/ switch /for for each

1、块作用域&#xff0c; 定义在{}中的变量&#xff0c;只能在{}内生效 import java.util.*; public class Test{ public static void main(String[] xxx){int a10;if(a>9){int k 2;//k只在if{}内有效}//这个括号之后再对k进行操作&#xff0c;违法} } import java.util.…

Java之优雅处理 NullPointerException空指针异常

前言 NPE问题就是&#xff0c;我们在开发中经常碰到的NullPointerException。假设我们有两个类&#xff0c;他们的UML类图如下图所示 在这种情况下&#xff0c;有如下代码 user.getAddress().getProvince(); 这种写法&#xff0c;在user为null时&#xff0c;是有可能报Nul…

AI引擎助力,CamScanner智能高清滤镜开启扫描新纪元!

文章目录 ⭐ 写在前面⭐ 突破图像处理难点&#xff1a;扫描全能王的独特优势⭐ 耳听为虚&#xff0c;眼见为实⭐ 产品背后的主要核心&#xff1a;AI-Scan助力⭐ 深度学习助力智能文档处理的国际化进程⭐ 品味智能文档处理的轻松与精准 ⭐ 写在前面 在数字化快速发展的今天&…

CentOS6上安装MySQL8与Nginx开机自启

背景 临时在一台华为云的 CentOS6 上安装部署一个业务系统&#xff0c;这里记录下 MySQL 8 与 Nginx 的安装过程中遇到的问题。 CentOS6上安装MySQL8 # 下载 wget http://repo.mysql.com/yum/mysql-8.0-community/el/6/x86_64/mysql-community-common-8.0.19-1.el6.x86_64.r…

7-8 二分查找法

分数 10 全屏浏览题目 切换布局 作者 王跃萍 单位 东北石油大学 用二分法在一个有序数列{1,2,3,4,5,6,7,8,9,10}中查找key值&#xff0c;若找到key则输出其在数组中对应的下标&#xff0c;否则输出not found。 输入格式: 直接输入一个要查找的正整数key。没有其它任何附加…

并发-并发挑战及底层实现原理笔记

并发编程挑战 上下文切换 cpu通过给每个线程分配cpu时间片实现多线程执行&#xff0c;时间片是cpu分配给各个线程的时间&#xff0c;cpu通过不断切换线程执行。线程有创建和上下文切换的开销。减少上下文切换的方方法 – 无锁并发编程&#xff0c;eg&#xff1a;将数据的id按…

CSS中如何实现文字溢出省略号(text-overflow: ellipsis)效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS中如何实现文字溢出省略号&#xff08;text-overflow: ellipsis&#xff09;效果&#xff1f;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 …

16----公式

本节我们来学习如何在markdown中打印公式 Markdown是一种轻量级标记语言&#xff0c;常用于撰写文档、博客和论坛帖子。虽然Markdown本身并不支持数学公式&#xff0c;但可以使用一些扩展来实现公式的显示。在支持公式扩展的 Markdown 解析器中&#xff0c;我们可以使用 Katex …

【核磁共振成像】临床基本通用脉冲序列

目录 一、脉冲序列二、自旋回波(SE)脉冲序列2.1 自旋回波脉冲序列2.2 信噪比、差噪比2.3 采样2.4 改进的自旋回波变型序列 三、反向恢复(IR)脉冲序列3.1 反向恢复脉冲序列3.2 关于反向恢复脉冲序列的改进 四、梯度回波(GE)脉冲序列4.1 GE序列基本概念4.2 三维成像 五、相干稳态…

【Spring Boot 源码学习】自动装配流程源码解析(下)

自动装配流程源码解析&#xff08;下&#xff09; 引言往期内容主要内容4. 排除指定自动配置组件5. 过滤自动配置组件6. 触发自动配置事件 总结 引言 上篇博文&#xff0c;笔者带大家了解了自动装配流程中有关自动配置加载的流程&#xff1b; 本篇将介绍自动装配流程剩余的内…

【Freertos基础入门】同步互斥与通信

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、同步互斥与通信是什么&#xff1f;1.基础概念2.freertos通信可用的手段 二、同步与互斥的概念三、各类通信的区别与适用场景总结 前言 本系列基于stm32系列…