i have used ai thousands of time what's the biggest border neck in achieving general artificial intelligence applying the existential the artificial intelligence is science fiction i was arrogant what's the biggest border neck in achieving general artificial intelligence every problem come down to moving data the computers are fast enough, but we can't move the data through the computing system and in those thousand cycles you could have done a tremendous amount of computing if everything was right where it should be what is the real catalyst that led you from electrical engineering to this cryptography stuff phone gets an update from apple how does it know that it came from apple and not from a memo of one person current logest trend is ai and it also poses many threats the security to privacy and or this kind of things do we have any comments on that yes, it's an ex said that artificial intelligence poses an existential threat too humanity that this is crazy in fact ed is said applying the e word existential to artificial intelligence in science fiction a lot of students they are worried about their future if their job will be replaced by the ai a lot of people are thinking that well ai will change education, but question is will it replace the faculty member and i don't think so what makes a good faculty member is not how bright they are, but if they care about the success of their students and if you replace the faculty member with an ai program you're just eliminated the most important part of an education i was optimistic now about ai when i was using ai in december 2022 almost nobody is using it, but they're saying, but aren't you frightened it doesn't tell you the truth it makes mistakes i say yes my friends make mistakes as well play passion in a problem i think you have to be prepared to be out of your comfort zone, it's going back you get one life to live, don't waste it figure out what you enjoy and have an enjoyable life。 参加这个世界顶尖科学家论坛,有一个和诺奖对话的机会,而且刚才他还找我要了我的抖音号, 哈哈哈,粉丝加一。因为这些诺奖得主,他们也经常做一些科学传播的工作,我们也能从他们的说法里面汲取一些养分,来反哺到我们的作品当中去。 我们学计算机的都知道鉴定性时间复杂度吗?那我当然知道,这个是由他提出来的。能跟这么一位顶尖的科学家交谈,当时是非常兴奋的。我刚跟 martin hellman 聊完,然后我现在感觉心情还是挺激动的。 因为以往的话,你在课本上学到的这些名字都是很很有树立感的,可以跟 money hell 们真的聊起来。我可以问他,你当初是怎么想到这个问题的?这种获得答案的求知感非常非常的快乐。
粉丝535.0万获赞1.0亿

可以带回家的工作来了哈,你想做吗?地址呢?就在我们城北的中央公园小区华宏电子厂啊,现在这里招女普工。 要求呢很简单,就是视力好一点,年纪是十八到四十五岁都可以哦,时间自由,学会了就可以带回家,也可以在公司做好,有意者呢可以关注我或者是留言哦。

这两天,科技圈最火的名词莫属 ai 龙虾,腾讯大厦排起了长队,小米发布手机龙虾,这股热潮究竟在追捧什么呢?这只俗称龙虾的 openclaw 本至少是一个开源的 ai 智能体。和以往只会聊天的 ai 不 同, 它的核心突破在于动手执行,你可以把它理解为一个七乘二十四小时待命的数字。实习生给他权限和指令,他就能自主地操作电脑, 替你写周报、处理邮件、分析数据,甚至是编写代码。比如有的自媒体博主让他盯着点热点自动写稿,有金融从业者用他每晚自动整理几十页的研报,甚至有创业者让 ai 分 身管理量化交易。当然,目前的龙虾也并非无所不能, 它仍然有使用门槛,而且由于需要极高的系统权限,隐私和安全问题也不容忽视。工信部门最近也发布了相关的安全风险预警。说到底, ai 龙虾代表的是一种趋势, 人工智能正在从嘴替进化为手替,它极大的提升了工作效率,但也考验了我们驾驭工具的能力。所以,你会选择一只龙虾来饲养吗?让我们拭目以待这时代的趋势。


云南话红科技股份有限公司包食宿,购买五险一金。招聘财务文员等岗位,专科以上学历,男女不限,十八到四十五岁,月薪五千到七千元。地址,昆明经开区洛阳街道关注私聊领取报名资料。

二零二六年开年,半导体大戏就开始上演了。今天主角是国内芯片制造的二哥华鸿半导体,他官宣要花超过八十二亿,把自家兄弟公司华丽微电子几乎全部拿下。 这可不是简单的买卖,背后站着的卖家清一色是国家队,上海华鸿集团、上海集成电路产业基金,还有咱们熟悉的国家大基金二期都赫然在列。你可能想问,华鸿为啥要搞这么大动静?我给你打个比方,这就像是把原来分开训练的两个特种兵小队合并成一个全能作战旅。 以前华宏和华立威都在做五十五纳米到四十纳米这个区间的芯片,难免有些左右互搏。现在合二为一,不仅内部竞争没了,关键是产能、技术、客户全部打通。 简单说,收购完成后,华宏直接就能多出每月三点八万片的十二英寸晶元产能。在芯片行业,产能就是硬实力,更重要的是,华立威在逻辑芯片工艺上的积累,能和华宏原本最拿手的功率器件嵌入式存储技术形成强力互补,一站式解决客户更多需求。 我们把眼光放大一点,你会发现华鸿这部旗正好踩中了两个关键节点。第一是政策的东风。国家工信部刚刚在部署二零二六年工作时,明确提出要打造集成电路等新兴支柱产业,并且要深入整治行业内内卷式的低质竞争。 华鸿这次的内部整合,就是典型的提升集中度,避免内耗的 u 等生操作。第二是资本的浪潮。有券商大佬已经预言,二零二六年并购重组将成为核心投资主线之一, 尤其在半导体这种硬科技行业,自己埋头研发固然重要,但通过并购整合、快速做强已经成为头部玩家的标准动作。华鸿这次可以说是打响了新年行业整合的第一枪。当然,市场从来都是用真金白银投票的,国际大头行高盛早在去年九月就已经把华鸿半导体的评级调高到了买入他们 看好的理由里。除了行业需求,很重要的一点就是华鸿持续的产能扩张与技术升级,比如预计在二零二七年导入更先进的二十八纳米工艺。这次收购无疑是给这个成长故事加了一个重磅助脚。 不过咱们也得冷静,任何一场大型并购,最大的挑战永远在婚后的整合,两家公司的技术团队如何高效融合,庞大的产线如何协调调度,这些实实在在的问题,决定了一加一能否真正大于二。另外,华鸿公司当前的估值水平也处于高位,市场给予了很高的期待, 这份期待最终需要并过后实实在在的业绩增长和盈利提升来兑现。回顾华鸿的历史,他本身就是一部中国半导体产业的突围史。从国家九零九工程的起点,到后来果断从存储芯片转型京元代工的遵义会议,再到如今成为全球功率七件代工的领头羊, 他的每一步选择都紧密贴合着国家产业发展的脉搏。这一次,在政策鼓励、资本助推、行业需求多重因素共振下,华鸿的这次重磅整合, 或许正是中国芯片制造走向更节约、更强大之路的一个缩影。那么你看好这次国家对加持下的半导体行业整合吗?你认为华鸿能否顺利消化这次收购,真正成为国际特色公益芯片代工的巨无霸?

大家好呀,最近科技圈有个特别火的网红,不是什么新手机、新电脑,而是一只叫 openclock 的 电子龙虾。 你可能会好奇,一只电子龙虾有啥了不起?别急,这背后可藏着 ai 发展的大趋势呢。以前咱们聊 ai, 可能更多想到的是 ai 帮我们写文案、画画,也就是深沉内容。 但这只电子龙虾不一样,它代表着 ai 开始从动动嘴皮子迈向动手干实事的新阶段了,也就是能自己执行任务啦。就像咱们请了个智能小助手,以前他可能只会帮你记笔记、写邮件, 现在他能直接帮你处理一些具体的工作了。多家机构都认为,随着国内科技公司也开始跟进这类龙虾产品,这种叫 agent 智能体的应用会越来越多地进入我们的真实工作场景。这意味着什么呢? ai 的 调用频率会大大增加,模型调用量也就是偷看消耗也会显著提升。打个比方,以前可能只是偶尔叫 ai 帮个忙,以后可能就像我们每天用手机一样,频繁地使用 ai 来处理各种事情。 所以啊, ai 产业链的关注重点也在悄悄转移,以前可能更多看哪些 app 用了 ai, 现在呢?从能执行任务的智能体、运行的底层算力基础设施, 甚至到怎么让计算和电力更协同的新型基础设施建设,这些环节都可能出现新的产业机会。是不是觉得科技发展越来越有意思了,这只电子龙虾说不定就是一个新的起点呢?你觉得未来 ai 还能帮我们做哪些具体的工作呢?来评论区一起聊聊吧!

