C语言指针——2021-06-03

本博主会随着学习的深入而逐渐的去完善指针的相关内容,也欢迎大家和我一起学习进步!

指针就是地址!!!

指针在c语言中有着举足轻重的地位,是C语言的精髓,是C语言的灵魂。这样说一点也不为过,那么指针究竟是什么呢?
指针就是地址!上课的时候老师一直在强调这句话要外化于形,内化于心,说的再通俗一点就是,如果把目标访问数据当做我们的宝藏,那么指针就好比是藏宝图。

1,指针用法

指针的定义

定义指针变量时,与一般变量最大的不同就是前面会有目标访问符" ∗ * ",在函数的说明语句板块你会看到不同的定义方式,如下面列举的几种

int *p1
double *p2
char *p3   
....

研究指针一定要清楚的就是内存的概念,也就是存储的形式和所占用的空间。
特别注意
1,指针变量在内存中所占用的字节数一般为4或8个字节,(这个由编译决定,大家可以使用函数sizef()来查看地址变量的字节数)
口说无凭,上代码:(我的占了8个字节)

#include <stdio.h>
int main()
{
   int *p,a,n;
	a=10;
	p=&a;         //&取地址的操作符
	n=sizeof(p);
   printf("%d",n);
   return 0;
}

结果显示:在这里插入图片描述
2,C语言中的地址信息中既包含位置信息,也包含它所指向的数据的类型信息。
前面定义的 i n t , d o u b l e , c h a r int , double,char int,double,char是“通知”编译器我们所定义的指针变量所指向的数据类型,他们所占的字节数还是原来字节数, i n t int int占4个, d o u b l e double double占8个, c h a r char char占1个……而指针变量对应的字节数是不会改变的
容易理解错的是,误以为前面的数据类型会影响指针变量所占的字节数。
3,I have a problem.指针到底是什么类型呢,嘻嘻,就是指针类型!

简单使用

试图用简单的操作来说明一些问题:交换两个变量的值

#include <stdio.h>
int main()
{	void swap(int *plt1,int *plt2);
    int *p1,*p2,a,b;
	a=4,b=8;
	printf("\n交换前:a=4,b=8\n");
	p1=&a;
	p2=&b;
	swap(p1,p2);
	printf("交换后:a=%d,b=%d\n",*p1,*p2); //*p1<=>a
   return 0;
}
void swap(int *plt1,int *plt2)
{
	int m;
	m=*plt1;
	*plt1=*plt2;
	*plt2=m;
}

代码说明:
swap()函数通过对变量a,b所对应的存储区的数据进行交换,从而达到了交换a,b数值的功能实现。虽然在调用函数的时候新开辟的存储空间中会在调用结束后释放,但指针的强大之处就在于,能通过指针这个媒介对main函数里的数据进行修改。
结果展示:
在这里插入图片描述

错误展示:

void swap(int *p1,int *p2)
{
	int m;
	m=p1;
	p1=p2;
	p2=m;
}

void swap(int a,int b)
{
	int m;
	m=a;
	a=b;
	b=m;
}

这两个函数放在一起看,二者都是对接受的变量进行了交换,而没有对mian函数中的变量进行作用,我们知道在函数调用结束后,内存会进行释放,所以该函数模块就“操作了个寂寞”,什么也没干。

2, 指针引用数组

指针引用一维数组

我们知道C中函数不能通过 r e t u r n return return去返回一批数据,两个也不行。
数组是一批具有相同数据类型变量集合,在内存中占用连续的存储空间,以同一个名字命名,用下标加以区分。其实数组的访问本质上就是指针的偏移。那我们为什么还要引入指针的概念来处理数组呢?这里只是对指针的一个简单应用,指针的魅力远大于此,比如文件指针等。
——例题1,将数组a中的n个整数按相反顺序存放,如图所示操作:
在这里插入图片描述

解题思路,通过相应位置值的交换达到逆序输出的目的,实现过程中会涉及到的很多干货,请爱学习的你耐心看下去吧。
先看代码吧,
解题一:

#include<stdio.h>
int main()
{	void swap(int arr[],int m);
	int arr[10]={1,2,3,4,5,6,7,8,9,10},i;
	swap(arr,10);
	for(i=0;i<10;i++)
	{
		printf("  %d",arr[i]);
	}
	return 0;
}
void swap(int arr[],int m)
{
	int zh,i,j,n=(m-1)/2;
	for(i=0;i<=n;i++)
	{
		j=m-1-i;
		zh=arr[i];arr[i]=arr[j];arr[j]=zh;
	}
}

解题二:

#include<stdio.h>
int main()
{	void swap(int arr[],int m);
	int arr[10]={1,2,3,4,5,6,7,8,9,10},i;
	swap(arr,10);
	for(i=0;i<10;i++)
	{
		printf("  %d",arr[i]);
	}
	return 0;
}
void swap(int *p,int m)
{	
	//相当于p=arr,把数组的地址给了p 
	int *h,*i,*j,n=(m-1)/2,zh;
	i=p;j=i+m-1;h=p+n;
	for(;i<=h;i++,j--)
	{	
		zh=*i;*i=*j;*j=zh;
	}
	return;
}

在这里插入图片描述
两者的操作结果是一样一样的,其实原理也一样。
干货number one:
指针的具体指向问题。
在这里插入图片描述
干货number two
指针的偏移问题
指针的偏移加减操作,并不是一个字节一个字节地去移动,而是根据你所定义的指针所指向的类型数据去移动该数据类型的数据所占字节数。 而不是简单的进行一个字节的偏移。
简单点举个例子:
在这里插入图片描述
干货number three
数组引用时形如 [ ] [ ] []的叫做变址运算符,即将a[i]按a+i计算地址,然后找出地址单元中的值,这就不难理解为什么 a [ i ] ⟺ ∗ ( a + i ) a[i]\Longleftrightarrow *(a+i) a[i](a+i)了。这里也会设计后面多维数组的指针引用章节的学习理解,大家应该注意。

指针对多维数组的引用

这里先讲一个比较重要的概念,一个关于C程序员的内功提升的点。
我们知道计算机对于一维数据的存储是占用连续的存储空间的,那对于多维的数据又是怎样存储的呢?
(以二维数据为例)像我们平时所见到的二维平面的存储形式:这样???
在这里插入图片描述
NO NO NO!!! 在内存里不存在的,操作系统只会提供连续的存储空间,尽管你在函数说明语句就已经“通知”它你要存二维数组了,可他是真没能力去给你开垦耕地。
接下来引入“降维”的概念:
这里简单点说就是,一维套一维来实现多维。我们可以这样理解,
比如有一个二维数组arr[3][4],在存储时就为一个有三个元素的一维数组,并且三个元素是包含四个数据的一维数组。在内存中仍占用连续的存储空间。
这一点是要先声明的,我们接下来讨论的指针引用二维数组可能会误导大家认为存储的真实形式,切记占用连续的存储空间
提笔还真不知道从哪写起……
还是先从最经典的这张图谈起吧!
在这里插入图片描述
我们看到这个二维数组与一维数组引用最大的不同是引入了行列索引的指向,也就是上面横线箭头与竖向箭头。
下面放上几个地址的表示,帮助大家更好地理解

表示形式含义
a二维数组名,0行起始地址2000
a[0]$12
导管$1
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小威程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值