C语言基础:初识指针(二)

当你不知道指针变量初始化什么时,可以初始化为空指针

int *p=NULL;

我们看NULL的定义,可以看出NULL是0被强制转化为Void* 类型的0;实质还是个0; 

如何避免野指针:
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置 NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

 指针运算

  • 指针+- 整数
  • 指针-指针
  • 指针的关系运算

 指针+- 整数

下面这段代码实现的是打印数组的元素。

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *p);
		p = p + 1;
	}
	return 0;
}
指针 - 指针
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", & arr[9] - &arr[0]);
	return 0;
}

指针-指针得到的是中间元素的个数

例如:求字符串的长度。模拟实现strlen这个函数 

int my_strlen(char* str)
{
	char* start = str;
	char* end = str;
	while (*end != '\0')
	{
		end++;
	}
	return end - start;
}
int main()
{
	char arr[] = "bit";
	int len = my_strlen(arr);
	printf("%d\n", len);

	return 0;
}

 指针与数组

数组名是首元素地址,怎么证明呢?通过下面的代码进行证明

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	return 0;
}

注意:两个例外

1.&arr   -   &数组名   -     数组名不是首元素地址-数组名表示整个数组 ,所以&数组名取出的是整个数组的地址,

2.sizeof(arr)  -  sizeof(数组名)-数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小。单位字节

下面的代码我们来看看他们的区别

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	printf("%p\n", arr);
	printf("%p\n", arr+1);

	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[0]+1);

	printf("%p\n", &arr);
	printf("%p\n", &arr + 1);
	return 0;
}

调试代码如下: 

前面两个都是地址加4,最后一个加了40,(16进制的运算) 

可以看出&arr是整个数组的地址,整个数组的地址加1,是跳过(整型)4*10(元素个数)=40

既然可以把数组名当成地址存放到一个指针中,我们使用指针来访问其中任意一个就成为可能。

看下面的代码:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int* p = arr; //指针存放数组首元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p + i);
	}
	return 0;
}

 可以看出是是一一对应的关系,所以 p+i 其实计算的是数组 arr 下标为i的地址。 那我们就可以直接通过指针来访问数组。

打印数组元素

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	int* p = arr; //指针存放数组首元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
 	}
    for (i = 0; i < sz; i++)
	{
		printf("%d \n", arr[i]);
	}
	return 0;
}

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?

所以我们就有二级指针

a 的类型是int 

pa 的类型是int*

ppa  的类型是int**  最后一个*表示是指针,指向的对象是int*

int main()
{
	int a = 10;
	int* pa = &a;
	int** ppa = &pa;
	printf("%d\n", **ppa);
}

指针数组

与数组指针的区别       就像好孩子,重点是孩子,

指针数组-数组   --存放指针的数组。

数组指针-指针。

为啥要与指针数组,跟数组的由来一样,看下面的代码,对同一类型的地址存储,如果一个一个写下去,太麻烦了,所以我们要有指针数组来存放,这样就方便多了。

int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int* pa = &a;
	int* pb = &b;
	int* pc = &c;
	return 0;
}

 

怎么初始化呢?

int arr[10];
int* arr1[3];//指针数组初始化

存放的类型都是int* 的类型

int* arr1[3] = { &a,&b,&c };
int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int* arr2[3] = { &a,&b,&c };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%d \n", *(arr2[i]));
	}
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

debian gnome-desktop GUI(图形用户界面)系统

目录 &#x1f31e;更新 &#x1f3a8;安装 &#x1f34e;分配 &#x1f6cb;️重启 &#x1f511;通过VNC连接 debian gnome-desktop &#x1f31e;更新 sudo apt update sudo apt -y upgrade &#x1f3a8;安装 sudo apt -y install task-gnome-desktop 这个过程比…

Java设计模式 _结构型模式_适配器模式

一、适配器模式 **1、适配器模式&#xff08;Adapter Pattern&#xff09;**是一种结构型设计模式。适配器类用来作为两个不兼容的接口之间的桥梁&#xff0c;使得原本不兼容而不能一起工作的那些类可以一起工作。譬如&#xff1a;读卡器就是内存卡和笔记本之间的适配器。您将…

Sy8网络管理命令(ubuntu23.10和centos8)

前言、 本次实验主要是扩展学习&#xff0c;不仅限在课本的内容。毕竟课本的内容太过于陈旧了。需要的童鞋看看。 说明&#xff1a;&#xff08;书本中sy9”第3.实验内容“大家还是要做下。&#xff09; 1、使用ubuntu做实验的童鞋只要看第二、三、四、七章节的部分内容。 2、使…

单片机为什么有多组VDD?

以前我在画尺寸小的PCB时&#xff0c;比较头痛&#xff0c;特别是芯片引脚又多的&#xff0c;芯片底下&#xff0c;又不能打太多过孔。 可能有些老铁也比较好奇&#xff0c;为什么一个单片机芯片&#xff0c;有这么多组VDD和VSS。 比如下面这个100个引脚的STM32单片机。 有5组…

Blender基础操作

1.移动物体&#xff1a; 选中一个物体&#xff0c;按G&#xff0c;之后可以任意移动 若再按X&#xff0c;则只沿X轴移动&#xff0c;同理可按Y与Z 2.旋转物体&#xff1a; 选中一个物体&#xff0c;按R&#xff0c;之后可以任意旋转 若再按X&#xff0c;则只绕X轴旋转&…

STM32、GD32等驱动AMG8833热成像传感器源码分享

