【C初阶——指针2】鹏哥C语言系列文章,基本语法知识全面讲解——指针(2)

news2025/5/24 9:25:20

崩刃的剑,依旧致命,锈蚀的盾,屹立如初(王者荣耀李信)
本文由@睡觉待开机原创,转载请注明出处。
本内容在csdn网站首发
欢迎各位点赞—评论—收藏
如果存在不足之处请评论留言,共同进步!

这里写目录标题

  • 前言
  • 1.数组名的理解
    • 1.1数组名、取地址数组首元素与取地址数组名的区别
    • 1.2数组名的正确理解总结
  • 2.从本质上理解数组与指针的关系
  • 3.一维数组传参的本质
  • 4.冒泡排序
  • 5.二级指针
  • 6.指针数组
  • 7.指针数组模拟二维数组

前言

本节博客继续来探讨关于指针初阶的相关基础内容

1.数组名的理解

1.1数组名、取地址数组首元素与取地址数组名的区别

数组名是数组首元素的地址。
取地址数组名取出来的是整个数组的地址。

也就是说arr==&arr[0]!=&arr

我们可以来简单做个测试:

//数组名的理解

int main()
{
	int arr[10] = { 0 };

	printf("p1 = %p\n", arr);
	printf("p2 = %p\n", &arr[0]);
	printf("p3 = %p\n", &arr);

	return 0;
}

在这里插入图片描述

结论:完全一致!!!
但是,有些同学可能就好奇了,作者你不是说arr!=&arr吗?结果是一样的啊。的确在单单看这个地址结果是一样的,但是但是,我们对这些地址进行+1操作你就会发现前两者是一样的,但是第三者是不同了:

int main()
{
	int arr[10] = { 0 };

	printf("arr = %p\n", arr);
	printf("&arr[0] = %p\n", &arr[0]);
	printf("&arr = %p\n", &arr);
	printf("指针+1操作:\n");
	printf("arr+1 = %p\n", arr+1);
	printf("&arr[0]+1 = %p\n", &arr[0]+1);
	printf("&arr+1 = %p\n", &arr+1);

	return 0;
}

在这里插入图片描述
好好看一下,就发先前两者+1之后都是加了4个字节的地址,第三个变成加了40个字节的地址哈。

那为啥呢?
指针类型的意义:指针类型决定了指针+1操作跳过多少字节。
因为前两者的指针类型都是int类型的,第三者的类型是int()[10],两种指针类型指向内容的类型大小不一样,前者是4个字节,后者是40个字节!

1.2数组名的正确理解总结

数组名就等同于数组首元素地址,&数组名是整个数组的地址,虽然数组首元素的地址和整个数组的地址从地址结果上来看是一样的,但是指针类型是不同的!
但是有1个例外:
sizeof(数组名):这种情况计算出的为整个数组的大小

2.从本质上理解数组与指针的关系

其实有了指针,我们就可以用指针来访问数组了。

//数组与指针的本质联系
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *p);
		p++;//指针p在第十次循环中越界
		if (i == 9)
			p = NULL;
	}
	return 0;
}

在这里插入图片描述
但其实,指针访问跟用数组下标访问本质上是一样的:

//数组与指针的本质联系
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int i = 0;
	//数组下标
	printf("arr[i]: >\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	//一般指针
	printf("\n");
	printf("*(p+i)\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p+i));
	}
	printf("\n");
	printf("\n");

	printf("上面得出结论:arr[i]==*(p+i)==*(arr+i)");
	printf("\n"); 
	printf("\n");
	//指针换一种写法
	printf("\n");
	printf("加法符合交换律,*(i+p)\n");
	
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(i+p));
	}
	printf("\n");

	printf("so,i[p]这种写法也可以吧::\n");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", i[p]);
	}
	printf("\n");
	return 0;
}

在这里插入图片描述
说白了编译器在处理arr[i]的时候,也是会把他转换成*(arr+i)进行处理的。

3.一维数组传参的本质

说起一维数组传参来说,可能很多人会以为我们传数组的时候会直接把整个数组传过去,实际上不然。

//一维数组传参的本质
void test(int arr[10])
{
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	test(arr);
	return 0;
}

在这里插入图片描述
按照道理来说不应该是1 2 3…10吗?怎么只有一个数字1呢?
我们调试一下来看看哪里出现了问题:
在这里插入图片描述
什么?这个sz怎么给我算出来了个1啊!
原来传进去的是arr中的第一个数字的地址而已
在这里插入图片描述

那他是怎么找到后面的数字的呢?
答案很简单,因为数字都是连续存放的,找到第一个数字的地址之后,顺藤摸瓜即可。
其实,一维数组传参也可以改写成这样:

void test(int* arr)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	test(arr);
	return 0;
}

在这里插入图片描述

