技术标签: C语言
在c语言中,如果想要通过函数调用来改变值,有两种方式,第一种是通过指针的传递来改变值(这种可以一次改变多个变量的值),第二种是通过方法的返回值来传递值。第一种,中传递的时候其实只是地址的传递,相对第二种的值传递来说,第一种的效率要高不少,因为第一种传递的是地址,四个字节(部分计算机)大小的地址。特别,是在c中做字符串的处理时,这种第一种情况用的非常的多,我当时也是在做字符串处理的时候遇到这些问题,然后下面我会举例,还有一些思想方法。
一、通过函数调用来交换值(一级指针)
void exchangeValue(int* a,int* b){
//交换的时候,还是要通过第三个变量来交换两个变量的值
int temp = *a;//a的值,也就是x的值,因为我们是将x的地址传给了a,所以a就指向了x,同理b也是如此
*a = *b;
*b = temp;
}
int main(){
int x = 10;
int y = 20;
exchangeValue(&x,&y);
cout << x << endl;//这两句话是c++中的输出,为了方便就没写printf了
cout << y << endl;//输出结果是20和10
system("pause");
return 0;
}
上面的程序可以实现x和y值的交换,不知道大家,有没有这样想过,在exchangeValue方法中,为什么不能这样写
int* temp = a;
a = b;
b = temp;
这样能改变x和y的值吗?下面我们就来探讨一下这个问题
void exchangeValue(int* a,int* b){
//交换的时候,还是要通过第三个变量来交换两个变量的值
int* temp = a;//a的值,也就是x的值,因为我们是将x的地址传给了a,所以a就指向了x,同理b也是如此
a = b;
b = temp;
cout << "a地址:" << a << endl;//a的地址:00E4FB64
cout << "b地址:" << b << endl;//b的地址:00E4FB70
}
int main(){
int x = 10;
int y = 20;
cout << "x地址:" << &x << endl;//x的地址:00E4FB70
cout << "y地址:" << &y << endl;//y的地址:00E4FB64
exchangeValue(&x,&y);
cout << x << endl;//这两句话是c++中的输出,为了方便就没写printf了
cout << y << endl;//输出结果是10和20
system("pause");
return 0;
}
下面的这个方法也可以改变x和y的值,但是不是通过方法调用改变的,只是为了深入分析一下指针问题
int main(){
int* x = (int *)malloc(4);//这里必须的为指针变量x分配空间
*x = 10;
int* y = (int *)malloc(4);
*y = 20;
//交换x和y的内容(并不是交换他们的值所指向的内容)
int *temp;
temp = x;
x = y;
y = temp;
cout << *x << endl;
cout << *y << endl;
system("pause");
return 0;
}
二、跨函数使用内存之二级指针
1、跨函数调用通过二级指针来给一个指针变量赋值,跨函数分配内存
void test(int **a){
*a = (int*)malloc(sizeof(int));//这里其实在给指针变量x开辟空间,相当于在main方法中的int* x = (int*)malloc(sizeof(int));
**a = 10;
}
int main(){
int *x;
test(&x);
cout << *x << endl;
system("pause");
return 0;
}
//根据第一个分割的字符串分割str字符串,返回分割字符串之前的部分和之后的部分
void str_split(char *str,char * strsubstring,char ** str_before,char ** str_after){
*str_before = (char*)calloc(strlen(str),1);//为以str_before的内容为地址的字符串开辟空间并赋初值
//malloc和calloc都是为指针变量开辟内存,malloc不会为开辟的空间初始化保留的是垃圾数据,而calloc会初始化
*str_after = (char*)calloc(strlen(str),1);//用calloc的原因是为了避免产生乱码
char * s = strstr(str,strsubstring);//根据第一个strsubstring进行分割,返回的是从strsubstring开始的一个首地址
//如果字符串str中没有strsubstring这个被分割的字符串
if (s==NULL){
**str_before = '\0';
**str_after = '\0';
}else{
//如果被分割的字符串刚好位于字符串的开头部分
if (strlen(s) == strlen(str)){
* str_after = s;//如果不想要分割的字符串可以这样写,* str_after = s+strlen(strsubstring);
**str_before = '\0';
//被分割的字符串刚好位于字符串的结尾部分
}else if (strlen(s)==strlen(strsubstring)){
int i = 0;
int flag = (strlen(str) - strlen(s));
while (i < flag){
*(*str_before + i) = *(str + i);//如果能理解这句代码的含义,说明真正弄懂了二级指针的含义
i++;
}
**str_after = '\0';
//被分割的字符位于字符串的字符串的中间
}else{
* str_after = s;
int i = 0;
int flag = (strlen(str) - strlen(s));
while (i < flag){
*(*str_before + i) = *(str + i);
i++;
}
}
}
}
上面的图就是str_before的一个二级指针图,对于指针问题,如果不是很清楚的时候,画图理解是一个很好的方法。其中以0X开头的是内存单元的一个8位十六进制的地址。我上面的图画的不是很标准,因为在计算机中内存是一个字节大小的存储单元,也就是8位。而像0XAABB33DD这个值需要四个字节来存储,而地址一般是存的首地址。通过上面的图,我们再思考一下为什么*str_before[1]会报异常呢?因为,在c语言中[]的优先级要高于*,这样的话,*str_before[1]的意思就是,0XAABB33DD这个单元的第二个数据,而str_before[0]等于0XAABBEE11,str_before[1]这个值根本就不存在,所以导致报异常,如果改成这样(*str_before)[1]就没有问题了。现在,再来解释一下*(*str_before+i),*str_before指的就是0XAABB33DD这个单元,*str_before指向的就是0XAABBEE11中的第一个 字符,*str_before+1指向的就是0XAABBEE11中的第二个字符。而**str_before就等于字符a,*(*str_before+1)就等于字符b。最后,说一下个人感悟,作为一个程序员肯定是会遇到问题,在遇到问题的时候,怎么去高效的解决问题,这就体现了一个程序员的能力。我当时,遇到这个问题的时候,就只是想着在网上一顿乱搜,最后也没能找到答案,时间也浪费了,问题还没解决。我觉得,当我们遇到问题的时候,首先应该静下来仔细考虑想想整个程序的逻辑是怎么样的,理解每句代码究竟是什么意思。然后,再去找问题在哪,这样才能提高一个程序员解决问题的能力。最后,如果实在想不出来的话,可以请教他人,再想想自己还有那些知识点没弄明白,然后再去补短,这样才能有所提高。上面纯属个人见解,如有问题尽请留言。
文章浏览阅读178次。本篇文章由泉州SEOwww.234yp.com 整理发布,mssql数据库www.234yp.com/Article/168188.html谢谢合作!mssql数据库 Boost SQL Performance with cursor_sharing 关键词:cursor_sharing 概述 本文阐述在Oracle8i Release 2和Oracle9i中增强的游标共享设施。这些增强功能被一个新的参数cursor_sharing控制。 cursor_sharin...
文章浏览阅读135次。**一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。**使用1.输入图片颜色返回一张图片icon.image = [UIImage createImageWithColor:[UIColor blueColor]];2.裁切图片的一个点进行延伸[btn setBackgroundImage:[UIImage _ocuiffx
文章浏览阅读221次。一、安装xlrd地址下载后,使用 pip install .whl安装即好。查看帮助:>>> import xlrd>>> help(xlrd)Help on package xlrd:NAMExlrdPACKAGE CONTENTSbiffhbookcompdocformattingformulainfolicencessheettimemachinexldatexlsxFUNCTIONScou..._"file \"c:\\program files\\python38\\lib\\site-packages\\xlrd\\__init__.py\", line 17"
文章浏览阅读1.9k次。一套既美观又方便的后台框架可以大大幅节约开发时间和成本,本文推荐 6 款漂亮、功能强大的后台模板。01.vue-element-adminvue-element-admin 是一个后台模板,它基于 vue 和 element-ui 实现,可以帮助你快速搭建企业级中后台产品原型。功能非常丰富,几乎囊括了你见过的所有组件元素,可以通过下面这个链接体验一下。地址:https://panjiachen.github.io/vue-element-admin地址:https://github.com._好看的静态网页模板github
文章浏览阅读9.3k次。1)运行此命令:import sysfrom PIL import Imagesys.modules['Image'] = Image2)在笔记本中运行以下两行,以确保它们正确指向同一目录(如果不是因为你的PIL旧库弄乱了Pillow库)from PIL import Imageprint(Image.__file__)import Imageprint(Image.__file__)3)如果它正常工作并且两个导入打印指向同一个python3目录,那么继续.如果不,转到您的操作系统_from pil import image报错
文章浏览阅读8.2k次,点赞5次,收藏27次。一、借鉴基础知识: MOS管基础知识百度文库链接:https://wenku.baidu.com/view/fc0a7d2eccbff121dd3683b2.html 首先,我并没有转载某知名博主的文章,只是觉得PPT的图片截取的还可以; 其次,博客地址:https://blog.csdn.net/zhengyanan815/article/deta..._p沟道mos管电流方向
文章浏览阅读2.1k次,点赞2次,收藏6次。Oracle 21cCentOS 安装Oracle 21c_centos7安装oracle21c
文章浏览阅读3.9w次,点赞39次,收藏174次。Code Review(CR)即代码评审,又名代码走查,是一种通过复查代码来提高代码质量的过程,一般体现在一个团队的开发过程中。CR要求团队成员有意识地、系统地检查彼此的代码,从而验证需求、发现错误,同时指出其中不合规范的“低质量”代码,从而提高整个团队的代码质量。一次 CR 可以是一次 Commit,也可以是一次 Merge Request。因此,实践课系统支持团队内部的 MR 评审以及 Commit 评审,供大家学习和交流。..._code review
文章浏览阅读2.1k次。1.报错内容 、 *** Please tell me who you are. Run git config --global user.email "[email protected]" git config --global user.name "Your Name" to set your...
文章浏览阅读3k次,点赞2次,收藏5次。开始直接上效果图不墨迹直接上代码html<!DOCTYPE html><!-- This code is for demonstration purposes only. You should not hotlink to Github, Rawgit, or files from the Cytoscape.js documentation in you..._cytoscape.js 网络推普图
文章浏览阅读4k次。今天用android Q版本做文件写入适配操作,报了标题的错,具体报错如下:2021-04-29 20:40:54.078 22377-22377/com.example.ringtone E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.ringtone, PID: 22377 java.lang.IllegalArgumentException: Primary directory audio not al_java.lang.illegalargumentexception: primary directory sounds not allowed for
文章浏览阅读10w+次,点赞217次,收藏892次。虽然学深度学习有一段时间了,但是对于一些算法的具体实现还是模糊不清,用了很久也不是很了解。因此特意先对深度学习中的相关基础概念做一下总结。先看看前向传播算法(Forward propagation)与反向传播算法(Back propagation)。1.前向传播如图所示,这里讲得已经很清楚了,前向传播的思想比较简单。 举个例子,假设上一层结点i,j,k,…等一些结点与本层的结点w有连接,那么结点_反向传播算法