一、AMG8833介绍 1简介 AMG8833是一种红外热像传感器&#xff0c;也被称为热感传感器。它可以用来检测和测量物体的热辐射&#xff0c;并将其转换为数字图像。AMG8833传感器可以感知的热源范围为-20C到100C&#xff0c;并能提供8x8的像素分辨率。它通过I2C接口与微控制器或单…

全面解析平台工程与 DevOps 的区别与联系

平台工程的概念非常流行&#xff0c;但很多开发人员仍然不清楚它是如何实际运作的&#xff0c;这是非常正常的。 平台工程是与 DevOps 并行吗&#xff1f;还是可以相互替代&#xff1f;或者 DevOps 和平台工程是两个完全不同的概念&#xff1f; 一种比较容易将两者区分开来的方…

Feign负载均衡

Feign负载均衡 概念总结 工程构建Feign通过接口的方法调用Rest服务&#xff08;之前是Ribbon——RestTemplate&#xff09; 概念 官网解释: http://projects.spring.io/spring-cloud/spring-cloud.html#spring-cloud-feign Feign是一个声明式WebService客户端。使用Feign能让…

AI大模型探索之路-训练篇5:大语言模型预训练数据准备-词元化

系列文章目录&#x1f6a9; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据…

法律知识学习考试系统 C#+uniapp+asp.net微信小程序

技术要求&#xff1a;后端C#&#xff0c;安卓app&#xff0c;mysql数据库 系统分为管理员、教师端和学生端: 管理员端实现管理员的注册登录以及教师和学生的注册、法律法规内容的发布与更新、法律法规页面的评论的添加与删除、内容查询、知识小测的内容发布与删除、问卷调查的发…

云计算和边缘计算究竟有什么不同

在数据时代&#xff0c;无论是人的活动还是机器的运作都会产生各种各样海量的数据。在对数据梳理和筛选过程中&#xff0c;计算机的运算处理必不可少。为了减少本地计算机算力成本等限制&#xff0c;越来越多的企业选择了云计算和边缘计算。今天&#xff0c;德迅云安全就带您来…

SpikingJelly笔记之梯度替代

文章目录 前言一、梯度替代二、网络结构三、MNIST分类1、单步模式2、多步模式 总结 前言 在SpikingJelly使用梯度替代训练SNN&#xff0c;构建单层全连接SNN实现MNIST分类任务。 一、梯度替代 1、梯度替代&#xff1a; 阶跃函数不可微&#xff0c;无法进行反向传播 g ( x ) …

miniTry:Python实现web搜索(全自动+程序操控)

声明&#xff1a;本问给出了全部代码--可以复现--亲测有效 :) [ 代码为图片--> 强制自己去敲一次 又不多] 1.打开网站&#xff1a; 2.利用id去定位到我们要进行输入的内容&#xff08;bing可以直接进行搜索&#xff0c;而csdn需要登录&#xff0c;所以我们用csdn做演示&…

HODL、FUD、FOMO 等其他比特币俚语是什么意思?

作者&#xff1a;Paxful Team 1、FOMO&#xff08;惧怕错失机会&#xff09; FOMO 是惧怕错失机会的缩写&#xff0c;可用于日常生活。它指的是当其他人都在谈论比特币时&#xff0c;产生的购买比特币的紧迫感。 2、Shill&#xff08;不断推广吹捧&#xff09; Shilling 是指…

linux支持vGPU方案

1&#xff0c;查询gpu型号&#xff1a;lspci | grep "NVIDIA\|VGA" PCI Devices 2&#xff0c;下载驱动 官方驱动 | NVIDIA 3&#xff0c;安装 sudo sh NVIDIA-Linux-x86_64-440.118.02.run -no-x-check -no-nouveau-check -no-opengl-files参数说明&#xff1a; …

自定义View-旋转变色圆角三角形的绘制

本文字数&#xff1a;3151字 预计阅读时间&#xff1a;20分钟 在现代设计中&#xff0c;动效图在APP的UI界面中所起到的作用无疑是显著的。相比于静态的界面&#xff0c;动效更符合人类的自然认知体系&#xff0c;它有效地降低了用户的认知负载&#xff0c;UI动效俨然已经成为了…

汽车新四化,会发生什么?

北京国际汽车展览会正如火如荼地进行中,作为国内外汽车行业瞩目的盛会&#xff0c;众多车企纷纷亮出了自家的“杀手锏”。 这场汽车的盛宴不仅集中展示了众多汽车品牌的最新技术和产品&#xff0c;更深刻体现了汽车新四化的发展趋势。汽车新四化&#xff0c;即电动化、网联化、…

DS进阶:AVL树和红黑树

一、AVL树 1.1 AVL树的概念 二叉搜索树&#xff08;BST&#xff09;虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-…

使用Keil移植工程时修改单片机型号参数

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 当使用Keil对STM32系列单片机开发时&#xff0c;如果使用的是库函数&#xff0c;那么不同型号单片机的工程项目文件是可以直接移植的。只需要按照下面的步骤修改对应的芯片&#xff0c;就可以直接将工程移植过去&a…

JVM垃圾收集器--分区收集器

G1收集器 属性 G1&#xff08;Garbage-First Garbage Collector&#xff09;在 JDK 1.7 时引入&#xff0c;在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。G1 有五个属性&#xff1a;分代、增量、并行、标记整理、STW。 分代 G1收集器 将内部分为多个大小相等的区域&#x…