php fun怎么用,函数的返回值返回到main函数后?
根据所用编译器和CPU的不同,以及返回值数据类型的不同,C语言中的函数返回值可能通过寄存器传递,也可能通过栈传递。对大多数CPU和编译器来说,出于性能考虑,能使用寄存器传递的,尽量使用寄存器传递,只有当寄存器不够用的时候,才会通过栈传递。
针对这两种情况,我分别举个x64 + GCC环境下的例子来说明。
通过寄存器传递返回值如下图中的一段简单的代码,返回值是一个有符号整数类型
我们看下x64/GCC下面对应的汇编代码:
test函数中的
1129: mov $0x2,%eax
便是把返回值2存放到eax寄存器中。而main函数中的
113d: callq 1125 <test>
1142: mov %eax,-0x4(%rbp)
则先调用test函数,然后把返回值从eax中取出,并存放到rbp 4的地址处,也就是赋值给局部变量a。
通过栈传递返回值下面这个例子中,test()函数返回一个结构体struct result。(注:这里只是为了演示用栈传递返回值,实际项目中不建议函数直接返回结构体,可以用结构体指针代替)
(这个例子第一眼看上去会有些许复杂,千万不要懵逼,汇编代码不是洪水猛兽,掌握一些基本的汇编代码对修炼内功、调试问题都是大有裨益的:)
在x64/GCC环境下的汇编代码如下:
先看main()函数:
我们先看main()函数中调用test()的几条指令:
ret = test();
11dd: lea -0x50(%rbp), %rax
11e1: mov %rax, %rdi
11e4: mov $0x0, %eax
11e9: callq 1135 <test>
11dd和11e1两条指令的作用是把栈地址rbp 0x50存放到rdi寄存器中,我们暂且不去管这个地址是用来做什么的,等看了test()函数之后自然就会明白。后面两条指令是把eax清零,然后调用test()函数。
test()函数的汇编代码如下:
test()的汇编看起来是不是有点复杂呢?不要紧张,其实做的事情很简单,就是给局部变量r分配栈空间,然后对它进行初始化,然后把r的值存放到一个内存地址当中,最后把这个内存地址放到rax寄存器中,并返回出去。我们仔细分析一下:
1139: mov %rdi, -0x28(%rbp)
这条指令是把rdi寄存器的值存放到栈空间rbp 0x28的地址处。还记得rdi寄存器中存放的是什么吗?回想一下,在main()函数调用test()函数之前,是不是把一个地址存放到rdi寄存器中了呢?忘了的话,再去看一下。我们先不管这个值用来做什么,只要记得,test()函数把main()函数传递过来的一个值存放到了一个栈地址当中。
接下来的这几条指令,就是对局部变量r进行初始化:
struct result r = {1, 2, 3, 4};
113d: movq $0x1, -0x20(%rbp)
1145: movq $0x2, -0x18(%rbp)
114d: movq $0x3, -0x10(%rbp)
1155: movq $0x4, -0x8(%rbp)
下面就要把r的值返回出去了,我们来看看编译器是怎么做的,先看这几条指令:
return r;
115d: mov -0x28(%rbp), %rcx
1161: mov -0x20(%rbp), %rax
1165: mov -0x18(%rbp), %rdx
1169: mov %rax, (%rcx)
116c: mov %rdx, 0x8(%rcx)
115d这条指令,是把栈中rbp-0x28处的值放到rcx寄存器中,还记得这个地址存放的值是什么吗?对了,就是test()入口处从rdi中取出来的那个值,也就是main()函数通过rdi寄存器传递给test()的一个值。然后,1161和1169两条指令把r.a值存放到rcx寄存器指向的地址处,1165和116c两条指令把r.b的值存放到rcx寄存器指向的地址再偏移8的位置处。
现在我们再来回过头想一下,main()函数通过rdi寄存器传递给test()函数的那个值是用来做什么的呢?对了,那个值其实就是存放test()函数返回值的那块内存的地址。
那么记下来的几条指令就比较容易理解了:
1170: mov -0x10(%rbp), %rax
1174: mov -0x8(%rbp), %rdx
1178: mov %rax, 0x10(%rcx)
117c: mov %rdx, 0x18(%rcx)
1170和1178把r.c存放到rcx + 0x10地址处,1174和117c把r.d存放到rcx + 0x18地址处。
到这里为止,test()函数已经把局部变量struct result r的所有字段的值全部存放到main()函数通过rdi寄存器传递给test()的那个内存地址中。
最后,看一下剩下的几条指令:
1180: mov -0x28(%rbp), %rax
1184: pop %rbp
1185: retq
1180指令把rbp 0x28处的值rax中,也就是把存放返回值的那块内存的地址,存放到rax寄存器中,最后返回出去。
到这里,是不是清晰多了呢?我们再来总结一下这个过程:
main()函数把一个栈空间中的地址rbp 0x30通过rdi寄存器传递给test()函数test()函数从rdi寄存器中取得这个地址,然后把要返回的值存放到这个地址指向的内存中test()把这个地址存放到rax寄存器中,并返回给main()函数掌握一定汇编知识的重要性可能对于很多童鞋来说,汇编语言比较晦涩难懂,难以掌握。确实,作为一个最为接近机器语言的编程语言来说,汇编确实比较晦涩,除了一些做底层系统软件的童鞋外,日常工作中直接用汇编写代码的机会确实不多,但是,这并不意味着掌握汇编语言就毫无用处。
掌握一定的汇编知识,会对整个计算机的原理和体系结构有更深入的理解,很多东西都能够知其然并知其所以然。尤其那些对底层系统软件感兴趣的童鞋,如BIOS/bootloader、OS内核、设备驱动、编译器、虚拟机等,汇编语言更是必须要掌握的。有些做上层应用的童鞋,如前端开发等,平时用到汇编的机会不多,但是在调试一些问题的时候,如果能够了解一些汇编知识,就会如虎添翼,事半功倍。
总之,不管所用的开发语言是C/C++还是Java、Python、PHP、Javascript,不管是做系统软件开发,还是做前端开发,只要是有志于干程序员这一行当的,掌握一定的汇编,对完善自己的技术知识体系,增强自己调试问题的能力,和对计算机体系结构的理解都大有裨益。
思考题能坚持读到这里,我想你已经基本清楚C语言的函数返回值是怎么传递的了。
那么,不妨思考一下,C语言的函数参数又是怎么传递的呢?😁欢迎留言,或者私信讨论,要是有人感兴趣,我可以写篇文章介绍一下。
最后,对这个问题有不清楚的地方,欢迎留言讨论。也欢迎关注,我计划在接下来的一段时间,更新一些偏底层的东西,如Linux kernel(e.g. memory management、process management、scheduling、timekeeping, etc.)、KVM/Qemu virtualization、compiler、debugger等,有兴趣的童鞋欢迎关注,互相交流学习。
可以推荐200价位左右的耳机吗?
感谢邀请,我来回答!
200元可以听歌音质不错的耳机我本人觉得是不存在的,如果只有200元预算的还不如用你手机自带的耳机听歌呢,没有多大的分别,然后把200元的投资放在播放端!
建议买入节奏坦克小金标!
小金标是一条内置了dac功放芯片的typec耳机转接线,支持最高24bit 192khz的解析率高清音源,信噪比达到了114dB,在手机端播放音质的提升是非常可观的,总的来说就算你用手机自带的耳机,只要在接上小金标后,你会有明显的感受同一首歌在有和没有接上小金标后听感是两个世界的,就算如果你是传说中的““木耳朵””你也能直接感觉音量的大小提升了,人声更加突出了,低音也有力气了!因为低音是人类耳朵最容易感觉到的部分,所以现在大部分的耳机都是通过低音的调教来吸引购买量的!
节奏坦克小金标价格也很便宜,只要129元,200剩下的你还可以去买条小米的动圈耳机来提升下耳机端的效果,这会比你买一条500甚至800左右的线性耳机有更明显你能感觉到的效果提升,这也是小金标一直缺货的原因!
再来听说魅族和16s也推出了一条typec转接口,比小金标的解析度更高,可以去到24bit 256khz!价格在169,不过我没有品质接触过亲身听过效果,所以我不敢太推荐给你,我怕连累了你!
小金标我个人是入手了一条的,就接上我S8时候送的Akg耳机一直在用,效果很明显,我S9 Note8 Note9 s10的耳机都还没打开呢!
小金标还可以进行刷机成三种模式,手机模式 音乐模式和手机音乐模式,第一种助力效果只有2成,然后手机音乐模式是5到6成,刷成音乐模式(不能通话)火力会全开,推荐这个模式,不过你的手机耳机插上就只能听歌不能通话了!
这是我的推荐
再次感谢邀请,只代表个人观点,欢迎讨论!
js如何直接调用后端php函数?
原则上前端html+js是不能直接调用后端php中的函数的并返回结果的。
菜农在学习网站编程后,就被此事困扰很长时间。
因为前端的js可以通过ajax技术带参数访问后端的php过程,并返回结果。
那么是否js也能带参数访问任意php函数并返回结果?
菜农在网友的指点下完成此设想并测试通过!
其核心思想是通过js的ajax调用php的call_user_func_array()函数,以实现任意php函数的调用。
特别注意:
为了网站的安全和防止黑客的攻击,特别设立了$funclst数组,js只能调用$funclst数组内的特定函数。
php核心代码为:
$funclst = array("f0", "f1", "f2", "a1", "a2", "a3", "a4", "HotCount");
$func = $_REQUEST["function"];
if(in_array($func,$funclst) && function_exists($func)){//只能调用例程函数
if(isset($_REQUEST["age"]) && strpos(strtolower($_REQUEST["age"]), "http://")){
echo "函数$func()的参数中包含非法字符!!!";
} else {
$age =isset($_REQUEST["age"])? explode(",",$_REQUEST["age"]) : array();//参数以","分割
echo call_user_func_array($func,$age);
}
}else{
echo "函数$func()不存在!!!";
}
javascript通过Ajax直接调用任意PHP函数多参数例程
菜农在网友的指点下完成此例程,非常感谢!!!
如图所示,前两个分别是html和php的源码(csv内存储了访问该测试函数的次数,即网站访问计数器。
人们都说泰国是个适合旅游的国家?
小麦也觉得是!!深度解剖泰式玩法!体验当地人水上生活!芭提雅最美浮潜地,跳无人三岛!
哈喽,麦友们好~
大家平时是不是除了工作日循规蹈矩地上班
回到家基本上就是“空调wifi西瓜,葛优躺”了呢?
这样的生活总是缺少点什么
毕竟这个世界充满了奇妙
还有更多的惊喜等着我们去发现啊!
怎么让你快速摆脱枯燥无味的生活呢?
来来来小麦给你支支招!
去旅行!
教你最地道的泰国曼谷新玩法!
泰式水上原生态生活,像个当地人一样逛市场
感受最地道的曼谷风情
小麦觉得在曼谷最能感受到的就是当地独具特色的水上市场了!那才是暹罗人真正的家,只有水才可以完美地展现他们自然民风、纯真性格和天赋!没有阔马扬鞭,只有乘船摇桨才是这个自由国度的独有的气质!
在泰国“逛市场”是游客必不可少的当地地道体验,古朴又接地气的集市非常具有泰国风情,这种传统方式的购物体验,可以让游客们更加深入地了解本地的风土人文~
充满着浓厚的泰国传统水上人家氛围的安帕瓦水上市场才是本地人的最爱!这里只有周末(周五、六、日)才会开放噢~
安帕瓦水上市场:有人说,这是最懂生活的地方
安帕瓦水上市场是泰国人最爱周末郊游目的地,市场集中了吃喝玩乐的泰国特色水上文化体验和真实市井生活,也是色彩斑斓的旅程中不能缺少的一抹颜色~在这里,你可以了解泰国当地居民的日常而又特别的生活情景,还可以品尝地道小吃和水果!
在两岸热带树木茂盛的运河里,载着蔬果小吃的船在水道里穿梭~船上,戴着独特草帽的曼谷阿姨们大声地吆喝叫卖。在这里,你会真切地感受到泰国的真正模样!
寻找安帕水上市场的萤火虫
除了琳琅满目的商品之外,安帕瓦水上市场最具特色的莫过于晚上的“找寻萤火虫”之旅,这里也被称为“萤火虫之乡”噢!夜幕降临,搭乘小船,整个天空都被萤火虫光亮所照耀,让你感觉仿佛置身于梦幻的童话故事之中!
被菩提庇护的树中寺庙
安帕瓦树中庙,誉为泰国十大最灵验的庙之一,被巨大榕树根包围,墙壁与树木融为一体。树庙古朴斑驳,浑然天成,香火鼎盛。赶紧虔诚许愿,说不定就能实现哟!
被铁道横贯的当地市场
深入体验地道泰国味
火车穿梭在摊贩中的有趣奇景
只因为一条铁道穿过市场,摊贩在火车经过前后要收放摊位,就让美功铁道市场成为引人注目的景点,以致每年都有不少游客慕名而来看火车经过,并混在当地人中购买水果和品尝小吃噢~
美功铁道市场位在曼谷西南边约100公里左右的近郊区,搭車约1个半小时~2小时左右可到达,小麦很建议可以把美功铁道市場+安帕瓦水上市場及丹嫩莎朵水上市场排在同一天,因为都相隔很近,可以利用包車的方式前往比较方便及省时啦~
生活气息满满的美功铁道市场,每天生意都很好,当地人餐桌上的新鲜食材大部分都来自这里!
当火车缓慢开过铁道的时候,商贩都会娴熟的收起摊位,游客们忙着用手机或相机拍照,最有趣的是火车司机也很配合,会像个明星一样不停和游客挥手,偶尔还来个热情的击掌~
跳岛无人三岛,畅玩芭提雅最美浮潜地
以最大限度玩尽芭提雅
在芭提雅附近可供游人游玩的有格兰岛,沙美岛,无人三岛(林岛,猴岛,竹岛),前两个岛都十分的热门,最不为人们所熟知的就是无人三岛,无人岛是近几年开发出来适合浮潜的,看猴子的小岛!小麦迫不及待要给大家讲讲~
竹岛
以浮潜著名,有各种漂亮的珊瑚群和海洋生物
竹岛以浮潜最为著名,有几个未受外界干扰的沙滩,有各种珊瑚群和海洋栖息地,在这里进行浮潜、海钓、游泳、戏水,幸运者钓到的鱼还可以在船上进行烧烤,哇真的太棒了!!
林岛
泰国海军时序基地,非常好的浮潜和海钓区域
林岛也是一个无人岛,该岛是泰国海军时序基地,有壮丽的珊瑚礁石,可以享受原始岛屿的野性,是非常好的浮潜和海钓区域噢!
鸭岛
尽管你看不到一只鸭子,但是猴子却比比皆是
又叫猴子岛,鸭岛非常多猴子,这里的猴子非常欢迎游客们的到来,可以在这里跟猴子拍照、喂猴子噢!
游玩猴岛时注意这些顽皮的猴子会抢你的帽子和眼镜,建议上岛把身上的配饰收到随身的包里噢!如果想增加和猴子的互动还可带一些水果上岛~
在活色生香的芭提雅,享受世外桃源般度假
所有喧闹隔绝在酒店外
芭提雅的灯红酒绿比你想象的还要凶猛,闹市区的马路上永远都是满满的荷尔蒙气息,但是不管怎么说,芭提雅都是一个气候宜人的海滨度假城市,当然不能少了安静宜人的度假酒店啦!
芭提雅安凡尼度假酒店作为闹市中的清净园,虽身处繁华红尘,酒店自有大隐隐市的清新脱俗!酒店与芭提雅海滩和步行街都只有一街之隔,不管是享受安静度假,还是闹市繁华,都能满足你!
酒店造型很特别,连通大型购物中心,很适合放松休息,美味的餐点、宜人的环境、完善的设施,足不出户就能享受度假~
谢谢观赏~喜欢可以关注WX号:麦趣自由行 或者 麦趣自由行Fun
C语言能干什么?
从功能上来讲,任何其他编程语言能够做的事情,C语言都可以做到。
对于入门来说,推荐学习C语言,毕竟这是绝大多数程序员的入门语言。C语言语法简单,易于学习。
现在广泛流行的绝大部分语言,如Java、Python、Lua、Javascript、Go等这些编程语言,都是在C语言的基础上衍生而来的。而且,这些语言开发在之出的第一个版本的编译器,往往也是采用C语言开发的。因此,这些语言能够实现的功能,C语言全部都可以实现。
但是,随着计算机技术的发展,现代软件项目的规模越来越大,实现的复杂程度越来越高,软件开发周期越来越长。有些大的软件项目,可能需要几千人花费几年的时间来开发。在这样的背景下,为了提高开发效率,缩短软件开发周期,降低软件的维护成本,一些更为高效的语言应运而生。注意,这里说的高效,是指开发效率,不是软件运行效率。
现在流行的高级语言,如Java、Python、Go等,相比C语言来说,提供了很多提高开发效率的高级特性,如面向对象、动态类型、垃圾回收等。这些特性大大缩短了软件的开发难度,降低了开发成本。
小结简单总结一下,C语言适合开发一些对性能要求很高的的系统软件,如BIOS、操作系统、编译器、数据库、基础库等。其他诸如Java、Python等语言,适合开发规模较大、复杂度高、对性能不是非常敏感的上层应用软件。
一些入门的建议很多想学习编程或者刚开始学习编程的童鞋,往往会纠结于什么编程语言是最好的,最好的IDE工具是什么,或者哪个版本的语言最好用等等诸如此类的问题。当然,尚未入门的童鞋,对编程还没有什么很具体概念,这些问题也在情理之中。
但是,对于入门来说,最重要的是培养对编程开发的兴趣,尽快找到编写程序的感觉。可以适当了解一下各种编程语言的特点,但是不要过于纠结。
我的建议是,选择一个绝大多数程序员入门的语言(通常是C或Python),然后从最简单的“Hello World”开始,由浅入深,循序渐进,尽快了解并掌握语言的基本语法,然后逐渐培养程序开发的兴趣和感觉。
做软件开发这一行,个人认为兴趣是最重要的,有兴趣才会有动力持续、深入的学习。一旦没有了兴趣,技术上不可能达到很高的乘次,编程也会变成一种煎熬。
希望对你有用!对编程开发感兴趣的童鞋,欢迎关注我!