C语言指针详解(2)(能看懂文字就能明白系列)

这篇具有很好参考价值的文章主要介绍了C语言指针详解(2)(能看懂文字就能明白系列)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C语言指针详解(2)(能看懂文字就能明白系列),C语言笔记,c语言,开发语言,经验分享,笔记,学习

系列文章目录

能看懂文字就能明白系列
C语言笔记传送门
🌟 个人主页:古德猫宁-

🌈 信念如阳光,照亮前行的每一步



前言

前面有篇文章简单的介绍了指针及其一些简单的运算和野指针,指针提供了一种以符号形式使用地址的方法。因为计算机的指令非常依赖地址,指针在某种程度上把程序员想要传达的指令以更接近机器的方式表达。因此,使用指针的程序更有效率。尤其是指针能有效地处理数组。数组表示法其实是在变相地使用指针。


一、数组名的理解

数组名是首元素的地址

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &arr[0];

这里我们使用&arr[0]的方式拿到了数组第一个元素的地址并赋值给指针变量p,但是其实数组名本来就是地址,而且是数组首元素的地址,我们来做个测试。

#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;
}

按照上面的说法,大家觉得结果是否一样

C语言指针详解(2)(能看懂文字就能明白系列),C语言笔记,c语言,开发语言,经验分享,笔记,学习
我们发现数组名和数组首元素的地址打印出的结果一模一样,数组名就是数组⾸元素(第一个元素)的地址。

数组名如果是数组首元素的地址,那下面的代码怎么理解呢?

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

运行结果:
C语言指针详解(2)(能看懂文字就能明白系列),C语言笔记,c语言,开发语言,经验分享,笔记,学习
按照上面所说,数组名是数组首元素(第一个元素)地址,那运行的结果应该是4/8才对,怎么变成40个字节了。
其实数组名就是数组首元素(第一个元素)地址是对的,但是有两个例外:

  1. sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)

除此之外,任何地方使用数组名,数组名都表示首元素的地址。

那各位再看看下面的代码

#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);
printf("&arr    = %p\n", &arr);
return 0;
}

运行结果:
C语言指针详解(2)(能看懂文字就能明白系列),C语言笔记,c语言,开发语言,经验分享,笔记,学习
我丢,三个的结果一样,那arr和&arr有什么区别呢?
不要急,请接着往下看

#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[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);
return 0;
}

C语言指针详解(2)(能看懂文字就能明白系列),C语言笔记,c语言,开发语言,经验分享,笔记,学习
这里我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1相差4个字节,是因为&arr[0]和arr都是首元素的地址,+1就是跳过一个元素(这里是int类型,所以是4个字节)。

但是&arr和&arr+1相差40个字节,这就是因为&arr是数组的地址,+1操作是跳过整个数组的。

下面的等式就体现了C语言的灵活性:

//arr + 2 == &arr[2];相同的地址
//*(arr+2)==arr[2]相同的值

以上关系表明了数组和指针的关系十分密切,可以使用指针标识数组的元素和获得元素的值。
从本质上看,同一个对象有两种表示法。实际上,C语言标准在描述数组表示法时确实借助了指针。也就是说,定义arr[n]的意思是*(arr+n)。可以认为*(arr+n)的意思是“到内存的arr位置,然后移动n个单元,检索储存在那里的值”。

特别注意的是:
不要混淆*(arr+2)和*arr+2。解引用运算符(*)的优先级高于+,所以*arr+2相当于(*arr)+2

//*(arr + 2);arr第三个元素的值
//*arr + 2;arr第一个元素的值再加2

二、使用指针访问数组

明白了数组和指针的关系,我们来练习一下

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	//输⼊
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//输⼊
	int* p = arr;
	for (i = 0; i < sz; i++)
	{
		scanf("%d", p + i);
		//scanf("%d", arr+i);//也可以这样写
	}
	//输出
	for (i = 0; i < sz; i++)
	{
		printf("%d ", p[i]);
	}
	return 0;
}

运行结果:
C语言指针详解(2)(能看懂文字就能明白系列),C语言笔记,c语言,开发语言,经验分享,笔记,学习
将*(p+i)换成p[i]也是能够正常打印的,本质上p[i] 是等价于 *(p+i)。
同理arr[i]应该等价于*(arr+i),数组元素的访问在编译器处理的时候,也是转换成首元素的地址+偏移量求出元素的地址,然后解引用来访问的

三、一维数组传参的本质

假设要编写一个处理数组的函数,该函数返回数组的元素之和,那应该如何调用该函数呢?

total=sum(arr);我们可能是这样调用函数的

那么,该函数的原型是什么呢?前面说过,数组名是首元素的地址,所以实际参数arr是一个存储int类型值的地址,应该把它赋值给一个指针形式参数,即该形参是一个指向int的指针。

int sum(int* arr);//对应的函数原型

sum()从该参数获得了该数组首元素的地址,知道要在该位置上找出一个整数。
注意,该参数并未包含数组元素个数的信息。
我们有两种方法让函数获得这一信息:
第一种方法是,在函数代码中写上固定的数字大小

int sum(int* arr)
{
	int total = 0;
	for (int i = 0;i < 10;i++)
	{
		total += arr[i];//arr[i]和*(arr+i)相同
	}
	return total;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int ret = sum(arr);
	printf("%d", ret);
	return 0;
}

既能用指针表示数组名,也可以用数组名表示指针。
该函数定义有限制,只能计算10个int类型的元素。
另一个比较灵活的方法是把数组大小作为第二个参数:

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

