C语言深入理解指针2

news2024/11/27 10:28:10

1.数组名的理解

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

在这里插入图片描述
可以发现数组名和数组首元素地址的打印结果一样,因此,数组名就是数组首元素地址

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

在这里插入图片描述
输出结果是40,但如果按上面的结论来,应该输出4/8
数组名是首元素地址这个结论是对的,但对于以下两种情况是例外

  • sizeof(数组名),sizeof中单独存放数组名,这里的数组名表示整个数组的地址
  • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址
  • 除此之外,任何地方的数组名,都表示首元素地址
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("&arr[0]  =%p\n", &arr[0]);
	printf("&arr[0]+1=%p\n", &arr[0]+1);

	printf("arr      =%p\n", arr);
	printf("arr+1    =%p\n", arr+1);

	printf("&arr     =%p\n", &arr);
	printf("&arr+1   =%p\n", &arr+1);//+40字节

	printf("%d\n", sizeof(arr));
	return 0;
}

在这里插入图片描述

解释:
&arr[0]表示首元素地址,&arr[0]+1表示跳过一个元素,是第二个元素的地址,因为该数组的元素是int类型,所以跳过4个字节,arr并不是两种例外情况的一种,所以表示数组首地址,arr+1表示跳过4个字节来到第二个元素地址,&arr表示整个数组的地址,数组的起始位置是首元素地址,所以打印结果是首元素地址,&arr+1,表示跳过整个数组的地址

2.使用指针访问数组

//使用指针访问数组
int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	//输入
	int* p = arr;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		scanf("%d", p+i);//p++
	}
	//p=arr
	//输出
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
	return 0;
}

结论:*(p+i)本质上等价于p[i], arr+i等价于p+i

3. 一维数组传参的本质

#include <stdio.h>
void test(int arr[])
{
 int sz2 = sizeof(arr)/sizeof(arr[0]);
 printf("sz2 = %d\n", sz2);
}
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 int sz1 = sizeof(arr)/sizeof(arr[0]);
 printf("sz1 = %d\n", sz1);
 test(arr);
 return 0;
}

在这里插入图片描述
在函数内部,并没有正确求解数组元素个数,因为数组名是数组首元素的地址,所以数组传参的时候,传递的是数组名,即本质上数组传递的是数组首元素的地址,所以在函数内部无法求得数组元素的个数

void test(int arr[])//参数写成数组形式,本质上还是指针
{
printf("%d\n", sizeof(arr));
}
void test(int* arr)//参数写成指针形式
{
 printf("%d\n", sizeof(arr));//计算⼀个指针变量的⼤⼩
}
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 test(arr);
 return 0;
}

总结:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式

4.冒泡排序

核心思想:两两相邻的元素进行比较

void sort(int arr[], int sz)
{
	//确定冒泡排序的趟数
	int i = 0;
	for (i = 0; i < sz-1; i++)
	{
		//一趟冒泡排序
		int j = 0;
		for (j = 0; j <sz-1-i ; j++)
		{
			if (arr[j] > arr[j + 1])
			{//交换
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;

			}
		}
	}
}

void print(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = {9,8,7,6,5,4,3,2,1,0 };
	//排升序
	int sz = sizeof(arr) / sizeof(arr[0]);
	sort(arr,sz);
	print(arr, sz);
	return 0;
}

缺点:无论是否有序都要进行遍历

void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
 int i = 0;
 for(i=0; i<sz-1; i++)
 {
 int flag = 1;//假设这⼀趟已经有序了
 int j = 0;
 for(j=0; j<sz-i-1; j++)
 {
 if(arr[j] > arr[j+1])
 {
 flag = 0;//发⽣交换就说明,⽆序
 int tmp = arr[j];
 arr[j] = arr[j+1];
 arr[j+1] = tmp;
 }
 }
 if(flag == 1)//这⼀趟没交换就说明已经有序,后续⽆序排序了
 break;
 }
}
int main()
{
 int arr[] = {3,1,7,5,8,9,0,2,4,6};
 int sz = sizeof(arr)/sizeof(arr[0]);
 bubble_sort(arr, sz);
 for(i=0; i<sz; i++)
 {
 printf("%d ", arr[i]);
 }
 return 0;
}