哈喽,我是源哥,今天咱们聊聊国内存储芯片最核心的十家公司,都是实打实的行业大佬。第十名,深科技。这家是国内做存储风测的龙头,像长鑫存储、 sk 海力士、美光这些大厂都是他的合作伙伴。他主要干 d r m。 风测、 h b r m 风装, 还有硬盘磁头制造制造,给存储芯片提供封测加模组一条龙服务。在此插播一句,如果以后想看源哥研究哪个行业,欢迎留言。第九名,花红公司,它是特色工艺精髓制造的龙头,是长江存储 n a n d。 代工的核心伙伴, 也给国内其他公司做车规级存储芯片代工。他专门给长江存储造 nnd flash, 还在十二英寸厂布局了先进制程,实力很强。第八名,德明利,这家专注做存储主控芯片和存储模组, 自研的 ssd 主控芯片在国内实战率排第三。他的 pci 4 zero ssd 主控芯片通过了长江存储的验证, 企业级内存模组还进了华为鲲鹏服务器的供应链。第七名,百维存储。它推出了全球首款十二 tb qlc ssd, 专门用在 ai 数据中心,产品覆盖公车规及 ssd、 ddr 四 ddr 五内存条、五内存条嵌入式存储业务占比接近百分之六十, 还提供先进封测服务。第六名,东新股份,它是国内少数能同时做 n a n d n o 二 d l m 全品类存储芯片的企业, 其中 n a n d flash 业务占比百分之五十七, d r m e 占百分之十,布局很全面。第五名,联云科技,它是国内 s s d。 主控芯片的龙头, 长江存储江波龙头部比店品牌和服务器客户都是它的合作伙伴,还是它还布局了 a l t 信号处理芯片 产品,覆盖消费级、企业级、工业级全场景。第四名,江伯龙,作为国内存储,长江存储、华为、小米都有合作, 它能做消费级、企业级嵌入式全品类存储,还具备设计加封装加测试的全能能力。第三名,北方华创,它是半导体设备的平台型企业,是长江存储长期存储的核心设备供应商, 也服务中心国际。在存储领域,它的课时机 pvd 设备覆盖了三 d n a n d d r m h b m 全产业链制造环节。 第二名,蓝启科技,它是全球内存接口芯片的龙头,英特尔、 amd、 美光、英伟达这些国际大厂都是它的合作伙伴。它主导了 ddr 四、 ddr 五接口芯片的标准制定,现在重点聚焦 ai 服务器和数据中心场景。 第一名,赵毅创新,它是国内存储设计的绝对龙头,合作伙伴包括长兴存储、特斯拉、比亚迪等车规级客户。 它覆盖了 n o r flash 立体型、 d r m m c u 三大核心赛道,同时还在布局三 d n a z 存储芯片。温馨提示,以上内容只是知识分享,不构成任何投资建议,投资有风险,大家一定要谨慎哦!