这里,第一个形参告诉函数该数组的地址和数据类型,第二个形参告诉函数该数组中元素的个数文章来源地址https://www.toymoban.com/news/detail-792187.html


到了这里,关于C语言指针详解(2)(能看懂文字就能明白系列)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详解 matplotlib.pyplot ,Python 初学者真能看懂

    Matplotlib 是一个 Python 中的 2D 绘图库, pyplot 模块是一个方便使用 Matplotlib 的接口。 下面是 pyplot 模块中的五个重要的知识点: 【创建图形】: pyplot 模块提供了许多简单易用的函数来创建图形,如 plot、scatter、bar、hist 等。这些函数可以绘制不同类型的图形,例如散点图、折

    2024年02月02日
    浏览(35)
  • 二维前缀和&二维差分(超详细,python版,其他语言也很轻松能看懂)

    上一篇文章讲解了一维前缀和一维差分,本篇进阶为二维。 二维前缀和跟一维前缀和求法相同,这里直接上例子。 数组a = [[1,2,2,1],[3,2,2,1],[1,1,1,1]] a数组如图: 则数组a的前缀和为:数组b[[1,3,5,6],[4,8,12,14],[5,10,15,18]] b数组如图: 前缀和递推公式为 b[i][j] = b[i - 1][j] + b[i][j - 1]

    2024年04月22日
    浏览(28)
  • TCP/IP协议族之TCP、UDP协议详解(小白也能看懂)

            在进行网络编程之前,我们必须要对网络通信的基础知识有个大概的框架,TCP/IP协议族涉及到多种网络协议,一般说TCP/IP协议,它不是指某一个具体的网络协议,而是一个协议族。本篇章主要针对IP协议、TCP和UDP协议记录总结。 OSI七层参考模型是国际标准化组织(

    2024年02月02日
    浏览(32)
  • 接口自动化测试要做什么?8个步骤讲的明明白白(小白也能看懂系列)

    先了解下接口测试流程: 1、需求分析 2、Api文档分析与评审 3、测试计划编写 4、用例设计与评审 5、环境搭建(工具) 6、执行用例 7、缺陷管理 8、测试报告 那\\\"接口自动化测试\\\"怎么弄?只需要在上篇文章的基础上再梳理下就可以。为更好理解\\\"接口自动化\\\"具体操作流程,最

    2024年03月09日
    浏览(43)
  • 【外行也能看懂的RabbitMQ系列(三)】—— RabbitMQ进阶篇之死信队列(内含视频演示业务和业务代码)

    准备篇 RabbitMQ安装文档 第一章 RabbitMQ快速入门篇 第二章 RabbitMQ的Web管理界面详解 第三章 RabbitMQ进阶篇之死信队列 第四章 RabbitMQ进阶篇之通过插件实现延迟队列 恭喜所有看到本篇文章的小伙伴,成功解锁了RabbitMQ系列之高级特性 死信队列 的内容🎁通过本文,你将清楚的了解

    2024年02月07日
    浏览(30)
  • YOLOv8预测参数详解(全面详细、重点突出、大白话阐述小白也能看懂)

    YOLOv8现在可以接受输入很多,如下表所示。包括图像、URL、PIL图像、OpenCV、NumPy数组、Torch张量、CSV文件、视频、目录、通配符、YouTube视频和视频流。表格✅指示了每个输入源是否可以在流模式下使用,并给出了每个输入源使用流模式的示例参数 预测参数 Key Value Description s

    2024年02月11日
    浏览(31)
  • 【计算机视觉】YOLOv8参数详解(全面详细、重点突出、大白话阐述小白也能看懂)

    comments description keywords true Master YOLOv8 settings and hyperparameters for improved model performance. Learn to use YOLO CLI commands, adjust training settings, and optimize YOLO tasks modes. YOLOv8, settings, hyperparameters, YOLO CLI commands, YOLO tasks, YOLO modes, Ultralytics documentation, model optimization, YOLOv8 training YOLO 设置和超参数

    2024年02月05日
    浏览(37)
  • 包看包会Stable Diffusion原理,新手也能看明白

    知道看文章的人怎么看,听我讲的人经常反应的就是听不明白。于是我又在网上找了一下,发现这篇文章讲的很好,算得上是深入浅出,可惜是英文的,就把它翻译了一下: https://stable-diffusion-art.com/how-stable-diffusion-work/ 在翻译的过程中,我增加了自己的一些东西,调整了一些

    2024年02月09日
    浏览(32)
  • 小白也能看懂的ChatGPT知识介绍

    ChatGPT 是一款由 OpenAI 开发的人工智能技术驱动的语言模型应用。以下是 ChatGPT 的主要特点和功能: 自然语言处理:ChatGPT 可以识别和理解自然语言,包括英语、法语、德语、西班牙语等多种语言。它可以回答各种问题、提供各种建议,并与人类进行自然的对话。 语言模型:

    2024年02月06日
    浏览(35)
  • 深入浅出讲解Stable Diffusion原理,新手也能看明白

    最近一段时间对多模态很感兴趣,尤其是Stable Diffusion,安装了环境,圆了自己艺术家的梦想。看了这方面的一些论文,也给人讲过一些这方面的原理,写了一些文章,具体可以参考我的文章: 北方的郎:图文匹配:Clip模型介绍 北方的郎:VQGAN(Vector Quantized Generative Adversar

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包