优点:如果有序就不用继续遍历排序,提高效率

5.二级指针

指针变量也是变量,是变量就有地址,指针变量的地址存放在二级指针里
在这里插入图片描述

ppa通过对ppa中的地址进行解引用,这样找到的是pa,**ppa先通过ppa找到pa,在对pa解引用找到a

6.指针数组

指针数组是存放指针的数组
在这里插入图片描述
在这里插入图片描述

指针数组的每个元素都是用来存放地址(指针)的,指针数组的每个元素是地址,又可以指向一块区域

7.指针数组模拟二维数组

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
	int* parr[3] = { arr1, arr2, arr3 };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", parr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述

parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型一维数组,parr[i][j]就是整型一维数组中的元素

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

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

相关文章

研究生深度学习入门的十天学习计划------第七天

第7天&#xff1a;自然语言处理&#xff08;NLP&#xff09;中的深度学习 目标&#xff1a; 掌握自然语言处理的基础知识与深度学习模型&#xff0c;理解如何应用RNN、LSTM、Transformer等模型处理文本数据。 7.1 自然语言处理的基础概念 自然语言处理&#xff08;NLP&#…

Vue学习笔记 二

4、Vue基础扩展 4.1 插槽 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力在Vue中插槽是很重要的存在,通过插槽,我们可以把父组件中指定的DOM作用到子组件的任意位置,后面我们坐项目用到的组件库比如element-ui,vant-ui都频繁用到的插槽,Vue的插槽主要有…

【hot100篇-python刷题记录】【在排序数组中查找元素的第一个和最后一个位置】

R7-二分查找篇 目录 双指针 二分优化 ps: 思路&#xff1a; 双指针 直接用双指针回缩啊 class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:ret[-1,-1]left,right0,len(nums)-1while left<len(nums):if nums[left]target:ret[0]…

可解释性与公平性的关系

可解释模型更有可能公平的三个原因 可解释性和公平性似乎是相辅相成的。可解释性涉及理解模型如何进行预测。公平性涉及理解预测是否偏向某些群体。负责任的人工智能框架和机器学习会议始终将这两个特征一起提及。然而&#xff0c;可解释性并不一定意味着公平。 话虽如此&…