4.冒泡排序

紧接着,我们来科普一下最基本的一个排序算法哈,冒泡排序
核心思想是两个相邻的数字进行比较
这里不重点说这个,简单一提。

void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
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);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	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 i = 0;
	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.二级指针

啥是二级指针?
指向一级指针的指针变量。
在这里插入图片描述
大概示意图如下:
在这里插入图片描述

6.指针数组

首先问个问题哈,指针数组是数组还是指针啊?
为了让大家好理解呢,我举个例子,好孩子是好还是孩子啊?好孩子也是孩子吧。
那么答案就很明确了,指针数组也是数组,只不过这个数组里放的是指针而已。

//指针数组
int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	int* pa = &a;
	int* pb = &b;
	int* pc = &c;
	int* arr[3] = { pa,pb,pc };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%d ", *arr[i]);
	}
	return 0;
}

在这里插入图片描述
大概示意图是这样滴:
在这里插入图片描述

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

指针数组比较典型的例子还得是模拟二维数组的这个代码了。
下面来进行代码展示:

//指针数组模拟二维数组
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };

	int* arr[3] = { arr1,arr2,arr3 };

	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", *(*(arr+i)+j));
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述
当然,我这里用指针和数组下标还可以进行杂交处理一下,其实数组下标就是指针而已,不同的写法罢了:
在这里插入图片描述
当然了,为了同学们便于理解,我还是来画个图给大家瞅瞅:
在这里插入图片描述

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

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

相关文章

能翻页的电子图册怎么做

​随着科技的进步&#xff0c;电子图册已经成为了越来越多企业宣传和展示产品的重要工具。相比于传统的纸质图册&#xff0c;电子图册具有更多的优点&#xff0c;如方便携带、易于分享、可交互性强等。那么&#xff0c;如何制作一款能翻页的电子图册呢&#xff1f; 一、确定主题…

INT201各种题型收集

汇总一下 FA 有穷自动机 - RL正则语言 DFA M (Q, Σ, δ, q, F) Q 是有限状态集合&#xff08;Finite Set of States&#xff09;&#xff1a; 这表示自动机中存在一个有限数量的不同状态。每个状态代表了自动机在某个特定时刻的内部状态。这些状态可以用符号或名称表示。 …

基于多反应堆的高并发服务器【C/C++/Reactor】(中)Buffer的创建和销毁

TcpConnection:封装的就是建立连接之后得到的用于通信的文件描述符&#xff0c;然后基于这个文件描述符&#xff0c;在发送数据的时候&#xff0c;需要把数据先写入到一块内存里边&#xff0c;然后再把这块内存里边的数据发送给客户端&#xff0c;除了发送数据&#xff0c;剩下…

内存的基础知识-第四十天

目录 什么是内存&#xff1f;内存的作用 常用的数量单位 指令的工作原理 思考 三种装入方式 绝对装入 可重定位装入&#xff08;静态重定位&#xff09; 动态运行时装入&#xff08;动态重定位&#xff09; 写程序到程序运行 编译和链接 链接的三种方式 本节思维导…

代码随想录27期|Pthon|Day31|贪心算法|理论基础|455.分发饼干|376. 摆动序列|53. 最大子序和

理论基础 首先&#xff0c;贪心算法基本靠“做题感觉”&#xff0c;所以没有规范的总结和做题技巧&#xff0c;只能说见到过之后还能想起来。 一般情况可以看成是对于一个大的问题的子问题的局部最优的求解&#xff0c;然后可以推导出全局的最优。 这个过程没有证明&#xf…

数据库中的几种锁

数据库锁 1.数据库锁的种类 以 mysql innoDB 为例&#xff0c;数据库的锁有 排他锁&#xff0c;共享锁&#xff0c;意向锁&#xff0c;自增锁&#xff0c;间隙锁&#xff0c;锁的范围有包括&#xff0c;行锁&#xff0c;表锁 &#xff0c;区间锁。 从应用研发的视角&#xff…

Gromacs WARNING问题

上述示例中&#xff0c;NA 是对系统净电荷进行中和的阳离子。请根据您的系统特性和仿真需求调整这些值。 总体而言&#xff0c;这个警告是为了提醒您关于电荷中性化的问题&#xff0c;确保您的模拟结果更加物理可信。 收敛性未达到预期精度&#xff1a; 警告指出&#xff0c;优…

普中STM32-PZ6806L开发板(HAL库函数实现-访问多个温度传感器DS18B20)

简介 我们知道多个DS18B20的DQ线是可以被挂在一起的, 也就是一根线上可以访问不同的DS18B20而不会造成数据错乱, 怎么做到的&#xff0c;其实数据手册都有说到&#xff0c; 就是靠64-bit ROM code 进行识别, 也可以理解成Serial Number进行识别, 因为主要差异还是在Serial Numb…