欢迎大家收看二零二六年全新制作的切入式开发系统教程。为了制作这套课程,我不仅翻遍了 b 站几乎所有的课程,甚至还去 youtube 观看国外的老师做的切入式开发教学视频。 总结下来,我发现百分之九十以上的视频都整的鱼龙混杂,滥竽充数,而且很少有一步步带着你一起做,并且详细讲解单片机实战的教程。所以我决定摒弃所有花里胡哨,用最原始、最直观、最纯真的方式呈现出来,能让大家 最直接、最快速的吸收,并且最大程度上的活学活用。所以我综合了切入式的所有知识点,用更有趣味性的课堂表述,加上知识和实操相结合的实际案例,十三个月终于做出了这样的课程,让你真正体会到什么是每一秒都在疯狂输出知识。 我们这套课程呢,会从基础篇、境界篇和项目实战篇等三大方面来讲解。第一阶段基础篇包括了 c 语言、 linux 操作系统、数据结构与算法、 linux 操作命令和算法的编程与实现。接下来是嵌入式应用的学习片,你将掌握 linux 文件、 r u 标准用 法、并发程序设计和网络编程实战等,用最易懂的方式带你入门。嵌入式开发学习提升篇学习 c 家家面向对象编程以及 u t 侵入式图形开发,并结合当下热门的音视频开发和 open 七 v 实战,逐步学习 a r n 体系结构和接口技术。系统移植、侵入式内核驱动开发全套,从而帮助我们更有效的进行故障排查和错误调试,使用内核日制调试工具和跟踪技术来定位问题, 提高驱动程序的质量和可能性。我还会提供整套课程相对应的思维导图,让大家不用来不及记笔记而烦恼。实战篇会手把手带着大家练习企业级的落地项目,比如智能工业分解系统、智能交通系统、智能机器人系统、 互联网智能家居系统等等,从而帮助大家更好的应对人工智能时代的挑战。最后呢,会给大家一个小福利,课程视频中的所有素材 有搭建嵌入式开发环境工具包,还有嵌入式学习路线图,几十上百集素材,电子书学习课间面试题和项目实战等等,只要你能想到的素材我这里几乎都有,评论留言六六六 即可全部免费打包带走。相信我,这套嵌入式系统教程将会是全网最齐全最懂的小白专用课。如果看到这里对你有所帮助的话,请给 up 主免费的一键三连吧,让更多想要学习嵌入式开发的小伙伴都能看到这个视频。 hello, 大家好,欢迎来到沁州市零基础课堂,我是乐游,那么从本节课开始,我们就正式开始沁州市的学习了,那在沁州市当中呢, c 语言的作用可谓是直观重要的啊,所以我们将会从 c 语言进行学习。 那对于有些小伙伴来讲的话啊,我们去学习一门新的编程语言,那肯定不能只学习他的皮毛吗?对不对啊,特别是我们这种 c 语言偏底层的语言。所以我们在学习 c 语言的时候呢,我们要去学习他底层的这一个逻辑和一些实现原理, 那这样子的话呢,其实会更好的帮助我们去理解他的一些运行,以及在后续的学习当中啊,我们对于硬件操作能够起到帮助, 对吧?啊,所以我们学习社语言会从底层去带大家一起学习。十卷 n copy 就 出现了。十卷 n copy 的 作用是什么呢?十卷 n copy 的 作用就是去指定哎, n 个字节我只拷贝这么多,对吧? 啊,注意它是字节啊,它不是数组的这个元素数量,它是字节数啊,比如说 int 类型的话是四个字节为一个 int 类型嘛,对不对啊?那么你如果十个的话就是四十个啊,这样的一个过程,我们计算的时候一定要以字节去计算啊 啊,读出来的会补零啊,这个是注意事项,大家可以了解啊,到时候老师就认识求知不穿的长度啊,他是遇到反向杠零结束啊,就不包含反向杠零以及反向杠零后面的数据, 对吧?啊?比如说这里的实训十啊,然后全部都是零,那么你去实训认识他的话呢,他的结果就是零啊,就零 就没有就没有长度嘛,对不对啊?但这是拷贝的,还有什么呢?还有拼接的啊,拼接就是把原兽师的这个字母串啊,给他拼接到我们的目标字母串的后面,哎,后面怎么去定义呢?就是以反斜杠零的那个位置开始去进行拼接啊,他会把反斜杠零替换为 原字母串的第一个字母,然后以此类推哎,给它拼接上去。呃吧。啊,同样也包含一个时俊 ncat 的 一个字母啊,当然还有什么呢?还有时俊 c m p 和时俊 n c m p compare 嘛, 对比啊,就是我们要比较两个字母串,你自己去写 f 循环对比的话很麻烦啊,所以它有一个 compare 的 这样一个函数可以提供给我们去使用啊,我们直接调用就可以了,当然函数现在我们可能还没接触到,对吧,我们下一节课就会去学习函数了啊, 这里我们先知道啊,先了解它有这么多一些函数提供给我们去使用,我们在下一节课的时候呢,我们会带着大家一起去使用这些函数。各位, 哈喽,大家好,欢迎来到沁州市零基础课堂,我是乐游。好,那么其实,呃,经过前面几节课的学习呢,我相信大家已经把自己的这一个计算程序已经优化的比较好了,对不对啊?我们可以去进行一个呃,多位数的一个计算对不对?哎,但是呢, 虽然我们可以去进行多位数的计算了,但如果说啊,你像我们这个程序哎呦,把它搬过来再写啊, 我们这个程序的话呢,它是从外函数从上往下我们去编写的这样一个程序逻辑对不对啊?那这一堆东西呢,都是用来做一个数据运算的,那如果说我想在这个下面我再去进行一个数据运算的话,那我是不是又得把这一个东西哎给他 放到这里来对,复制一份吗?那这样的话就会显得我们整个程序很臃肿,档案码呢,有很多重复的地方,这个重复的东西呢,他明明可以不重复的,但是我们把它重复了对不对啊?这个在我们开发过程当中呢,叫做熔鱼啊,熔鱼就是重复了吗?对不对?重复的东西太多了, 好了,我们能不能去解决这一个重复性的一个东西,对不对啊?比如说这里是运算数据的啊,运算我这一个数据的一个结果的,那我只想要这一堆东西, 那这一种东西,然后呢?我运算的时候呢,我就去使用它,我不运算的时候呢,我就放在那边就可以了,对不对啊?同时呢,它在整个慢函数里面呢,它也不会说显得很杂很乱,对不对?我把它搞到一个,搞到一块去,对吧?啊?最后它只要返回一个结果给我,或者提供一个结果给我了,对不对啊?这样子是不是就 ok 一 点, 对吧?好,那编程语言,也就是我们 c 语言啦,或者说很多的这种编写 编辑程序的语言,他们为了能够去避免这种重复的劳动力,也就是我重复的去写相同的代码,对不对啊?所以呢,他就干嘛呢?他就引入了一个叫做函数的概念,那么函数呢?也就是我们本节课需要学习的一个重点内容。 函数啊,我们叫功能模块啊,功能模块 function, 在 c 语言当中的话呢,这个函数它其实就是完成某个特定功能的一个子类序集的集合的封装啊,可能这个这句话比较专业性啊,什么叫子类序集的这一个集合封装呢?首先每一 条语句啊,我们这里每一条代码,每一条语句,它其实就是一条指令啊,它去操作我们系统的一个 cpu 或者内存的,对不对啊?它是一条指令,那么多条指令在一起呢?它其实就是一个集合嘛,对不对?我们从上往下这些指令按顺序去执行,它可以完成某个功能的话呢,它就是一个指令续集, 那我就把这一些指定续集集合呢?我给它放到一块去,对不对?我们这里是放到了 main 这个函数里面,对不对?好,那我们放到一块,我放到我 main 函数,它是一个主程序啊,它是一个主函数, 是所有的程序都要从慢函数开始执行,对不对?那我不可能把这一些内容丢到慢函数,丢到这个主函数里面啊?我能不能放到另外一个地方呢?对不对?好,那么这个函数就起到了这么一个作用,就是我们可以把我们这一堆计算数据的这一些指令续集啊,把它封装到另外一个函数里面去, 所以函数的作用呢,就是把我们的指令续集做一个封装,做一个整合,对啊,整合完了之后我们去使用这个函数呢,哎,他就能够去执行那个里面的这些指令,对吧?然后呢完成我们需要完成的功能。 所以说函数的作用其实就是干什么的?函数的作用就是实现代码的一个复用啊,符合我们程序开发的这一个高内聚低偶合的一个 要求啊?什么叫高内聚,对吧?啊?我们的更多的功能它是比较内聚的,比较集合的低偶合的话呢,就是功能与功能之间他们不会有太多的关联,就是每一个功能它独立开来的话,也可以独立运行,对不对?他们不需要有太多的这一个偶合在里面啊?这个是我们程序设计的一个 要求,或者说一个规则,对不对啊?第二个的话呢,就是可以实现模块化的设计,什么叫模块化的设计啊?正如同我们去拼图对吧?啊?大家应该对乐高应该有个了解,乐高是不是有什么电机模块呀,轮子模块呀,啊什么等等其他的一些模块,对不对啊?如果有玩过的同学应该知道啊, 那这个模块的话是不是能够更方便?比如说我们想用乐购去组成,组成一辆,组装一辆车子,是不是可以用一个电机模块加轮子模块啊?加一些这种东西拼成一个车的形体啊,或者说框架,我们就可以让这个车跑起来, 对,那不需要你什么呢?不需要你去手搓电机啊,手搓轮子这些东西对不对啊?你手搓电机那就从零开始了嘛。所以模块化设计其实就是把一些功能性的东西,我们把它整合到一起,在需要的时候去使用,对吧?所以第三个 它的优势就是啊,它的作用就是它可以进行灵活的组合调用,就跟我们拼图一样,是吧? 那如何去进行一个函数的使用,或者是如何把我们指定续集的这个集合封装到函数里面去了,那就涉及到了我们啊,我们函数的一个定义实现,当然 在正式我们去学习函数的定义实现之前呢,我们得需要去知道,或者说我们得要去学习一下函数它的设计要符合一些什么东西,或者说我们如何才能够去设计好一个函数,对不对?首先呢我们在设计一个函数,设计这样一个模块函数的时候呢,我们首先要去分析一下它的需求, 就是我们先要知道我们去设计这个函数,或者说去设计这个模块,它是用来干什么的,对不对?那我要完成这个模块,或者说我这个模块从开始运作到最后它的功能实现,它应该要我提供一些什么东西,对不对?是吧? 比如说我们的电机,电机模块的话是不是需要我们提供电源,所以他就会留两根导线出来吗?对,这个就是需要的资源。我们函数也是一样的啊,你需要实现这个功能,那么你就要留一些东西出来啊,你需要我提供的一些东西出来,对不对啊?这个我们称之为资源,可以是数据,可以是内存空间,可以是一些其他的东西。 对啊,第二个我们需要去考虑的是就是函数的功能实现啊,这个玩意我们叫算法,就是如何去实现这个函数,比如说我们去实现这一个计算的函数,对不对啊?计算的这个模块,那我怎么去实现这个计算的模块呢?对不对 啊?我想要考虑到多位数的运算,所以我会用到数组,我想要考虑到重复的运算,我是不是要考虑到这一个 while 循环或者 for 循环来让它支持这个重复运算,对吧? 那么啊,我要考虑到这一个数据的一个累加或者累减,我还要去判断这一些运算符的操作,对吧?那这个呢,就是我们函数的一个功能具体实现的方式。那最后一个点呢?就是需不需要反馈一个结果? 我这个函数啊,计算数据之合或者是计算数据的一个结果的,那最终是不是要把这个计算完的结果给到我们, 对,那这个就是我们需要返回的一个结果呀,像电机模块,你我提供了电源,那么电机他就会返回一个扭矩给我,或者说返回一个这个电机会转起来吗?对不对?他那个转的那个上面是不是会有旋转的扭矩?对,那这个扭矩就是我需要的这个力吗?他就给到了我一个这样的结果,不对,他会转起来就是一个结果 啊。所以我们再去做函数的一个设计的时候,我们就要考虑这一些点啊,就是,呃,我要完成什么东西,要什么资源,对不对?我怎么去实现?最后需不需要有结果的反馈,对不对? ok, 那 知道了这些之后呢,我们就可以开始来我们的实现我们的函数的一个定义了。首先呢,呃,这一个函数的话呢,它的一个定义语法啊,我们可以先来了解一下。首先呢函数它是分为这一个函数头 啊,函数头其实就是跟我最开始跟大家介绍啊,我们第一个程序是一样的啊, int main, 它其实也是一个函数嘛,对不对?那 int 的 话我讲过是一个返回值类型,对吧?啊?那么在我们自己设计的函数里面呢,也需要返回值类型,可以是什么呢啊?可以是任意合法的这一个 c 元的类型, 对吧?任意合法的 c 语言类型啊,它一般是 return 后面的那一个数据的类型,就是 return 后面那个数据的类型,要跟我们函数名前面的这个返回值类型要一致啊。如果你返回的是整形,那么我的这一个函数名前面的这个类型应该是 int 类型或者是 short 类型这样子的整形对不对? 然后后面是函数名,函数名是什么呢?它是类似于变量名、数组名一样的东西,它也是一个标识符啊,作用的话呢是将这个名字和函数关联起来,这里要注意啊,函数呢?它其实本质上是什么呢?本质上它其实就是一个内存执行的一个地址, 我们指令它也是存储在内层里面的啊,我们可以画个图给大家稍微讲解一下这个底层的原理啊。就是,呃,比如说我们的微函数,这是微函数对不对啊?哎? 哦, main 函数,那么 main 函数呢?它会有在内存当中去执行的时候,它会有一个地址分配给它啊?我们假设叫零 x e f 的 这样一个地址,那假设我们分成了另外一个函数,对不对啊?我们另外一个函数叫什么呢?假设叫做这一个。呃, my function, 好 吧。啊? my function 啊, my function 这样一个函数,好,这个函数呢?它是另外一个地址了啊?零 x, 比如说 e d 啊,或者说,呃, f f 的 这样一个地址, ok 啊,随便写的。 那也就说慢函数它在执行的时候呢,它会从 e、 f 的 地址一直往下执行每一条指令呢?其实就是一个地址,每一条指令就是一个地址,所以一你这个里面有多少条指令,它其实就会按顺序往下执行到这个地址来,对不对?好,那如果说我想要去执行 my function 这个函数的话怎么办?那我是不是就把这个地址给它插进来就可以了, 对不对?插到我慢函数,或者说我想要使用这一个函数这个模块的一个位置就可以了,对不对啊?也就是说 只要把他的地址插进来,那这个我比如说我们插到函数里面来,那函数从上往下执行的时候,哎,他遇到了这个零、 x、 e、 f、 f 的 地址,他是不是也会去执行这个函数里面的内容? 对,他是一个这样子的过程嘛,跳到这里来执行啊,所以他本质上是个地址,那这个地址怎么拿得到呢?哎,就是通过函数名去拿到的,函数名他就绑定了这样一个地址啊,他跟函数关联起来了的 o 吧。好,然后里面呢有一个括号,后面紧跟的是一个括号,括号里面是行差链表,行差链表呢,是指我们这个函数这个模块在运行在直线的过程当中,它需要我们外部去提供一些什么资源,对吧?像那个电机一样,我们外部要提供一个什么电源吗? 对不对啊?由我们外部的一个使用这个模块的人,或者说使用模块的。呃,这个函数去提供 o 吧。好, 那函数体呢?是花括号括起来的啊,就跟我们函数一样括起来的。这个里面呢可以写什么定啊,类型的定义啊、负循环啊等等七里八里的一些代码啊,这些代码呢都是为了去实现我们这个函数需要实现的功能,比如说我们想要去计算数据值和对不对,那我们就可以把我们之前的代码给他放到这个函数里面来就可以了。 好吧,所以一个函数的写法其实就是由函数头加函数体组成的,那么函数头就是由返回值、类型加函数名加行长列表对组成函数体呢就由花括号加函数的具体实现步骤来组成的,他们两个加起来就形成了一个 这个标准的函数,或者说一个函数的一个,呃形式好吧好,最后呢这里面有一个返回值啊,返回值类型的话,呃这里面有写啊,当然也可以没有好不好也可以没有。那有跟没有怎么他其实是有区别的,有两种写法,我们等一下来再具体去实现函数的时候我再跟大家去讲, ok 吧。 ok 呃我们来看一下啊。啊那数据的话呢?呃格式啊,就是行参列表啊,我们其实可以不写啊,当然也可以写 void 啊,其实之前跟大家讲过有 void 就是 空类型对不对?它作为函数的一个参数来使用的话呢它就表示没有啊,没有参数。那你不写其实也是没有参数吗? 对不对啊?不写也是没有参数,那如果有参数怎么去传呢?就是数据类型一啊,加数据名一然后逗号 啊,就这样子啊,数据类型二加数据名二啊,都好,就是类似于一个变量的定义一样, ok 吧啊它可以有不同类型都是可以写到上面的啊,它是个列表行差好不好?好了我们怎么去定义一个函数啊?比如说我们拿 m 函数做例子的话呢? m 函数它的原型长什么样呢?它是长这样子的啊, 叫啊 int main 啊, int a r g c 啊,逗号 const 叉二星 a r g v 的 一个叫什么?一个方括号啊,其实后面是一个数值对不对啊?它其实 main 函数的这一个原型函数啊,就是它长得原来的最开始的样子就是这样子的啊,带两个参数,一个类 int 类型的参数,一个叉二星类型的数值, 对不对?那里面就是我们要写的东西了吗?对不对啊?我们要写的东西。 ok, 好, 那这个东西比如说我们要去实现我们自己的一个函数的话啊,假如说我们这里要实现我们自己的这一个计算函数啊,计算的一个函数对不对?哎,我们来看一下啊。呃呃,计算函数对吧? 好,把我们之前的我们写的那一个计算的代码给它搬过来,我们的代码是这样子对不对?我们现在要封装一个函数,我们怎么去封装呢?哎,我们是不是计算函数我们把它拿过来啊?计算函数,那么它需要参数吗?肯定需要参数,对不对啊?参数 ok, 参数呢?是,呃需要计算的这一个操作数对吧?需要计算的操作数。那有没有返回值?当然有了,返回值呢就是计算之后的这一个结果 对不对?好, ok, 那 我们来定一下啊,那计算之后的结果我我们的结果一般都是整形对不对?这里都是整形,所以我就用整形。好,然后啊 cardalay 呃卡卡卡口,哎,算了,我不记得了啊。 c h c ok, 可以 了。 c l c l c 啊,就这样一个名字。 好,然后它要有行参,我们的参数就是行参嘛,所以第一个啊叫做 sum 一 int 一个 sum 二就可以了。好,那有没有结果呢?结果肯定有了, sum 类型对不对啊?等于一个零。 ok, 那 我返回,返回谁呢?返回 sum 啊,就是返回计算的这一个结果,对不对? 好,那这里其实还有一个问题啊,就我们要计算的话,你你你一跟二要计算它到底是加还是减,我们是不是也要有一个,对不对啊?所以我们把这个 char 类型的,呃,这个 expr 啊,操作数啊,以及这一个操作符,我们给它搞进来, 对,好,那怎么去计算嘛?那 sum 等于什么?等于 long 一 欸?直接 expr long 二吗?这肯定是不行的,对不对?它不能直接放进来,所以还是需要什么呢? switch 我 们要来判断一下。 判断什么东西呢?判断这个 expr 啊,它到底是加还是减,对不对啊? cash 我 们的加啊,然后呢?我们的 sum 就 等于 sum 一 加上 sum 二啊, break 掉 就可以了,对不对啊?然后 sum 如果是减号的话,我们是不是就是 sum 等于 sum 一 减去 sum 二就可以了啊?同样 break, 那也就是说在这个里面他就会不断的去进行计算了,他只会去计算两个操作数,对不对?但是我们这里,你看我们这里是什么?我们这个数据他是要不断的,干嘛?他要不断的去, 呃,叫啥来的?不断的去获取我们的这一个数据啊,然后去计算他是多位数的吗?对不对啊?那这里的话呢,我们稍微修改一下, ok, 稍微修改一下,嗯,我们直接来啊,把它删掉。 int 一个 number 一 啊,等于零啊, int 一个 number 二等于零,对吧啊? scale 我 们的这个百分号 d 啊,然后百分号 c 啊,百分号 d, ok, 这样子。取整数符 number 一。 呃,取整数符 xpr, 我 还没定义啊,等下定一下啊。呃,取整数符 number 二,对,好,搞定我们就可以输入了嘛?对啊, char xpr 等于一个零, ok, 好, 我们数据已经输入完了啊,我们的这个计算函数也搞定了,对不对?那么我们怎么去使用它呢?那这涉及到了什么?涉及到了我们函数的一个调用的方式。函数调用呢,很简单啊,它呢? 首先啊,语法可以,为什么呢?哎,括号还是一样可以省略的部分啊,返回值类型变量名等于。哎,那这是什么? 既然是数据类型加变量名,它其实就是定义一个变量吗?也就是说如果我们的函数有返回数据的话,你需要接收到它的返回数据的话,你可以定义一个与函数返回值类型一致的变量来接收它的结果,对不对啊?那真正的调用是怎么调用呢?就是函数名加时长列表就可以了, 这里时差列表是什么?时差列表?注意它和行差列表是一一对应的,如果你的行差是 int a, int b 跟恰 c 的 话,那你实际参数在传递的时候就是时差就是实际参数啊,实际在传递的时候呢,就是要传递一个整形,两个整形和一个制服型。 对,它只要类型相似就可以了。它不需要,不需要我们写类型加变量名的啊,只要这个变量它的类型跟行差的类型一致就 ok 了。 好吧,那就比如说,呃,我们这里要调用啊, int 一个 sum 等于,或者说啊 resolute 啊, resolute 等于什么呢?等于啊, coco coco 啊,我们来一个啊,十十和一个加号,那其实就什么计算十和十的合并 存储啊,将其结果存储到 resolute 变量中,对不对?就这么一个过程嘛。好吧,这个就是函数的调用,所以在这个里面我们可以干嘛?我们直接就是啊,呃, into resolute 等于 coco, 对 吧?啊?朗一传进去,朗二传进去和一个 expr 传进去,最后啊,我们打印一下,结果啊,打印下结果,我们的这一个百分号 d 啊, 呃,百分号 c, 百分号 d 等于百分号 d 啊,我们给它写的好看一点,对不对啊?朗一, expr, 朗二和 resolute, 我 们的结果 对不对?好,这样一个结果, ok, 我 们来看啊, g c, c 整理啊,然后翻译一下啊,等一下啊,好,翻译完成。点干 a 点 ex, 一 加二等于三, 对不对?那我任何地方我都想要计算的时候,我不需要重新去写这个里面的代码了,我只需要干嘛?我只需要去使用这个 code 啊,对吧?然后把参数传进去就可以了嘛,对不对?是不是很简单? 很简单吧,那这个呢,就是我们一个自定义的函数啊,但是在这个函数里面啊,大家要注意啊,这个函数里面呢?呃,我们一般把 在这个里面啊,你看这这一行号呢,我们一般在这种情况下,我们分为这个慢函数跟 coco 函数呢,我们有一个区分的啊,慢函数呢,称为主调函数, coco 函数呢?我们称为什么?称为背调函数,那为什么?呃,慢函数称为主调函数, coco 函数称为背调函数呢?是因为 我们的这一个,哎,往下面写一点啊,我们的这一个主调函数呢,其实就是在别的在调用其他函数的这个函数,它就是称为其他函数的主调函数就是 main 函数。调用了谁呢?调用了我们的 coco 这个函数,对,而 coco 呢,它是被我们的 main 函数调用的,所以 coco 它是什么? 它是称之为背调函数啊,它是内函数的背调函数,而内函数呢,是 coco 的 主调函数,所以主背调函数,我们要知道,好吧,我们要区分谁是主调函数,谁是背调函数, 好吧,谁是主调函数,谁是背号背调函数。好,那么为什么?既然我们搞清楚这个东西了,让我们再来思考一下,为什么这个 coco 它可以去计算 number 一 跟 number 二的这个数据,对不对?那 这个的话呢,就涉及到了我们函数它的一个调用过程啊,你可以来看一下,比如这是 main 函数,对不对啊?这是我们的 coco 函数 main 函数啊, coco 函数好, coco 函数需要一个 int 类型啊,然后再需要一个 int 类型啊,以及一个 char 类型,对不对? 而麦芽素在这里调用了 coco 函数啊,它传了一个什么东西呢啊?传了一个,呃, number 一, 对啊,这个 number 二和一个 expr 进去了,对不对啊?那也就是说,在这个传递的过程当中呢,它会把 number 一 的值给到 coco 里面所对应的这一个 行差,那么二呢?同样给到这个行差, expr 也给到这个行差。好,那我们这里那么的值是多少?是一,那么二是二啊,然后 expr 呢?是加,对不对?所以这里过来的时候呢,它就相当于把一给到这里的那么一了, 对啊,把这二呢给到这里的那么二了, expr 给到这里的 expr 了, 对不对?好,那为什么可以给?是因为啊,回到我们代码这里来看一下啊,这里的 int num 一 呢,它是类似于变量定义,也就是说当这一行代码执行的时候呢, 我们 calculation 就 开始执行,就开始运行了,对不对?那运行的过程当中,它先会把 num 一 的空间去申请, num 二的空间申请, e x p r 的 空间申请,对不对?这里就相当于进行了三次的变量定义,定义完了之后呢,再把 number 一 number 二跟 e x p r 这个里面的值呢,给它拿出来复制给它们。所以总的来讲啊,它其实就相当于一个什么样的过程呢?哎,等一下啊, 就相当于是 man 里面它有一个啊 number 一, 对不对?往下面写一点啊?看不清啊, man 里面是不是有一个呃, number 一 的数据? 而我的这一个啊,卡口里面它是不是也有一个纳米级?它就等于什么呢?等于我们的这一个呃, man 的 纳米级,它做了一个这样类似于一个这样子的操作啊,我们可以这样子去看待它啊,会比较好理解一点,对不对啊?它做了一个类似于这样子的操作, e x p r, 所以 我们卡口里面它才能接触到这一个类似于这样子的操作, e x p r, 所以 我们卡口里面它才能接触到这一个类似于这样子的操作。欧巴 好,那么拿到这些东西了,他是不是就可以去进行一个运算了?所以他整个的一个调研过程呢,就是先会把时差的值赋值给行差,然后呢去执行背调函数中的语句代码, 那背调函数返回的时候呢,函数的表达式的值就为 return, 后面的表达式的值就是函数结束了啊,这个函数他到这里就结束了,对不对?那么这此时这一个表达式,我们称之为表达式嘛,对不对?这个表达式肯定会有一个值的,他一个结果的结果就是他里面这个 return 里面的值。 好吧,那这个值我是不是就可以获取到这个?呃,一加二,或者说这个辣米一加辣妈,辣米一减辣妈的一个结果,然后复制给 resolute 了,对不对?就这样一个过程嘛, 这是整个函数的一个调用过程,当然它前面还有细化的啊,就是要先去把行参的空间开辟出来啊。好,那么函数它的数据传递呢?我们刚也看到了啊,我们可以通过参数传参的时候呢,我们可以通过实际参数和形式参数进行传递。 那背调函数与主函数传递参数的话呢?啊?我背调函数怎么传递参数给主函数?传递数据给主函数通过返回值嘛? 当然主调函数与背调函数想要相互传递参数啊,那我们可以通过指征或者是全矩阵,那这两个东西呢?我们后面也会再去学习的, ok 吧? 啊?我们现在只知道啊,现在知道啊,这个主调函数与背调函数相互传递,可以通过指征与变量,当然主调函数往背调函数传递了,我们可以通过传参,对不对?背调函数与主调函数传这个传递参数的话呢?我传递数据的话,我们可以通过返回值,对不对?啊?三种东西,好吧, 好,那知道了这一些内容之后呢,我们再来看一下啊,大家可以发现我的这个函数是写在哪里的?写在主函数的上面,对不对?那大家都说,欧巴我之前跟大家讲过我们的这个执行顺序从上往下执行吗?对不对?那他为什么不会先执行?他可而会先执行妹呢? 啊?因为面是第一个函数啊,就是面。呃,这个程序里面的一个入口函数,相当于大门一样,他会先从这里来进,好不好?那有的人说我可不可以把这个函数写到后面?这个函数你可以写到后面。没关系啊,这个函数可以写到后面。可以的 啊。可以。但是呢,嗯,有的时候会出现一些问题啊,我们可以看一下。这个时候他就出现一些问题了。什么问题呢?他他告诉我们啊,这一个, 呃。 function call, 对 吧?它其实是找不到啊,就说说人话。就是啊,我找不到这个参数啊,我找不到这个函数,你这个函数去哪里了,对不对?哎,但我这个函数在这里啊。这卡口不是在这里吗?为什么它找不到呢? 啊?因为我们程序它虽然是从慢函数开始执行,走上往下执行的,对不对?但是还有一个翻译的过程啊, g c c。 它有一个翻译的过程, 他翻译了就是从上往下执行的,他没有不会说从慢函数开始执行的,他会从上往下执行,从上往下执行,他就会遇到一个叫做 coco 的 函数。哎,我没见过这个函数。没有啊,你没告诉我这个函数啊,那 没有这个函数不就报错了吗?对不对啊?所以他就报错,他不让我们翻译成功啊。那为什么写在上面可以?因为从上往下执行的时候,我们的 coco 函数它在上面,它一开始就被这个编辑器发现了, 但是这个函数呢?没有做其他的事情,它只是声明啊,我们就定义了这样一个函数,对不对?没有去用它,那到了 main 函数的时候发现,哎,我 main 函数里面调用了 coco, 那 coco 我 在上面已经看到过它了,所以它就不会报错。 ok, 那 我只能把函数写在上面吗?当然不是的啊,如果说我们把函数想要写在下面的话呢?我们要进行一个操作,什么操作呢?叫做函数的一个声明。 去提前告诉我们编辑器有这么一个函数啊,你不要报错,你见到了这个函数的调用,你先不要报数了,我的函数的声明可能在后面,对不对? 好吧,也就是说当背调函数在主调函数的后面的时候,我们就要去声明,好吧,或者说在其他文件的时候啊,声明怎么声明啊?非常简单,就是把它的函数头拿出来啊,加个分号就可以了。写在最前面啊,也就是我们代码这里把这一节给他复制啊,丢到最前面了。这个就是声明函数 声明了一个啊,返回值为 int 类型,且带有啊两个 int 类型和一个 char 类型的 类型参数的函数啊,就声明嘛,就告诉,提前告诉嘛。那这种情况你申明了之后呢,你会发现你再去翻译它,它就不会报错了,同样啊,它可以正常的执行,对不对? 好吧,这个就是函数的一个声明。好吧,那只不过了声明的时候有一个小小的啊点,就是我们可以把他的名字给他省略掉,就是变量的名字,这个名字可以不写啊,你只要告诉他类型就可以了。因为为什么可以不写?因为你在定义的时候你已经给了他名字了, 你在定义的时候给了他名字了,你声明的时候其实不需要改名字,你只需要改什么呢?只需要告诉类型就可以了。为什么类型一定要名字不要啊?名字刚刚讲了为什么不要?类型一定要的原因就是系统他必须要知道你这个函数他要不要行差嘛,对吧?行差是什么类型他才能够计算你这个函数需要在 一开始的时候我就给你的这个行餐分配多大的空间吗?对不对?我要告诉或者别人在调用的时候,我可以通过你的类型去判断他有没有调用出错吗?对吧?这个就是类型必须要写的一个原因。好吧, 那我们学习完这个之后呢,可能就有同学会有一些疑问了。啊?什么疑问?老师,这个返回值我有点搞不清这个返回值它到底返回了一个什么东西,对不对?我这里知道啊,在计算的时候我们可以我们是返回了一个整形用来返回结果的,那其他时候呢?它返回什么东西,它表示什么意思呢? 那么这个的话呢,大家要注意了,返回值到底返回什么东西啊?返回的是什么?它取决于写代码的这个人,我写的这个程序,那么返回值由我来决定它是 干什么的,也就是说我觉得这个玩意它应该要返回什么,它就返回什么,那最终返回值的结果所能表达的含义的,那解释权归我们程序开发者所有啊,好吧, ok 吧。 啊,同时啊,要注意的就是一个程序里面的卖还是只能有一个啊?因为他是大门啊,你们家大门一般都大,每每个人家里大门只有一个吧,对不对?不可能有多个大门嘛,对不对?但是其他的函数的可以有零个或者多个,也就是你家除了大门之外啊,你其他的那一些室内门你可以有也可以没有, 对不对?这个是没关系,只是大门必须要有一个好吧?啊?有且只能有一个, ok, 好, 这个是我们的一个函数啊, 函数的话他可以帮助我们去实现很多很多东西啊,可以去解决我们代码里面的一些这种逻辑混乱啊啊,然后代码重复的一些问题,对不对啊?可以让我们的整个程序的啊逻辑啊这些业务的一些呃代码的呃 功能啊等等都会变得更加清晰更加明亮,好吧。啊那么在函数里面呢有一个东西叫递归函数啊,递归函数的话呢?是呃比较特殊的一个函数。那递归函数它是什么样子的呢?就是我们在一个函数里面,比如说在 coco 里面, coco 里面它自己也可以调用 coco 了,对不对? coco 是 不是也可以自己调用 coco? coco, 好, 那么自己调用自己这种情况的话怎么办呢?哎,你看这里我 coco 调用了 coco, 那 又进到这里来了啊,那么又进来的时候又有 coco, 它又不断地进,不断地进,不断地进,哎,那是不是就不断地去调用自己了, 对不对?那就陷入了一个循环里面去了。那自己调用自己的这种函数他叫什么函数呢?就我们刚我刚跟大家讲了他叫递归函数,递进递归啊,自己调用自己的一个函数,或者说直接或者间接调用自己的函数都叫递归函数,好吧,那么递归函数 这个东西他能干什么对吧?他的优点是什么?为什么要搞一个这样的函数出来?为什么要单独把递归函数拿出来讲对吧?好,递归函数呢,他可以把复杂的问题简单化的去描述啊,当然 第一关函数他虽然是简单化描述,但是他不会降低整个程序的复杂度啊,他只会增加复杂度。好吧,这是第一点,第二点的话呢就是可以提高什么 big 啊。提高逼格写代码要写到别人看起来很高大上吗?对不对啊?这个提高逼格 那比如说像什么样子的呢?嗯我们要去呃做一个这种累加的程序的话,对吧? 啊累加的程序哎累加累加,比如说从一加到什么呢啊?我们要从一加到一百对不对啊?那怎么去写呢?如果说我们按照以前以往我们现在已经学完的这一个呃东西去写的话呢可能我们就会这样子去写了, 叫做呃 int a 等于零,然后呢?呃 for 循环啊, int i 等于一 g i 小 于等于一百,然后 i 加加对不对?然后这里面是什么? a 加等于 i 嘛?最后啊 print 我 们打印一下啊百分号 d a 的 值啊,这个累加对吧?是不是好运行一下五零五零是没问题的对吧?啊是没问题的好,那这个累加的话呢,可能嗯 大家都会写对吧?看起来也挺简单的。他除了能够用 for 循环去写的话,我们给他讲了我们可以用递归函数去写啊,但递归怎么去写呢?递归写之前啊我们还是一样要通过像函数的这一个设计一样,我们要去分求一下啊,去分析一下他的需求。首先他是递归啊,他是哪家,对不对?第二个的话呢?我们怎么去实现 啊?实线的过程我们其实就是要拆分。第一个函数呢,要考虑实线的过程,他跟正常的函数实线不一样啊,他要考虑拆分,他是去把问题给他拆分一下。比如说一啊要加到一百,那么我们是不是可以把它拆分成 什么呢?一加到九十九啊,再加一百的这个值,那一到九十九,我们是不是又可以拆分成一加到九十八啊?然后加上九十九的值, 对,以此类推。最后,最后,最后,最后我们是不是可以猜成什么呢?一加上二的结果,再加上三就是我们这一个地规,最开始的时候就是我们一加二的结果,加三才是我们的这一个前面三位数嘛。但再往下猜,可能就是,呃,这个零加一 啊,零加一加二的结果呢,就是我们前面两位数的和,对不对啊?以此类推。你是哎,你会发现整个一累加到一百,它可以拆分成很多个形式啊,或者说它可以一直往下拆,拆到最后就会变成零加一加二的一个形式,对不对?那递归呢?它其实就是利用了这样一个原理, 你会发现在这个里面,他其实无非就是,呃我的呃,一加到三的结果,等价于这一个三加上他前面数据之合,对不对啊?一加到一百的结果,其实无非就是一百加上前面数据之合嘛, 对吧?他可以看成一个这样子的,这一个呃,叫做问题,这个问题一加到一百的这个问题可以把它拆分成啊,一百加上前数据之合 对不对啊?就加变成两位数字两位数的一个运算方式了啊,我这里是一直往下加,对不对?好,那么地归怎么去加呢?呃,地归累加地。哎, 地归啊累加,那我们可以这样子去写啊,把这里给它干掉,好吧,然后呢?呃去写一个 enter and 好, and 是 什么呢? and 是 我们的这一个累加的一个函数啊,就是第一个函数啊,然后我们定一个 num, 它这个 num num 是 干什么用的呢? num 就是 你要计算的那个值,对不对啊?计算的那个值 ok, 那 么此时是,呃,比如说我们要算这个一百啊,我们要算一百 一累加到一百对不对?那么是不是我们刚才讲的才分成啊一加到一百啊,它其实等价于我们括号一加到九十九加一百的值对不对?所以假设这个 num 它是一百的话,那是不是就是 num 要加上 and 欸 long 减一的值,好,那这里的话 long 是 什么呢? long 等价一百而 long 减一是不是就是九十九? 对欸,那这样为什么这样子可以啊啊有同学问老师为什么这样子可以啊?那你想想看啊,我们 end 的 作用是什么? end 的 这个作用啊, end 呢?是求啊一累加到 long 的 值的一个 功能的。对啊,那那么是一百,那就相当于是一累加到一百,那那么减一变成九十九了,那是不是就是一累加到九十九那这不就变成了什么?就变成了我们在一个一加到九十九的结果加上一百吗?对不对? 好,那这里又调用了 and 那 这个时候传进来是多少。是九十九那就变成了九十九加九十一减加到九十八那九十八再往上那就变成了九十八等于啊这里应该是加等于啊加等于啊加等于我们的不是加的加。哎这搞错了 into 一个少了个东西啊 into 一个 sum 啊等于我们的 let 就变成了九十八啊加上我们的这个九十一累加到九十七的结果对不对啊最后我们这里干嘛呢我们就返回一个啊上不就可以了吗那有的人会说了啊你老师你这一直减下去不就减成负数了吗还有可能吗对不对啊肯定有这种可能。那怎么办呢我们要给他一个退出条件退出 条件如果你不给退出条件的话呢他就类似于一个死循环一样了对不对啊那你要等于什么呢等于我们的一的时候啊我们就返回一就可以了对不对那么等于一的时候我们就返回一 o 吧一一还要算吗这里不是二吗对不对啊二加上它返回结果是一啊二减一为一嘛对不对等于一了就返回回来就可以了所以我们这里同样啊应了上等于我们的这个 and 一 百的值我们去求一勒加到一百的结果。 print 啊百分号 d 上嗒看一下啊 啊地归类加啊走你五零五零是不是也是五零五零啊但如果说大家觉得呃这个玩意看起来我我觉得可能大家搞不清的逻辑对不对啊那怎么办我们可以把它打印一下吧哎浪等于多少 对不对 num 等于多少。好我们来看每一层它的 num 是 什么样子的, ok, 你 看一下啊,从第一次往最上面就是第一次,第一次进来,我们在主函数调用的这一个 num 之后,那 num 进来是不是一百好,然后就变成了一百加上 and 一 百减一,然后就 进,下一次进入了这个 and 就 变成九十九了,对不对?好,然后一直往下,一直往下,一直往下就变成一对,所以他其实就是把一到一百的值全部给他累加起来了,跟我们那个复循环有点相似啊,但是你会发现他这个,呃,他这个 结构其实会变得比较复杂的,把这个问题呢会给他简单了,就是原本是要一累加到一百,一百个数相加的,他变成了两个数相加,对不对?他变成了两个数相加了,对吧?这个就是我们的一个帝国函数啊,帝国函数,那么呃,帝国函数的设计啊,大家一定要注意啊,设计的话呢, 首先我们这个问题,模型要符合地归模型,就是他要地推对,像我们刚一累加到一百,他其实就是符合地归模型的嘛,就是我一累加了一百,一百个值相加的这个模型我可以变成两个数相加的一个模型,对不对 啊?第二点的话呢,就是要去明确函数要实现的功能和参数之间的关系。那我们这个代码里面,我们函数它在实现过程当中呢,它对于参数的要求是这样子的,就是我 第一次进来是一百,对不对?第二次了,他应当是这上一次调用的这个参数减一的一个参数,因为他们是一个递减的过程,对,递减的过程啊。第三个的话呢就是问题的解要递归到一定层次的时候,答案是显而易见的啊。什么意思呢? 就是我们要从一累加到一百,对不对?那你从一百要百一,一累加到一百要变成一百加上九十九加一的值,一直要往下推,推推推推,推到什么时候呢?推到二加一的结果就可以了,那这个结果就已经出来了嘛, 对不对?推到那母为一的时候,是不是就那母为二的时候,这个整个结果已经显而易见了?就最终他就变成了二加一的一个结果,对不对啊?那为一的时候就结束了吗?所以要有一个结束函数。所以呢啊,最后一点就是要呈现出第 n 层和第 n 减一层的第二环关系。 我们这里也是有的啊,比如说第一百层就是一百加上九十九加一的值,那第九十九层就变成了九十九加上九十八加加到累积到一的值,对不对啊?就这样一个过程。好吧, 好。那么递归的话呢,它其实除了,呃除了我们的这一个我们刚讲的这个递归方式之外啊,它其实大致分下来的话会有两种形式啊,就是先递归到最下层,然后一层一层的往上走啊 啊?一层一层的往上走,比如说我们这个二进字的一个组合,他要把一个数呢要拆打散才分成二进字啊?然后呢不断的往上去进行一个组合,对不对啊?你可以把它看成是什么呢?呃,我们一个比如说一个服务员啊,他去坐电梯, 对啊,他要给每一层呢都要去分发这一个,这个这个简餐,对吧?这个,嗯,要吃的东西。好,那他怎么去做呢?他首先跑到最上层啊,从最上面往下面跑 啊,跑到最上层啊,就我们可以看的是底啊,他最上面的,然后呢?嗯,一层一层一层的往下,干嘛?发这一个,呃,饭,对吧?发完他是不是就结束了? 从跑到最下面,然后一层一层的发啊?发这个配餐发完了他刚好就回到最底下了。这个就是先跑到最下面,然后再往上走,这个叫回数法啊,回数法 o 吧。好,然后第二种的话呢,我们叫分制法。分制法是什么呢?分制法其实就跟我刚刚所讲的这一个一类加到一百是一样的, 他会把一个问题分解成模规模更小的问题,我把一类加到一百,一百个值相加啊,变成了这个一两个数相加的一个规模, 对不对?你看啊,一类加到一百二变成了一百,加上一到九十九啊,然后九十九变成一加加到九十八啊,然后 n 加到 n, 一 加到 n 减一的和,然后三啊,就是一加二的和,对不对?就这样子不断的去拆解问题,不断的去拆解问题。上面这个回数法呢,是先跑到最下面再往上面走, 欧吧?这是这样的一个过程啊,两种方法啊,两种方法,大家反正根据场景去选择方法就可以了。好吧,根据场景去选择方法。 那么地规函数的这个数据传递的话呢,其实都是差不多的啊,跟函数函数函数的传递, 只不过它每一次地规处理的数据对象呢是不同的。这个数据对象的时候呢,我们可以把数据对象啊作为参数去传递,比如说 long 对 不对?那如果说每次地规处理的是同一个数据对象的时候呢,我们就可以使用全 g 变量啊,或者说指向啊,后面会讲到的。 然后再一个的话呢,就是我们把子问题解决了之后需要回解,就是你把我的解传回去的话啊,就我们类似于一加到一百的这个结果,对不对啊?他要回解吗?一加到二的值是不是要返回给第三层对不对?那么他就可以通过返回值去返回就可以了,好吧, 好, ok 啊,那么函数的话呢,它其实可以解决我们这一个程序里面啊,当我们程序的代码全部写在同一个函数的情况下面啊,造成的这一个逻辑啊复杂,或者说我们逻辑不清晰的情况下面呢?我们的函数啊可以让它变得更加清晰, 因为你像啊,如果说我们把很多的一些功能啊,很多的一些逻辑全部写到面函数里面啊,他就会显得很乱,对不对啊?很多 看起来不是很舒服,那我们就可以利用函数的这样一个机制呢,我们可以把我们一些单独的功能给他剔出来,放到函数里面去进行一个封装,对不对?那么呢我们整个程序就会变成了一个模块,两个模块啊, a 模块跟 b 模块的一个结合,对吧?啊?多模块的一个结合, 那这样子的话呢,就能够从整个就是代码上面啊,让我们看待这个程序的时候啊,我们的逻辑跟思路会变得更加清晰,对不对? 好,那么我们自己在写的过程当中呢,大家可能也会存呃,会遇到一个问题啊,就是用函数的时候会遇到一个问题,什么问题呢?就是我们会发现啊,在某一个函数里面,我们如果说, 呃定义了一个变量,那么在其他函数里面好像是没有办法直接使用的,对不对?比如说我在 sum 里面定义了一个 s 的 这样一个求和啊,或者说重合的一个变量,那么在 main 函数里面,我们没办法直接去打印这个 s, 对 吧?你不调用那个函数啊,你直接去打印 s 好 像是不行的,它会报错, 报什么呢?报找不到这一个变量的一个错误,对不对?那这是因为什么原因呢?这是我们在 c 语言里面,其实它规定了每一个变量都拥有一个自己的作用范围的。 好,那这个作用范围我们要怎么去确定?或者说我们怎么样才能知道一个变量它的作用范围是怎么样子的呢?对不对啊?那么我们接下来就来学习关于这一个变量的一个作用域与生存期。 那所谓的作用域呢,其实就是去表示啊,我们定义的一个变量,这个变量的名字,它能够作用在哪一些区域范围之内吗?对不对?那有几个变量啊?我们一一来学习一下。第一个的话呢,我们 称之为全变量啊,前面我也跟大家经常提及到了这个变量,对不对啊?全变量。全变量的话呢,是指在函数外面定义的这个变量,并且呢一般我们定义在整个文件比较靠前的位置啊,我们叫做全曲的变量, 那全局变量的重要性,它的使用范围就是从全局变量定义的位置开始,一直到整个文件内容结束 啊,那么它的范围就结束了。那其实对于整个工程来讲的话,我们也可以在其他的文件里面去使用这个全局变量,只不过在使用之前呢,我们要通过 xten 进行一个外部的声明啊,把这一个啊其他文件的全局变量声明到这个文件里面来, 对不对?但是需要注意的是,如果说一个全集变量我们使用了一个 static 进行修饰的话啊,就是你在这个变量全集变量定义的前面加了一个 static 的 关键字,那么这个全集变量就只允许在当前这个文件去使用,它不能够被其他的文件使用 xten 进行一个外部声明, 好吧,这个需要注意的啊,因为 static 属于静态啊,属于静态的一个全局,你可以把它理解为就是限制死了它的一个作用域,作用域的一个范围,好吧,那比如说我们呢?呃,干什么呢? 我们,我们有假设啊,去定义了这样一个函数啊, int 一个上啊,定义了一个变量啊,不是函数啊,然后呢?呃, int 一个 expr, 对 不对? 好,我们这里啊上呢,等于什么呢?等于我们的这一个 a 加 b 啊,这里没有 a 加 b, 对 吧?我们来一个 a 加 b, 那 a b 啊,就其实就是求 a 加 b 的 一个和嘛,对吧?求 a 加 b 的 和好,那么我们这里呢,你会发现 它其实它用到的这一个存储和的变量是谁?是 sum, 对 不对?它定义在整个函数外面啊,定义在函数外面啊,如果说更严格一点的话呢,我们会把它放到头文件的下面啊,放到头文件的下面, ok, 大 概是这个样子的。那也就说这个 sum 其实不单单可以在 x e, x, p, r 里面去使用,我们也可以这样的,什么?我们也可以在 main 函数里面去使用,也就是 main 函数里面,我们也可以去直接使用。什么?直接使用我们的这个 sum 啊?那么所以说 sum 它是什么呢?它是大家都可以去使用的一个变量,所以这种变量我们称之为一个选举的变量。 好吧,那这个选举变量我刚刚不是讲了可以被其他文件所去使用吗?那其他文件怎么去使用呢? 要加 external 的 关键字对不对?那 external 怎么去使用?比如说我们有一个文件叫做一点 c 啊,另外一个文件叫二点 c, 我 们在一点 c 里面呢,去定义了一个 int a 等于十,这样的一个整形选举啊,选举的一个整形变量, 那我想在二里面呢,去同样使用这个 a, 我 不想再重新定义了,怎么去使用 external 加上 int a 这样子的一个定义?声明,哎,但是 千万不要去粗制化啊,粗制化会报错啊,为什么呢?因为 a 已经在一点 c 里面被粗制化了,已经粗制化为十了嘛,对不对?那这里我们只需要告诉系统,我呢,想要使用一个 已经被定义过的整形变量,这个变量叫做 a 啊, extra, 你 可以理解为就是告诉编辑,告诉系统, 我想要去用一个其他文件中的 int a 这个变量。对,所以为什么只需要声明,不需要粗制化?声明是告诉编辑器有我要用的这一个变量是什么类型的,对吧?叫什么名字?那不需要粗制化的原因是因为它在其他文件已经粗制化了嘛? 对,那我们在这里直接 a 等于十,它等价于就把一点 c 里面的 a 给它复制为十了,好不好?就这样一个过程啊, extend 的 一个外部声明,那所谓的静态的一个声明又是什么意思呢?静态声明就是让它的这个作用域做一个约束, 比如说一点 c 里面我的 int a 这个全级变量,我在前面使用了一个 static 啊,进行了一个静态声明,对不对?静态声明,你然后在二点 c 里面去进行这个 extend 的 外部声明,声明这个 int a 的 话,它是不行的啊,它是有问题的啊,这个 a r 因为一点 c 里面的这一个 a 呢,它使用了静态的修饰符去进行声明的,所以它只作用于本文件,它不允许作用于其他文件,就做了一个约束嘛,所以 extend 在 这个里面就不行了。所以说你来看的话,两个关键字的优先级的话呢? static 它是要高于 extend 的 好吧。啊,这个大家在实际的使用过程当中还是需要注意一下,好吧,好,那么这个呢,叫全局变量,那我们全局变量它竟然是定义在函数外部的,对不对啊?那么定义在函数内部的叫什么呢?我们叫做局部的变量 啊,定义在函数内部的,我们就叫局部变量啊,我们经常使用的,对不对?在函数体或者在某个复合语句中定义的变量,我们称之为局部变量。 局部变量的重要性的话呢,就是从局部变量定义的代码那个地方开始,一直到函数结束,或者是叫复合语句结束啊,什么叫复合语句嘛? 异符啊花括号里面写的那些指令都是复合语句,对不对?那复合语句结束了,也就是我如果在异符里面啊花括号第一行就声明了一个 int a, 那 么到最后这个花括号结束的时候,这个 int a 就 不能使用了啊,它就没有用了。对啊,什么意思呢?我们看一下啊,一个四 g 代码, 比如说,呃,我们这里定义了一个 int, 对 不对? int 它是一个局部变量,它的作用域在哪里呢?它的作用域在慢函数结束它就没有了,对不对?那这个里面呢,我同样定义了一个 b 等于十, b 的 这一个作用域在哪里啊? b 的 作用域一直到 if 结束, 他就没有用了,而且他就被回收了啊,这被系统给回收的, ok 吧?那这里的呃,我们的这一个 c 他 其实也是一个局部变量啊,他是在 four 开始的时候定义的,那 four 结束了,他就没有了,对不对?好,那么这里的 k 的 话,大家注意下,我做了一个错误的一个示范啊, int k 加等于十确实是没问题的, k 是 for 循环里面的一个局部变量,对不对?但是呢,它的花括号就已经结束了,它不能到这个 k 加加里面去使用,因为 你抛开座右铭来讲,你定义在后面,你怎么可能在前面去使用吗?对不对?我们前面函数的时候我们就讲了,你要想使用一个呃,新的东西,你是不是要提前告诉编辑器,你这都放到后面去告诉编辑器,让他前面去使用,肯定会报错吗?对,肯定会报错啊,所以这样子写其实是有问题的啊,不太允许的好吧, 那么我们这样子的局部变量 int a 跟 int b, 它们两个在不同的范围之内,对不对啊?一个在慢函数的这一个层级下,一个在 ef 函数的层级下,那么不同作用域的两个变量的话呢,它必定是两个不同的且独立的一个内存空间, 即便我们这一个变量重名呢,表示这里也是 a, 也没有关系。这个 a 跟这个 a 他 不是同一个 a 啊,就是张伟跟张伟他不是同一个张伟,对不对啊?就这么个意思 啊,他们呢,是因为作用域不同,就会导致他们系统在给他们分配内存空间的时候,他们所分配到的内存空间不同,但是他们的名字可以一样, 那这个时候有同学就会有问题了。老师,那我这个相同的局部变量,我在使用的时候,那系统怎么分得清我用的是哪一个啊?系统很聪明的好不好啊?系统呢?他即便你的局部变量重名了, 那他在使用的时候,他只会往上面去找最近的那一个,比如说我们这里定义了一个 a, 对 不对?那么 a 等于十,他会找谁呢?他会找这个 a, 那 如果说这里也是 a 的 话,那等于,那怎么办?他就会找这个 a, 他 不会再往上找,他只要遇到了第一个定义了这一个 a 的, 他就 以这个为 a 为基础,不会再往上找了, ok 吧?啊?这个是系统的聪明之处好吧?啊?比如说,呃, 我们一个循环里面,对吧?有一个 int i 等于十,然后 i 啊,等于等于十,对不对?然后下面再写了一个 i 等于五,那这个时候 will i 减减,它是判断了谁呢?是第一个 i 还是第二个 i 呢?肯定是第二个 i 嘛,对不对?它不会再往上去找了的,那你如果往上找的话,那这个 i 不 就跳过了,它就没有用了吗?对不对? 所以说他只会往上找第一个, ok 吧啊?找找第一个好。同时呢,我们需要注意的是啊,我们前面学到的这个函数里面啊,是不是存在一个行参列表?那这个行参里面定义的那个什么 int a 啊, int b 它是什么呢?它是局部变量还是全局变量? 肯定是局部变量,我们说局变量的定义是什么?他是在函数外部的,那么你的行差是不是也是定义在函数体函数的头里面?函数头里面对不对?他也是符在函数内部 嘛,所以呢,他行差他其实也是属于局部变量,那么行差的话,我们需要注意的就是,行差他是 不能给时差进行赋值的,也就是它没有办法去改变时差的。也当我们主调函数,调用背调函数且实际参数为变量的时候呢,你背调函数中的形式参数的变量的值,是没有办法反过来去改变实际参数的啊。就比如说,呃, 看一下啊,我们这里假设有一个 f 一 啊, function 一 和一个 function 二,那么 function 一 里面调用了 function 二,传了一个 i, 对 不对啊?然后 int 一个 i 等于十, 那放写 r 里面呢,也要 into 一个 l 好 不好?那这样子在调用的时候,这个 i 啊,它是可以改变 l 的, l 可以 变成十,但是 l 它没有办法反过来改变 i, 这个是不允许的啊,没有办法改变的 啊,所以一定要注意一句话,我们虽然说形式参数跟这一个实际参数他都是,呃,基本上都是,呃,不是,呃形式参数,他是属于局部变量,对不对啊?我们的实际参数他可以是局部变量,也可以是局部变量,虽然他们两个都是变量,但是他们 没有办法去改变,就是你在调用的时候他是没有办法去改变实际参数的, ok 吧?啊?没办法的,而且你的这一个实际参数如果是局部变量的话,你也没有办法在函数内部通过形式参数去改变局部的这一个。呃实际参数, ok 吧,因为他们两个在不同的作用域吗?好吧。 啊,因为我我跟你讲两个在不同的座右翼,是他们的地址空间不一样嘛,对不对?形式参数的值只是被复制为了实际参数的值而已啊,两者其实是互不影响的,他们并不是两个变量在进行一个复制,而是只是单纯的我们系统从 呃实际参数里面把这一个数据拿出来了,然后放到了形式参数里面了, ok 啊,并不是由我们的这一个实际参数直接复制给他的 好吧?啊,这个是我们座右铭啊,我们在学习的时候一定要大家要严格啊,要记住啊,要要要,要那个能够想清楚的一个点好不好?