[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-26浅谈XILINX FIFO的基本使用

软件版本&#xff1a;VIVADO2021.1 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA 实验平台&#xff1a;米联客-MLK-H3-CZ08-7100开发板 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http…

9、Django Admin优化查询

如果你的Admin后台中有很多计算字段&#xff0c;那么你需要对每个对象运行多个查询&#xff0c;这会使你的Admin后台变得非常慢。要解决此问题&#xff0c;你可以重写管理模型中的get_queryset方法使用annotate聚合函数来计算相关的字段。 以下示例为Origin模型的中ModelAdmin…

Spring6梳理5——基于XML管理Bean环境搭建

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 ①搭建模块 ②引入配置文件 ③创建BeanXML文件 ④创建Java类文件&#xff08;User…

在K8s上运行GitHub Actions的自托管运行器

1&#xff1a;添加Actions Runner Controller的Helm仓库 helm repo add actions-runner-controller https://actions-runner-controller.github.io/actions-runner-controller helm repo update2&#xff1a;创建GitHub Personal Access Token (PAT) 登录到你的GitHub账户。访…

SQL语句(数据更新、查询操作)

数据库表操作 创建数据库语法格式 create table 表名(字段名1 类型 约束&#xff0c;字段名2 类型 约束&#xff0c;..... ..... )创建学生表&#xff0c;字段要求如下&#xff1a; 姓名&#xff08;长度为10&#xff09;、年龄、身高&#xff08;保留2位小数&#xff09; cre…

安卓shiply热更新入门

目录 一。我的开发环境 二。集成shiply热更新sdk 三。编写代码 1。创建一个CustomRFixLog类 2。创建一个MyApplication类 3。配置AndroidManifest.xml 4。创建一个新的Activity继承AbsRFixDevActivity 用于测试 四。登录shiply后台配置 1。创建项目 五。制作补丁 1。在app…

Ae关键帧动画基础练习-街道汽车超车

目录 1.让背景向左移动 2.让小红车匀速移动 3.实现小黄车的超车 完成街道汽车超车的一个简单动画&#xff0c;背景向左移动看起来就如同画面向右移动了一般&#xff0c;根据这个原理&#xff0c;可以完成这个动画。 导入素材时&#xff0c;要选择不同的图层&#xff0c;这样…

微软AD替代方案统一管理Windows和信创电脑的登录认证与网络准入认证

自国资委79号文明确了2027年底前信息系统全面国产化的目标后&#xff0c;金融单位、央国企集团及各子公司纷纷加大国产化改造力度。不少子、孙公司表示&#xff0c;集团要求到2024年底或2025年底国外的关键IT基础设施要停止使用&#xff0c;如微软AD、云桌面等。 信创国产化是大…

Mybatis链路分析:JDK动态代理和责任链模式的应用

背景 此前写过关于代理模式的文章&#xff0c;参考&#xff1a;代理模式 动态代理功能&#xff1a;生成一个Proxy代理类&#xff0c;Proxy代理类实现了业务接口&#xff0c;而通过调用Proxy代理类实现的业务接口&#xff0c;实际上会触发代理类的invoke增强处理方法。 责任链功…

艾体宝洞察丨透过语义缓存,实现更快、更智能的LLM应用程序

传统的缓存只存储数据而不考虑上下文&#xff0c;语义缓存则不同&#xff0c;它能理解用户查询背后的含义。它使数据访问更快&#xff0c;系统响应更智能&#xff0c;对 GenAI 应用程序至关重要。 什么是语义缓存&#xff1f; 语义缓存解释并存储用户查询的语义&#xff0c;使…

功率谱密度估计(Power Spectral Density Estimation, PSD)介绍,轴承磨损检测

介绍 功率谱密度估计&#xff08;Power Spectral Density Estimation, PSD&#xff09;是信号处理中的一项重要技术&#xff0c;用于描述信号在频率域中的能量分布。PSD提供了信号的功率随频率变化的情况&#xff0c;是分析随机信号和确定信号频率特性的常用工具。 功率谱密度…

美团代付支持多模板全开源多种支付通道 多模版三合一源码附教程

美团代付 支持多模板全开源多种支付通道 多模版三合一源码附教程 美团代付源码&#xff0c;支持多模板&#xff0c;全开源&#xff0c;多种支付通道&#xff0c;其它的就没什么好介绍的了&#xff0c;有兴趣的自行去体验吧。

驱动(RK3588S)第五课时:字符设备驱动编程

目录 一、操作系统的框架二、设备的类型三、什么是设备四、杂项字符设备的 API五、代码实现1、底层实现&#xff08;内核&#xff09;2、应用层代码3、交叉编译环境4、结果展示 一、操作系统的框架 二、设备的类型 硬件设备其实是分类型的&#xff1a; 字符设备&#xff1a;所…

TCP/IP 报文传输过程

目录 1. 概念理解2. 传输过程 原文回到 TCP/IP 强烈推荐下面博客&#xff0c;详细阐述了TCP/IP协议概念和传输过程 TCP协议详解 (史上最全) 1. 概念理解 2. 传输过程 以一个具体例子为例&#xff0c;如下图所示&#xff0c;由A 给 F 发送一个数据包整个过程是怎样的

Windows 安装 MySQL8

目录 前言 下载 安装 配置 连接 前言 一般数据库都是部署在 Linux 服务器上&#xff0c;在 Windows 上开发&#xff0c;通过数据库连接工具来连接数据库。在工作中&#xff0c;如果条件允许&#xff0c;会有单独的开发库给开发人员使用&#xff0c;否则开发人员就只能连接…

U盘损坏深度解析与高效数据恢复指南

一、U盘损坏现象初探 在数字化时代&#xff0c;U盘作为便捷的数据存储与传输工具&#xff0c;几乎成为了我们日常生活与工作中的必需品。然而&#xff0c;不少用户都曾遭遇过U盘损坏的困境&#xff0c;面对无法读取、文件丢失或系统提示错误等问题&#xff0c;往往感到束手无策…