成为一名合格的软件测试工程师,得掌握什么技能?

在这个信息时代&#xff0c;软件行业的需求空前增长&#xff0c;而软件测试工程师作为软件开发过程中的重要角色&#xff0c;也越来越受企业的重视。那么&#xff0c;成为一名合格的软件测试工程师需要掌握什么技能呢&#xff1f;我结合多年的教学经验为大家总结出以下几点。 …

Fast and flexible X-ray tomography using the ASTRA toolbox

使用ASTRA工具箱进行快速灵活的X射线断层扫描 论文链接&#xff1a;http://dX.doi.org/10.1364/OE.24.025129 项目链接&#xff1a;https://astra-toolboX.com/indeX.html Abstract 从一系列投影图像中重建物体&#xff0c;如在计算机断层扫描(CT)中&#xff0c;是许多不同应…

nuxt3 env文件、全局变量处理

有两种方向 通过配置nuxt.config.ts Nuxt提供的钩子函数&#xff0c;实现全局变量的获取 runtimeconfig env文件往runtimeconfig放入内容 useAppConfig 通过env文件配置来获取服务端全局变量&#xff0c;客户端通过vite.define实现 nuxt.config.ts Nuxt钩子 1. runtim…

Unity ab包如何加密

「ab包」全称为 AssetBundle &#xff0c;是Unity提供的一种资源存储压缩包。其中储存了游戏的资源&#xff0c;如图片、模型、纹理、音视频、代码等文件。 由于ab包具有灵活储存、支持热更、包体较小且便于管理等优势&#xff0c;已经成为了市面上主流的游戏资源压缩方式。 …

李沐机器学习系列4---全连接层到卷积

1 从全连接到卷积 1.1 平移不变性 从概率分布的角度来看卷积的定义, f ( τ ) f(\tau) f(τ)是概率密度&#xff0c; g ( t − τ ) g(t-\tau) g(t−τ)是在这个分布下的均值 ( f ∗ g ) ( t ) ∫ − ∞ ∞ f ( τ ) g ( t − τ ) d τ (f*g)(t)\int_{-\infin}^{\infin}f(\t…

2024/01/02 每日AI必读资讯

减少LLM幻觉的方法 这篇论文总结了减少LLM幻觉的32种方法&#xff0c;包括RAG、微调模型&#xff0c;提示词工程等。 论文&#xff1a;https://arxiv.org/abs/2401.01313E5-mistral-7b-instruct&#xff1a;使用合成数据训练的Embedding模型 亮点是仅使用LLM生成的数据即可实现…

指令流水线的计算

我们需要知道以下公式&#xff1a; 设指令的条数为 n&#xff0c;指令执行需要 m 个阶段&#xff0c;时钟周期为 t 不采用流水线执行的时间&#xff1a;T1 n x m x t&#xff1b; 采用流水线执行的时间&#xff1a;T2 m x t (n - 1) x t&#xff1b; 加速比 S T1 / T2&…

PTA——逆序的三位数

程序每次读入一个正3位数&#xff0c;然后输出按位逆序的数字。注意&#xff1a;当输入的数字含有结尾的0时&#xff0c;输出不应带有前导的0。比如输入700&#xff0c;输出应该是7。 输入格式&#xff1a; 每个测试是一个3位的正整数。 输出格式&#xff1a; 输出按位逆序…

MacOS M1/M2 Go Debug 配置

前言 换电脑&#xff0c;Go 环境带来一些麻烦&#xff0c;耽误很多时间&#xff0c;稍作记录。 原始电脑是 Mac 旧款&#xff0c;CPU x86 构型&#xff0c;新电脑 M2&#xff0c;因为旧电脑里本地文件很多&#xff0c;为了简化搬迁&#xff0c;还是用了 Mac 自带的迁移&#x…

LeetCoed刷题:21. 合并两个有序链表

题目&#xff1a; 是否独立解出&#xff1a;否 解题时的思路与想法&#xff1a;解题时有几个问题&#xff1a; 1.怎么遍历两个数组&#xff0c;嵌套两个while循环不能实现&#xff08;后面通过看题解知道list1&#xff01;null&&list2&#xff01;null&#xff09; …

旋转图像(LeetCode 48)

文章目录 1.问题描述2.难度等级3.热门指数4.解题思路参考文献 1.问题描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在「原地」旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。 示…

知虾分析——深入了解Shopee平台的知虾分析工具

Shopee是一家知名的电商平台&#xff0c;为了帮助卖家提高业务表现&#xff0c;他们提供了一款强大的数据分析工具——知虾分析。这个工具可以帮助卖家监控店铺的运营状况&#xff0c;优化销售策略&#xff0c;并提高整体的业务表现。本文将深入解析知虾分析的关键功能和用途&a…