请问:1.3.6.7.几三个数相加减的方法有哪些减等于2

1.市场相关:汽车后市场定义:汽车后市场是指汽车销售以后,围绕汽车使用过程中的各种服务,消费者购车流程中,当新车完成交付后就进入汽车后市场,所以汽车后市场是一个非常庞大的概念。汽车后市场在广义上囊括汽车售出之后,围绕汽车使用的生命周期中的所有交易和服务,涉及汽车使用、维护、修理、再购买等等;其供应链则涵盖了一个由供应商到最终用户所连接成的商品流通结构。行业发展历程2018年,中国汽车后市场行业依旧持续受到资本关注,融资主体主要集中在汽车刚需服务市场——维修保养、汽配、车险三大细分领域。据不完全统计,2018年维修保养及综合服务市场发生40次融资事件,可见维修保养仍是资本更为看重、发展潜力更大的市场。行业融资情况2018年,中国汽车后市场行业依旧持续受到资本关注,融资主体主要集中在汽车刚需服务市场——维修保养、汽配、车险三大细分领域。据不完全统计,2018年维修保养及综合服务市场发生40次融资事件,可见维修保养仍是资本更为看重、发展潜力更大的市场。1.1市场容量的测算,以及过去五年的增速,未来五年的增速(1)全球汽车后市场过去增长速度及未来增长速度预测根据麦肯锡2018年发布的全球汽车后市场统计数据显示,2017年全球汽车后市场规模约为8000亿欧元,其中北美地区汽车后市场规模约为2700亿欧元,欧洲地区汽车后市场规模约为2400亿欧元,中国地区仅次于北美地区和欧洲地区,为全球第三大市场。根据麦肯锡预测,全球汽车后市场未来10年将以年均复合增长率3%的速度增长,预计2018年全球汽车后市场规模约为8250亿欧元。(2)中国汽车后市场增长速度及增速中国汽车保有量不断增长,汽车后市场规模逐渐壮大中国经济水平保持稳定增长,我国居民也逐渐“富”了起来,随着人均可支配收入的逐渐增加,买车成为了许多家庭列上日程或者已经实施的计划。据公安部统计,截至2018年底,我国机动车保有量已达3.27亿,其中汽车保有量2.4亿,比2017年增加2285万辆,增长10.51%。我国已经超过日本,成为全球第二大汽车保有量地区。汽车保有量不断增长的背后预示着汽车后市场规模的不断壮大。2017年,我国汽车后市场规模突破万亿元大关,达到1.07万亿,预计2018年将保持19%以上的速度继续增长,市场规模约为12790亿元。在汽车保有量方面,2018年,我国汽车保有量2.4亿辆,其中小型载客汽车2.01亿辆,首次突破2亿辆。在成熟国家的汽车产业链中,汽车后市场的占比在50-60%,而我国目前只占到10%左右,还有很大的提升空间。据预计,2019-2022年我国汽车后市场将保持在10%-15%的市场发展增速。预计到2023年,汽车后市场的规模将达到2.3万亿左右。汽车加油市场规模达26250亿元汽车加油是汽车后市场养车用车一笔最大的开支,中国2.5亿辆汽车(不算其他机动车),平均每年按行驶1.5万公里,0.7元每公里油耗计算。有些车辆每年行驶里程很少,而有些车辆如营业和的士车辆行驶里程大大超过1.5万公里,我们按平均1.5万公里求平。同样,油耗也是一样道理,按0.7元每公里求平。因此,汽车加油市场规模则达到26250亿元。车动邦青哥说车,只能进行预测,相信中国三桶油应该有准确数字。汽车保险市场到8000多亿元,为后市场第二大规模市场购买新车首先就需要购买汽车保险,汽车保险有交强险和商业险,交强险是强制购买的,没有购买交强险的车辆是不能上路行驶的。那么,中国2.5亿辆汽车,交强险平均为1000元每车,交强险市场规模则为2500亿元。而商业险是根据保额大小而定的,同时保险公司会根据车辆每年出险的次数进行优惠,因此也只能求平,按每车保额50万元计算,每车每年3500元,商业险年市场规模则达8750亿元。相关媒体报道过中国保险市场规模为8000多亿元,车动邦概算为8750亿元,也是准确的。汽车救援市场规模不大,仅62.5亿市场规模车动邦将汽车救援单独核算,是考虑中国高速公路里程长,高速救援为归口交警管理,是单独的救援机构,包括城市救援机构也是单独核算的。汽车救援整体规模不大,救援数据尚无准确数据可查,一辆车平价年救援次数不到一次,中国百辆汽车年救援次数为五次,每次救援金额至少500元,汽车救援市场规模则达62.5亿元,考虑保险机构和汽车后市场维修保养机构也会提供会员免费救援,因此汽车救援市场规模只能按60亿计算。汽车保养市场规模:6000亿购买新车一半都会由汽车4S店免费提供首保,因此首保后,严格意义上讲,都是车主需要出费用,因此就离不开保养费用了。而汽车有小保和大保,中国2.5亿辆民用和小车保有量,每次保养金额按平均1200元计算(小保300-500元左右),一年平均保养2次,则市场规模为6000亿。汽车美容清洗规模不可小视,达3800亿元汽车美容和清洗是车辆养车用车中消费相对高频项目,一辆车平价每年洗车24次,平价每次洗车30元,则洗车市场规模达到了1800亿元。同时,汽车抛光、打蜡、镀晶、修补也已经成为车主经常消费项目,是修理和美容服务门店主要业务,因此洗车为门店引流项目,汽车美容为盈利项目,汽车美容市场规模比洗车市场规模更大,车动邦按每车平均800元计算,则美容市场规模为2000亿元。因此,整个汽车美容和清洗年市场规模为3800亿元。汽车用品和电子市场规模也不可忽视,达800-900亿规模汽车用品为车主购买车辆后的美观、辅助功能、便利、舒适性方面加装的汽车用品和汽车电子产品,如座椅、座套、方向盘套、安全锤、三角警示牌、随车工具、形车记录仪、导航仪、手机支架、充电器、倒车雷达、全景摄像头等车载设备和电子等。汽车用品和电子也已经成为一个独立的市场,行业数百家用品和汽车电子企业参与竞争,年市场规模至少达到800-900亿规模。汽车DIY及改装市场规模:由于中国汽车DIY市场还没有形成规模化市场,汽车改装主要为车辆颜色、动力、个性化等和汽车改装相关的有改装件、改装耗材、工具设备,也形成了一个独立的市场。中国对汽车改装有严格的政策法规规定,但随着车辆普及和车主个人化追求,国家在车辆改装法规在逐步放松。中国汽车改装行业预计达200亿规模大小。而汽车DIY市场正在快速成长,将可能成长为年600亿以上的市场规模。汽保设备工具行业增长迅速,已达100亿规模汽车维修保养设备简称为汽保设备,汽保设备逐步从维修行业析出,已经发展成为了一个独立的行业,每年3-4月在北京将举行汽保设备行业大规模的展会,吸引1000多家行业企业参展。近5年来,中国汽保行业得到快速发展,市场规模从60亿左右增长到了100亿规模。尽管行业容量不大,则增长速度快。汽车二手车和金融市场规模:1万亿中国存量的汽车保有量和2800亿辆的增量市场,促进了中国二手车市场的快速发展。随着汽车保有量提升和国民换车速度加快,同时国家也出台了各种支持二车车销售和流通的政策,在库存融资和消费信贷等支持下,中国二手车市场迎来了爆发期。中国二手车行业从收车、评估、销售、售后服务和保养、金融和再评估,已经形成一条龙服务。中国二手车年交易达1500万辆,年市场规模达1万亿规模。总结:广义中国汽车后市场规模为6.5万亿,狭义中国汽车后市场规模为1.1万亿综合计算,广义上的中国汽车后市场规模整体已经达到65637.5亿元,超过了了6.5万亿市场规模。而狭义的中国中国汽车后市场规模,即汽车维修保养市场,规模为11775亿元,为1.1万亿市场规模,不到1.2万亿。准确地说,除了整车制造和销售外的中国汽车后市场规模为6.5万亿,而狭义的汽车后市场即维修保养用品配件市场为1.1万亿市场规模。1.2市场增长的主要渠道因素影响汽车后市场需求的两大因素是:汽车保有量和汽车产业链利润结构。(1)汽车保有量根据公安部交管局公布的最新数据,截止2019年6月底,国内汽车保有量已达2.5亿辆,如果按13.95亿人口计算,中国千人汽车保有量已经达到179辆,超过世界千人汽车保有量平均170辆的水平。这是中国汽车保有量首次超过2.5亿辆,也是千人汽车保有量首次超过世界平均水平。其实,早在2017年一季度末,中国汽车保有量就超过2亿辆。有专家曾预测,到2019年,中国将超过美国的2.53亿辆,成为全球汽车保有量最多的国家。从现在的发展趋势来看,今年三季度中国就会超过美国,成为全球汽车保有量最大的国家。总的来说,随着汽车保有量的上升,汽车后市场也将得以快速发展,并有望保持两位数以上的增速。不过要进一步规范行业发展,切实给客户提供完整的服务解决方案。据前瞻产业研究院发布的《中国汽车后市场行业市场前瞻与投资战略规划分析报告》数据显示,我国汽车后市场规模已由2009年的2400亿元增至2015年的8000亿元,预计未来几年保持中高速增长,到2020年市场规模达到14350亿元。(2)汽车产业链利润:随着我国汽车保有量的增加,汽车后市场规模逐渐扩大,行业发展迅速。截至2012年,我国汽车后市场营业额达到4900亿元左右,2009-2012年年均复合增长率达到27.80%。  从销售利润方面看,国外成熟汽车市场中,整车的制造、销售利润约占整个汽车业利润的21%、零部件供应的利润约占22%,50%-60%的利润是在服务领域中产生。以美国为例,美国汽车售后服务年产值高达1400亿美元,汽车维修业的利润率达到27%。随着我国汽车产业利润的逐渐下降,汽车制造商开始向后市场需找利润,我国汽车后市场占整个产业链的利润将会逐渐上升。由于新车销售预期放缓,行业竞争加剧,对于厂商和经销商而言,来自于新车销售的利润必然会减少,其业务重心将会转向后市场。广义的汽车后市场是指汽车销售以后,围绕汽车使用过程中的各种服务,它涵盖了消费者买车后所需要的一切服务。图:成熟市场汽车产业链利润分布从成熟市场的汽车产业链利润结构来看,根据易观的数据,其后市场利润占比一般为65%左右,而国内占比不到30%,仍有较大的提升空间。长期以来,汽车后市场以一二级城市消费者为主,不过近期城市线级呈现不断下沉趋势,目前三四级城市消费者比例高达43%,超过大部分其他行业。未来,来自三四线城市的后市场消费需求将进一步推动产业利润结构发生变化。从内外环境看中国汽车后市场行业发展驱动因素近年来,中国汽车后市场在线服务市场发展迅速,已经成为汽车后市场中核心组成部分之一,是对传统后市场渠道、服务、价格、效率等各方面的优化和升级。在线服务市场的发展离不开外部环境与内驱动力的作用。外部环境中,1)多项相关政策的出台,打破原有传统服务及产品渠道格局;2)汽车消费大众化,消费升级带动更多元化汽车消费,资本更关注市场分散但潜力巨大的后市场领域;3)大众已经习惯线上服务模式,市场容量充足。内驱动力中,1)用户痛点频现,价格合理、高效便捷的模式需求明显;2)企业根据自身资源情况,切入不同垂直领域,核心业务也不尽相同;3)同一垂直领域中,多种模式相继出现,市场竞争激烈,业务范围逐步扩大,服务质量及品质要求提升。1.3产业链的上游下游分别是谁?集中度如何?养车的上游是汽车配件供应链,客观来说,配件供应链是比较强势的,下游和上游的议价权取决于其渠道的大小,渠道越深越广,背后的底气也就更强。1.传统模式及物流供应链在早期传统的汽配行业,经营主体是多层级的经销商,与客户线下对接的是城市中大大小小的汽配城,经销商根据经营规模的大小或者供应链的不同层级而进行分类。这一阶段的备件经销体系最大的特点是:层级非常多,经营主体高度分散,通常位于供应链上游的一级分销商才能拿到主机厂配件,下游的经销商则向其上一级经销商拿货。从广义上而言,各品牌汽车4S店也属于经销商范畴,区别在于4S点库存主要服务自己的维修厂,而经销商服务对象是广大的汽车维修厂。2.互联网下的新模式及物流供应链在互联网新经济环境下,汽车后市场近几年涌现出一批平台型备件零售商,他们通过B2B平台,实现向更广泛的市场区域客户群体提供更多的SKU。在供应链物流体系建设方面,通过建设物流中心,将更多类别的配件集成在统一的设施下进行管理,并在全国主要区域城市建立区域仓,服务广大的市场区域。在新的模式下,尽管后市场的主要客户仍然是维修厂,但由于汽车品牌、车型众多,从物流和供应链的组织角度来看,难度却更大。目前,互联网平台型企业加快进行汽车后市场的信息化系统、数据库建设,以及供应链体系、仓储物流体系、末端配送网络的搭建,但是要形成覆盖广泛、时效性高的物流网络布局尚待时日。目前来看,在国内汽配流通行业,虽然部分创新型公司暂露头角,但市场份额占比依然极低,市场整体都还处于高度分散的状态。汽配行业是很传统又很重的领域,从美国市场的发展历程来看,如今的四大巨头都经历了至少三十年的时间,才取得合计30%的市场份额。国内的创新企业虽然切入点各有不同,但所有的模式都绕不开线下服务。调研发现,除了最初从线下切入的公司,其余玩家也准备布局线下业务。而且汽配行业本身具有极强的地域属性,企业需要不断的建新店扩大自己的服务范围。美国独立汽配连锁老大AutoZone,经过30多年的发展,到目前已经拥有自营门店近6000家,至今仍在以每年200家左右门店的速度进行稳步扩张。国内市场目前处于第一梯队的康众汽配,其扩张策略与AutoZone类似,坚持自营,每年新增门店100家左右。从单店人效角度来看,康众当前的人效已经接近成熟状态下的AutoZone。AutoZone的毛利率在最初的二十年一直维持在40%左右,最近十多年毛利率更是一路上涨,2011年之后已经超过50%,仍然在稳定增长中。而康众的毛利率只有20%,这也是目前扩张较慢的原因之一。结论:中国汽配市场集中度将低于美国市场。剩余的市场参与者们,大多数都在以美国市场的四大巨头为对标,但是由于毛利率低于美国同行水平,所以头部公司需要更长的时间才能脱颖而出。所以,国内高度分散的市场仍然会持续相当长一段时间。再加上国内维修店的数量是美国市场的近2.6倍,所以整体市场集中度也会低于美国市场,需要更长的时间才能达到美国如今较成熟的市场现状。2.竞争格局相关:2.1目前市场上汽配维修行业的主要玩家是谁?分别的市场份额是多少?中国汽车后市场配件部分市场规模约6,000亿,但行业中存在超过50万家各级经销商、贸易商,下游大大小小的修理厂接近100万家,而目前市场上几家头部汽配B2B平台的市场份额合计不超过5%,基本没有对行业形成太强的话语权。反观美国汽配行业,在总量近9,000亿人民币的市场中NAPA,AutoZone等行业四巨头已经占据超过30%以上的份额,从生产到流通再到零售,共同掌控着美国汽车后市场供应链生态。当前汽车后市场中,4s店依然占据主体地位,在汽车养护市场中,4s店依然占主体地位,占比约七成,其次为除4s店之外的其他线下渠道市场份额约为29.0%,互联网养护渠道约占2.9%的市场份额,但随着互联网及移动互联网的快速发展、用户消费习惯的改变,互联网养护渠道的市场渗透率逐渐扩大。在互联网养护渠道中,自营型养护电市场业务增长迅速。自营型养护电商在供应链和线下服务能力方面优势凸显,在2016年全年中市场份额持续增长;综合电商凭借强大的流量优势保持领先的份额占比;服务提供平台目前处于模式转型和探索时期,主要以导流业务或以线下加盟连锁门店形式,将业务重心转向线下服务。从2016年上半年数据来看,途虎养车App端用户规模保持稳定增长,月均覆盖人数超过130万人,远高于其他养护电商用户规模;在市场中具有明显的流量优势,拥有丰富的用户基础。在用户留存方面,目前多数养护平台留率在15%-30%区间内,主要处于第二级别;途虎养车用户留存率相对较高,处于第三级别,留存率约为30%-50%,用户留存率较高。目前在汽车后市场领域,电商模式主要有垂直类电商(主要形式为B2B)、水平类电商(主要形式为B2C)、服务类电商(主要形式为O2O)模式,其中垂直类电商模式要求消费者具备相应的车辆或保养知识。以一般消费者为基础的电商模式主要有水平类电商模式和服务类模式。从商业模式来讲,主要分为B2B和B2C两种模式:B2B业务模式是通过汽车配件生产厂商提供相应配件给汽配B2B平台,直接发送给汽修厂,为打通汽配上下游,平台作为供应链管理平台,业务覆盖包括汽配商城、仓库管理、运输管理以及应用数据等;B2C业务则是车主在平台下单后,选择将配件送到汽车修理厂,由汽修厂为消费者提供服务,平台为搭建供应链管理系统,需要完善汽配商城、仓库管理、运输管理平台,搭建应用数据系统。汽车后市场水平类电商模式大多数属于综合类B2C平台,如天猫汽车、京东车管家等等。这类平台对于汽车专业的要求一般,准入门槛相对较低,销量较大的一般是易耗品(轮胎、雨刮)及用品(汽车内饰、清洁美容用品等)。汽车后市场服务类电商模式大多数属于O2O模式,如途虎养车网、车蚂蚁、车享网等。这类平台通常是由消费者在线上根据自身的品牌车型选择所需的配件型号,在线完成线上产品(线下服务)支付,随后根据所需选择门店进行线下服务,线下服务完成后再完成线上评价的过程。垂直类电商为B2B模式,提供汽车综合服务,如今国内的玩家主要有甲乙丙丁、玉米好车、三头六臂、快准车服、汽车街等。2.1.1国内目前市场中玩家细分2019年初,汽车后市场用户突破4千万大关,汽配维保用户突破1千万大关。其中,途虎养车用户覆盖率达46.2%。·活跃用户规模途虎养车的活跃用户在2018年12月达到427.2万,相比于第二名的乐车邦和车享家分别月活23.2万和20万,是20倍左右的量级。可以算是一家代表一个行业。从数据来看,途虎养车在月活用户规模、使用时长等方面均处领先地位,已经成为这一领域的绝对领跑者。首先,途虎养车的用户量占据绝对优势。从2017年上半年的线上养车移动端活跃用户的数据统计来看,途虎养车的活跃用户从1月份162.89万人,2月171.63万人,稳步增长到6月份220.67万人。这意味着约一半的线上养车移动端用户都在使用途虎养车APP。仅从6月份单月的数字来看,与主流中的行业其他APP相比,途虎养车的活跃用户超过了案例中四家的总和。不仅如此,途虎养车的用户黏性与忠诚度远远超过同业者。以途虎养车等五家线上养车平台为例,从5月份的线上养车移动端使用数据来看,途虎养车的APP启动次数居首位,达到1596.9万次;与APP打开次数相呼应的是,5月份途虎养车APP的使用时长也长达224.1万小时。从5月份独占用户和渗透率情况也可以看出,途虎养车的用户渗透率为45.1%,其独占用户在车后服务领域的占比已经达到37.5%,几乎占尽半壁江山。在眼下独立APP获取新用户难度加大、成本增高的情况下,这一数据更彰显出途虎养车的优势市场地位。易观分析认为,正是由于途虎养车提供的线上和线下服务能够满足车主在用车生活中的绝大多数刚性需求,因此在忠诚度和信任度方面都将同业者远远抛开。国内竞争格局:·B2C电商(1)汽车超人汽车超人创立于2015年,是上市公司金固股份旗下推出专注于打造汽车服务新零售品牌。2018年,金固股份汽车超人宣布获得阿里巴巴战略投资,并将平台供应链业务与阿里天猫汽车、康众汽配进行战略重组,成立天猫车站(新康众)。原有汽车超人品牌则重点通过供应链整合,门店系统,线上精准营销,流量导入,品牌建设,数据服务,新零售业务导入等信息化手段来赋能改造线下汽修门店,打造汽服新零售,推动产业升级。汽车超人为金固股份旗下特维轮的平台,2016年定增27亿到账,主做B2C电商,主要做轮胎和油品。2018年,阿里天猫方面宣布,天猫汽车联手金固股份旗下汽车养护平台汽车超人、汽配供应链服务商康众汽配,成立汽车后市场新公司(下称“新公司”),组建汽服新零售支撑体系,驱动汽服行业升级,为车主提供高效、可信赖的服务。在这个合作基础上,汽车超人的业务也进行了新的调整:一方面,原有供应链业务并入天猫车站,联合金固股份、天猫汽车、康众汽配三者的优势打造全新的供应链平台;另一方面,汽车超人仍保留原有的品牌,拓展门店新零售业务;截至2019年2月,天猫车站认证门店将近1500家,2019年开年不到两个月完成全年目标的1/3。未来五年,天猫车站认证门店预计将达到50000家。通过汽车超人与康众汽配的整合,当前天猫车站几乎实现了车后品牌商的全覆盖。同时,在仓配服务上,上述人士透露称,天猫车站当前拥有近800个前置仓,今年年内将达到1500个,覆盖全国一二线城市。本次投资完成后,阿里巴巴对汽车服务行业的战略布局已经基本完成,实现了从购车到车辆维保的汽车全生命周期服务。同时,随着滴滴、阿里等巨头深入布局汽车后服务,整个汽车后市场也迎来“大玩家时代”。可以预见不久的将来,车后市场里服务质量差、效率低的小玩家将会迅速淘汰,市场份额将逐步向头部平台集中,行业壁垒也由此形成。(2)车享家车享(上海赛可电子商务有限公司),车享网于2014年3月28日上线,是由上汽集团全资投资的汽车电子商务网站,以整车电子商务切入。2014年上线至今,秉持“车生活心享受”的品牌主张,结合“高效线上运营”和“优质线下服务”,全方位打通汽车“看、选、买、用、卖”O2O,一站式提供汽车全生命周期价值服务。现旗下已拥有车享网、车享家、车享家App等多个业务承接平台,以及车享新车、车享二手车、车享汇、车享付、车享配等多个业务类型,成功打造了汽车电商行业独树一帜的“车享模式”。2015年9月20日,上汽集团正式发布其“全生命周期”连锁实体服务品牌--“车享家”,全面进军汽车后市场。车享家专注于售后服务市场,这是汽车O2O创业项目中,被大多数投资人看好的业务领域。目前车享家在全国超过110个城市线下直营门店已达1100家,用户达到220W,在2020年,力求把车享家打造为中国汽车服务市场的领导品牌,整体市值达到千亿,线下服务网点达到一万家。作为车享家800家门店的线上入口,车享家APP用户已超200万,且用户活跃度稳居汽车服务类APP前5。目前平台累计用户量:0.62亿人次;平台月活用户量:362.6万人次;平台日均车主意向需求对接量:6156笔;平台月度增长率已经达到了130%;平台预估年度对接线上线下需求交易总额:126.8亿元。2017年12月1日,车享家在上海召开了B轮融资暨合作发布会,正式宣布获得由平安、中国太平和招商财富共同投资的约10亿元B轮融资2016年车享家获得了A轮融资,资金规模高达上亿元B轮融资后,车享估值大幅增长至62亿。(3)养车无忧养车无忧网成立于2012年底,是一家汽车保养服务电商。养车无忧主要提供在线保养O2O服务,其核心竞争力在于从源头采购正品并以低于4S店的价格提供给终端消费者。由专业汽车保养维修配件及养护用品B2C在线商城以及线下专业的保养快修服务站网络组合为车主提供服务。从原厂配套的国际大型零部件生产商直接采购保养配件直接销售给车主,既保障与原厂件一样的品质,又因减少了中间环节而大幅降低成本,这为广大车主带来了福音,让所有爱车族真正做到了养车无忧。经过多年发展,养车无忧积累了国内领先的保养和配件数据库,目前平台注册用户超过100万,其中日均UV近10万,特约安装服务商户的数量达到了1200家。融资转型情况:2017年8月24日,汽车后服务平台企业养车无忧成功获得千万元级投资,本轮投资方为杭州资典资产管理有限公司。投资完成后,养车无忧将从战略到模式上进行全方位的调整,并由李立兵出任新养车无忧CEO。目前养车无忧已经梳理出更完善的S2b2c的模式,结合配件超市连锁、连锁联盟品牌管理、金融中介、无忧云信息系统在内的四大体系。未来养车无忧将采用一城市一品牌的模式。养车无忧选择与各地知名连锁品牌合作,通过养车无忧的供应链能力、系统能力、金融能力、车务资源整合能力帮助他们成就百店规模和提升盈利能力,未来养车无忧将完成30城市30个品牌2000-3000家门店的拓展。财务数据来看,养车无忧2014年亏损800多万,2015年亏损5000多万,2016年1-11月亏损2900多万,特别是2015、2016两年亏损约8000万。先锋新材增资投入的6210万在半年的时间内已所剩无几。根据20%的股权售价6210万元,也可以计算出,养车无忧目前估值为3亿元左右。(4)途虎养车(后有详细介绍)途虎养车于2011年在上海创立,主营轮胎、机油、汽车保养、汽车美容、车品等,提供“线上预约+线下安装”的养车方式。在汽车后市场的电商平台中,途虎汽车被外界认为是目前最为专业的平台之一,而且有腾讯投资加持。途虎在融资上领先很多。2012年2月途虎便完成天使轮融资,而2018年9月途虎更是完成了由腾讯等领投的4.5亿美元的E轮融资。官网显示,目前途虎养车在全国拥有13000多家合作安装门店和超过1000家工场店,覆盖405个城市。以69亿元估值的途虎养车,是汽配零售中鲜有的B2C玩家。途虎参考了AutoZone的B2C模式,又进行了本地化调整。客户在线上选择和购买配件,然后到途虎的合作维修店进行安装。这种线上购买线下安装的闭环模式已初步得到验证,汽配B2C在国内也是可行的。2016年,途虎的营业额达到22亿元,增长速度超过了100%,其中高毛利的养护服务订单数量增速超过了150%。·B2B电商(1)康众汽配康众汽配成立于1995年,是国内第一批直接服务终端修理门店的B2B售后配件直营经销商。康众自创立起采用的就是直营开店的重模式,目前在全国建立超过700个服务网点,服务全国10万多家维修企业。作为国内B2B售后配件直营经销商的老牌大哥——康众汽配,在面对“互联网+”在不断冲击汽车后市场时,并没有后退一步,而是迅速积极转型。门店数:目前康众业务覆盖全国27省150多个地级市,拥有17个区域中心仓,310多家门店,其中已经正常营业的代理门店有20多家。康众在全国已经构建了141个直营网点,10个区域大型仓储中心,每月累计为近3万家修理厂提供精准供应服务。2017年7月康众汽配完成5000万美元B+轮融资,投资者为国内某保险集团和中金甲子,原有股东基石资本等跟投。2016年11月,康众汽配获得高盛B轮投资,这也是高盛在中国汽车后市场行业的首个股权投资项目。2015年,康众获得2亿元A+轮融资,同时对外开放品牌加盟,全国范围内招募代理店,加速线下布局。财务数据:毛利率20-30%,2017年估值超20亿康众运营成熟的门店的销售额为500-600万元,毛利率在20-30%。2016年康众汽配营收超10亿元,根据康众每年门店数量可以推算出,新开门店的销售额需要1-2年才能稳定在500-600万元。2017下半年康众预计新增50家门店,据此推测康众2017年营收在15-18亿元。2018年天猫汽车再次联合汽车超人、康众汽配建立三巨头联盟“新康众”,这三巨头背后分别代表着车主流量、维修服务和汽配件供应链的巨大势能。新康众是一家致力于网络覆盖全国的汽车后市场一体化服务商,在康众汽配连锁的基础上,融入了原汽车超人的部分供应链、阿里巴巴集团汽车后市场业务及相关资源而成立,并先后获得阿里巴巴、华平投资、云锋基金、PAG投资、美国高盛等投资机构数亿美元资金注入。目前公司已在全国设立配件供应网点900多个,计划在2020年末将发展网点到2000家,保障区域内维修客户需求“30分钟”送达。目前新康众是BP、壳牌、美孚、采埃孚、固特异、邓禄普、大陆、博世、盖茨、曼·胡默尔、索菲玛、泰明顿、飞利浦、NGK、天纳克、舍弗勒、安普得、阿西莫、帕诺德、力普拉斯等众多国内外知名品牌的经销商、全国性战略合作伙伴或专业维修网络服务商,并拥有阿里巴巴集团天猫车品和淘宝车品的独家运营权授权。(2)中驰车福以30亿元估值的中驰车福成立于2010年,是汽配B2B电商平台。中驰车福电商是集互联网技术开发、应用、网上商城平台、汽车数据平台、供应链云平台于一体的综合化垂直类服务平台。该平台是依托互联网云技术,建立从零部件生产企业到汽修企业、汽修企业到车主及增值服务集合的B2B2C+O2O垂直类行业平台,利用创新的商业模式及互联网思维,为汽修企业提供“一站式”的维修配件采购平台,同时为车主提供包含维修保养、汽车救援、新车销售、车险销售理赔、汽车租赁、二手车等业务在内的全方位、一站式的车主服务。融资情况:继拿下1.6元A轮融资后,中驰车福再获B轮融资。依托互联网云技术,建立起从零部件生产商到汽修企业、汽修企业到车主及增值服务集合的B2B2C+O2O垂直类行业平台。勇于用新思维的中驰车福显然已经在行业内细心布局,硕果自然是累累的。门店数:中驰车福在全国建立了超过25个中心仓,1000个左右分仓,并招募了超过200个城市合作伙伴,为平台大客户做最后一公理配送,与博世、飞利浦、盖茨、等国际汽车零部件巨头签署战略合作协议,授权提供公司旗下全线产品的供应链服务与终端客户服务。中驰车福目前的SKU数量超过了100万,这背后依靠的是大数据和云平台的支持。中驰车福高效的供应链和极快的配送速度,得益于优秀的物流系统。中驰车福销售人员近千人,地推能力强悍。近期,中驰车福对外公布,2016年营业额超过20亿,增长速度超过了100%。中驰车福2016年销售额为20亿元,其中自营产品虽然只占总SKU的20%,但是却拿下总销售额80%。原因如下:1.易损件客单价虽然较低,但属于高频产品,销售额占比30%;2.车型件虽然交易频次较低,但是客单价较高,直接拿下50%销售额;在毛利率方面,易损件的毛利率在10%以上,车型件的毛利率比易损件较高,在20-30%。拆机件和积压件由于是撮合模式,平台会收取10%服务费。认为公司整体业务未来最多保持15%毛利率,反观美国四大巨头动辄50%的高毛利率,而且每年还在稳步增长。除去本身规模效应带来的效率提升,还通过大量压货,倒逼生产厂商降价的方式,降低自身的采购成本。2.1.2美国市场主要玩家在美国,独立汽车后市场的份额占据70%,4S体系的份额占据30%。对于车主来说,独立后市场是最高效和便捷的选择。从2010年开始,4S店减少了2000家左右,独立后市场门店维持不变。增长速度最快的独立后市场门店类型是专修门店(比如宝马、奔驰、大众等),从2008年以来增长了14%。在美国市场,美国四大配件领域四大连锁AutoZone、AdvanceAutoParts、O'Reilly、NAPA屹然山立于百亿美金市值,维修服务领域也有MonroMufflerBrake、Valvoline等数十亿美金市值的独角兽,但中国始终未能出现能与之放在同一维度下对比的上市巨头。在AutoZone从一家汽配店发展成市值百亿美金的巨头企业期间,美国汽配零售行业得到了蓬勃发展,AutoZone、AdvanceAutoParts、O'Reilly和GPC(NAPA)形成了稳定的行业头部格局,它们占据约30%的市场份额。四家汽配连锁最新季度营收数据:AutoZone:27.83亿美元,同比增长4.7%;GPC(NAPA):49.34亿美元,同比增长2.3%;O’Reilly:25.89亿美元,同比增长5.4%;AdvanceAutoParts:23.32亿美元,同比略增0.24%。前文提到,AutoZone的毛利率在最初的二十年一直维持在40%左右,最近十多年毛利率更是一路上涨,2011年之后已经超过50%,仍然在稳定增长中。而康众的毛利率只有20%,这里通过中美市场的对比以及autozon自身的优势来说明为什么美国四大汽配零售巨头毛利率在50%左右,而国内同行毛利率普遍较低?中美市场对比:尚存差距,毛利率相差30个点美国汽车市场发展较早,在汽配经销领域已经有AutoZone、NAPA、O'Reilly、CARQUEST等知名企业。中美汽配经销商存在一定的相似之处:1.必须自己备库存,能够快速把货送到修理厂。2.都需要有一套完善的信息管理系统,包括仓管、采购、运输等模块,仓配效率是中美企业的关注重点。美国汽配分销市场相对成熟,更加注重服务体验,而非配件交易本身。而中国经营环境恶劣,假货、不开票、偷税漏税等在汽配销售行业比较普遍,中美企业的竞争环境存在较大差别。从利润情况看,美国汽配经销商的毛利率在50%左右,国内普遍低于20%,相差30个点。而在净利率方面,美国企业普遍高于10%,国内规范纳税的企业不会超过5%。其实,美国市场早期竞争激烈时,毛利率也没有这么高,中国目前与美国初期情况类似,但国内市场比较乱、信用较低、竞争激烈,各玩家进行价格战,导致毛利率低。另外,中国市场存在不开票、假货等现象,这些也是造成的毛利率较低的原因。此外,美国服务费比较高,修理厂的人工成本特别高,一般修理厂不做零部件差价,而是靠工时费来赚钱,所以在汽配店到维修厂之间的价值传递过程中,修理厂赚差价的部分很少。人工价值在美国零部件市场中占比很高,促使美国培育了DIY市场,中国目前尚未存在这类市场。整体上看,中国的汽配经销市场较美国的成熟市场还存在很大差距。AUTOZONE:AutoZone是全美市场份额最大,市值第二大的汽配零售商,市场份额约为8.86%。2016财年毛利润和净利润双料第一,净利润更是远超第三名AdvanceAutoParts,主要得益于近6000家线下直营门店和面对上游供应商强大的话语权。其1990财年~2018年财年的销售额与毛利率的变化如下图所示,可以看到在近30年的时间跨度里,AutoZone的销售额从6.7亿美金飙升至112.2亿美金、同时其毛利率也从38.1%提升到了53.2%(同时股价上涨超过40倍),本质上就是因为在销售额不断增加的情况下上游集采带来了采购成本的大幅下降、DC(DistributionCenter)-Hub-Store体系下的物流&仓储成本也在不断下降。线下门店销售占绝对优势AUTOZONE销售的汽配产品主要包括易损件、维修件和其它零配件等。在美国市场电商如此发达的当下,AutoZone线下的销售额占比依然惊人。2014和2015年线上销量的占比分别为3.62%和3.56%,线上销量的占比呈下降趋势。造成线上线下占比巨大悬殊的原因跟AutoZone的发展历程息息相关。它先是经历了连锁化,AutoZone一直以来的发展路径都是线下门店经营模式,通过在线下大量的铺设门店,来集中化服务周边社区购买汽配零件和修车的需求。AutoZone的汽配帝国——5000家连锁店的规模效应AutoZone是美国当地、区域和国家修理厂、经销商、服务站和公共部门客户的汽车零部件和其他产品的领先经销商。AutoZone是美国最大的汽车修配连锁品牌,前身Autoshack建于1970年,1979年开设了其第一家店,并命名为“汽车小屋”,1987年更名为“AutoZone”。1988年,AutoZone走出美国扩张到墨西哥。1991年AutoZone在纽交所上市(NYSE:AZO),其连锁卖场主要集中于美国东部及西海岸经济较发达城市。主要经营汽车配件、维修器件等,同时也提供汽车信贷服务、销售汽车诊断和修理软件。这家成立于1979年的公司在美国已经拥有了超过5000家连锁店。截止2014年,AutoZone在美国49个州以及哥伦比亚和波多黎各拥有4984家连锁店,在墨西哥拥有402家店,而在巴西拥有5家连锁店,共计拥有5391家连锁店。加上收购的近800家门店,Autozone预计在2017年拥有超6000家线下门店。AutoZone线下门店类型分为四种:分发中心(超过15万种SKU)、大型中心店(8-10万种SKU)、中心店(3.5-5万种SKU)和卫星店(2-2.5万种SKU)。AutoZone经历了连锁化,一直以来的发展路径都是线下门店经营模式,通过在线下大量的铺设门店,来集中化服务周边社区购买汽配零件和修车的需求。其中,卫星店主要提供大众化、最常用的配件,此外,还会基于选址时对当地车型车况的调研数据,额外搭配基于当地特色车型的常用配件。如果出现缺货情况,则由上级中心点或分发中心逐级向下配送,利用自有物流或第三方物流,最快当天即可到达。目前共有10个分发中心(还有2个在建设中),11个大型中心店,以及182个中心店。平均每1个中心店覆盖周边17个中心店,每1个中心店覆盖周围32家卫星店。中心店每周会从分发中心补给多次,以保证产品从中心店运送至卫星店在24小时内完成,卫星店还专门负责最后一公里的配送。上游生产商多样化策略,提高话语权Autozone依赖国内和国际供应商继续以优惠的价格和付款方式向我们提供优质商品。在供应链后端环节,最初AutoZone尚未建立规模优势和品牌知名度不高时必须通过零配件经销商来采购零配件,此时跟上游经销商和生产商的议价权有限,需要通过优化自身作业流程,提高前端效率来完成初始积累。在确立规模优势后,AutoZone可以绕过经销商直接与生产商接洽,在降低采购成本的同时,甚至可以执行反向定制化产品开发。在采购方面,AutoZone没有与某一家供应商签订长期供货协议,而是采取多家供应商并存的策略。一方面可以增加配件等货源的渠道,不受制于单家供应商,另一方面越来越多的生产商愿意提供更长的应付账款账期来成为AutoZone的供应商。2016财年,AutoZone应付账款超过40亿美元,该数值甚至超过了存货。也就是说,AutoZone所有存货都是“赊购”的。这足以证明AutoZone强大的渠道话语权。在2019财年,Autozone直接进口了大约14%的采购,剩下的从当地供应商直接购买他们的产品或其产品的零部件。随着AutoZone线下门店数量的增加,对商品集中化采购与上游供货商的议价能力会更强,未来的毛利水平也有一定的上浮空间。相比而言,国内汽配维修店的规模优势不明显,采购成本较高,向零部件生产商赊购更是遥不可及。3.目标公司研究:3.1途虎养车公司介绍途虎养车于2011年在上海创立,主营轮胎、机油、汽车保养、汽车美容、车品等,提供“线上预约+线下安装”的养车方式。在汽车后市场的电商平台中,途虎汽车被外界认为是目前最为专业的平台之一,而且有腾讯投资加持。官网显示,目前途虎养车在全国拥有13000多家合作安装门店和超过1000家工场店,覆盖405个城市。市场份额:途虎养车多项指标均超过竞争对手之和,2017年上半年月活持续增长,占市场份额接近50%,这预示着车后市场的寡头游戏已经提前到来。(1)服务类型途虎养车作为汽车后市场的电商服务平台,平台的服务覆盖了为消费者提供专业的汽车保养建议,零配件匹配供应,到产品仓储、物流、配送,到终端提供检测、安装等流程,涉及到的环节、厂商、经销商和服务企业的数量非常之多。在这方面,途虎养车也做到了业内领先。途虎养车主要提供保养、美容、易损易耗件,为用户提供线上预约+线下安装的一站式养车服务。途虎养车用互联网方式可以把服务标准化设计,在用户端方面,输入车型即可知道保养价格,各项服务收费标准模块化,车主下单后系统会将其引至最近的合作门店进行养护,而养护所需的配件和物料,车主可以选择在途虎养车的商城中选购,途虎在线下建有仓储配送设施,可很快为车主将配件和物料送到。用户提交到途虎各渠道的服务需求,不管是车前还是车后,都会被途虎分配到各个线下门店中去。在途虎线上部分购买了配件的用户,也会被引导到线下合作门店进行安装。(2)业务模式途虎的商业模式概况为“线上商城平台+线下门店服务”运营模式,线上即电商平台,线下包括合作门店和工场店。具体为:i)上游整合供应厂商资源,通过大规模集中采购模式,去掉中间环节,降低采购成本。ii)线上通过搭建PC商城和APP平台,建立线上综合交易平台,直达用户,实现线上交易、线下服务。iii)下游通过地推团队整合线下服务门店,对线下门店进行IT化改造,为终端用户提供标准化服务。iv)自建高效率的仓储物流和配送体系,为终端用户提供快捷、高效的服务,提高客户体验和客户粘性。从线上流量来看,途虎养车的活跃用户数呈增长趋势。据易观千帆数据,2019年前三个月,途虎养车的活跃用户数分别是423.03万、358.35万、491.32万;启动次数分别为3632.03万次、2264.68万次、4276.03万次。(3)盈利来源目前的盈利来源包括:轮胎、机油、其他配件等产品销售毛利,维修、养护、美容等服务收入等。将来还会有基于大数据的信息服务、金融服务,针对B端客户的导流费、针对品牌商的广告费、增值服务等盈利来源。通过线上网站、移动端APP及天猫等合作平台渠道展示并销售丰富品类产品,同时推广产品说明和养车常识,提供会员交流平台,协助产品订购过程,管理用户信息和需求;通过线上电话中心提供专业养车咨询,完成产品订购,进行定制回访和定期提醒;同时通过线下的仓储和物流做到全面覆盖和及时配送;最后在线下店面完成产品接收,由线下店提供安装、保养等服务,完成服务后,车主可以在移动端途虎APP进行直接支付,也可以通过途虎安装在门店的POS机刷卡完成交易。随着公司稳定经营和持续扩张,以客户为中心的品牌服务已日趋成熟。在B2C电商平台导流,O2O服务平台建立服务标准,B2B电商平台提供货源的前提下,途虎正在搭建以从线上到线下的加盟服务网络,从而发展半直营加盟店,开发自有品牌,提升利润空间,多维度获取利润。(4)产业链上下游产业链上游,除了建立自有品牌汽配龙之外,途虎还与包括德国马牌、美国固铂轮胎、邓禄普轮胎、3M、胜牌机油、博世、瓦尔塔VARTA、大陆马牌旗下的SUV专用轮胎将军轮胎等国际大牌达成紧密战略合作,并拿下中国的在线销售授权。在线下仓储物流布局上,途虎已经布局了25个仓储物流中心,及覆盖405个城市的超13000家服务门店。依靠强大的先发优势、线上精细化运营与线下深耕能力,途虎养车2016年销售额突破22亿,自有平台销售占比近90%;其中轮胎单月最高销售额2.3亿。可以说,在现有的起点上,途虎已经找到了发挥“互联网指数级复利效应”的钥匙,正在用自己的发展轨迹验证互联网巨头“强者愈强”的复利式增长路径。可以预见,途虎养车在中国的汽车后市场取得的寡头地位将会继续保持,甩开其他竞争者的差距也将会越来越大。3.2.2竞争优势1.服务网络的覆盖目前可查的途虎13000多家合作门店,加上近千家工场店,相比于其他的公司几乎是碾压的优势。供应链和网络覆盖相辅相成,即便打同样的折扣,途虎养车可能是平价,对于其他竞争企业就是亏损,消耗公司的资本。2.抓住互联网的红利,发挥自身优势开展线上+线下的创新服务途虎养车以自营B2C的模式建立品牌路径,以单品类轮胎切入,基于线上下单、线下安装的模式,通过打通和缩短供应链,以正品直供建立了其在用户之间的口碑,进而形成了良好的品牌。去年5月份,途虎养车与人民网联合成立汽车后市场诚信服务联盟,目前联盟成员囊括了德国马牌、普利司通、固特异、埃克森美孚、嘉实多等56家汽车后市场品牌,为消费者提供正品保障,为解决汽车养护行业消费者的信任度问题提供了良好的方案。3.专注打造正品产品链,提供标准化优质服务自成立之初,途虎养车就秉承着“正品自营”的理念,得益于对这一理念的坚持,途虎在轮胎品类上加速与全球知名汽车品牌深入合作,先后与包括德国马牌、美国固铂轮胎、米其林轮胎、邓禄普轮胎、万力轮胎在内的众多顶级轮胎品牌建立了紧密的合作关系。在途虎养车的平台上,几乎能看到全球所有的知名轮胎厂商的身影。在完善的产品供应网络后,途虎养车还建立了闭合式的管理和服务系统,自建仓储库等方式,保障轮胎品质。然而,在市场形成竞争优势,途虎养车不仅仅需要完善的物流体系,同时也需要更标准化的服务完成商品的交付。因此途虎不仅自建供应链和仓储,同时为了提升商品实际交付过程中的用户体验,还建立了一整套的服务标准,并定时对门店进行培训。途虎养车发布了服务标准化评价体系,其中包括技术施工标准化、服务流程标准化、管理运营标准化,以及线下的监督与反馈流程。伴随着汽车后市场越来越高的进入门槛,资本、用户及市场均逐渐朝着健康性发展,途虎养车的成熟模式为其自身建立了竞争壁垒,使其成为了汽车后市场不可替代的领先者。3.3.3财务数据(1)融资情况国内领先的汽车养护服务品牌途虎养车宣布完成由腾讯、凯雷、红杉等知名投资方领投的4.5亿美元E轮融资,建银国际、中金启元以及老股东愉悦资本、远翼资本、启明创投、高盛、中金甲子、汇勤资本等共同参与跟投。据途虎养车介绍,本轮融资将主要用于提升用户体验、加快技术服务流程标准化和专业化、强化可溯源的正品供应流程、深化全国服务体系战略体系布局等方面,寻求构建新型智慧化的养护服务生态。(2)销售情况2015年,途虎养车的销售额已达10亿元,业务覆盖400多个城市,合作门店数1万个以上,轮胎的月销售额最高,为1.8亿元以上,而保养订单也高达3000个/日,月增长率20%以上。2016年上半年,途虎养车用户也覆盖了8%的私家车主,下半年这一比率仍不断上升,注册用户1200万个,2016年公司的营收实现22亿元的突破,2017年销售额更是达到了32亿元,同比增长了45.45%,几乎拿下了汽车后市场的半壁江山。一年时间,途虎养车的销售额翻了一番。这对于那些依赖融资而生的汽车后市场企业来说,显然是有着天壤之别的。途虎养车已经形成了营收良好的发展趋势,且资本实力雄厚。据驾享兄发现,近些年,途虎养车与德国马牌、美国胜牌、3M、固铂轮胎、海湾、邓禄普、辉门多家国际品牌商合作,成为车后市场最被看好的企业之一。根据易观数据显示,2017年12月,途虎养车电商业务月活用户数量达到347.9万人,月活量占据整个汽车后市场电商的53%,线上汽车养护业务有近70%的市场,注册用户覆盖中国超13%的车主,日均访客超过130万,成为车后服务领域唯一活跃用户规模达到百万量级的企业。

1.1 什么是C语言?
C语言是一门通用计算机编程语言,C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
关于C
C 语言是为了编写 UNIX 操作系统而被发明的。
C 语言是以 B 语言为基础的,B 语言大概是在 1970 年被引进的。
C 语言标准是于 1988 年由美国国家标准协会(ANSI,全称 American National Standard Institute)制定的。
截至 1973 年,UNIX 操作系统完全使用 C 语言编写。
目前,C 语言是最广泛使用的系统程序设计语言。
大多数先进的软件都是使用 C 语言实现的。
当今最流行的 Linux 操作系统和 RBDMS MySQL 都是使用 C 语言编写的。
1.2 C语言能做什么?
操作系统开发
软件开发
嵌入式开发
语言编译器
1.3 C语言有什么优点?
可移植性:C语言是高度可移植的,你在不改动或者只做很小改动的情况下,就可以把C语言的程序运行在不同平台;
C语言很小:C语言完全基于变量,宏命令,函数和架构,整体非常小,因此C语言可以嵌入几乎现代所有微型处理器中,从冰箱到闹钟;
学会C学会一切:几乎所有编程语言都由C语言实现,或者有着和C语言一样相似的语法和逻辑规则,因此,学会C语言能使你很快学会其他语言。
1.4 C语言有什么缺点?
运行时间:C语言没有运行时间检查机制;
面向过程:C语言不支持面向对象编程,这就是为什么创造C++;
不安全:指针是C语言的一大特色,可以说是C语言优于其它高级语言的一个重要原因,但也就是因为它有指针,可以直接进行靠近硬件的操作,所以带来很多不安全的因素。
记住:语言终究只是工具,算法才是核心,思路才是灵魂。
2.1 C 程序主要构成
预处理器指令
函数
变量
语句 & 表达式
注释
2.2 C 程序编写流程
编辑
预编译
编译
汇编
链接
运行
2.3 C语言结束符
C程序语句的结束是通过分号‘;’实现的,它表明一个逻辑实体的结束。
2.4 C语言注释
C语言的注释是以/*开始,以*/终止的。单行的注释,也可以使用双斜杠‘//’表示。
您不能在注释内嵌套注释,注释也不能出现在字符串或字符值中。
2.5 C语言标识符
C 标识符是用来标识变量、函数,或任何其他用户自定义项目的名称。一个标识符以字母A-Z或a-z或下划线_开始,后跟零个或多个字母、下划线和数字(0-9)。
C 标识符内不允许出现标点字符,比如 @、$ 和 %。C 是区分大小写的编程语言。
2.6 C语言关键字
下列C中的保留字不能作为常量名、变量名或其他标识符名称。
auto
else
long
switch
case
extern
return
union
char
float
short
unsigned
const
for
signed
void
continue
goto
sizeof
volatile
default
if
static
while
do
int
struct
_Packed
double
define
typedef
2.7 C语言空格
只包含空格的行,被称为空白行,可能带有注释,C 编译器会完全忽略它。
在 C 中,空格用于描述空白符、制表符、换行符和注释。空格分隔语句的各个部分,让编译器能识别语句中的某个元素(比如int)在哪里结束,下一个元素在哪里开始。
3.1 数据类型
C语言中的类型包含以下几种:
序号
类型
描述
1
基本类型
它们是算术类型,包括两种类型:整数类型和浮点数类型
2
枚举类型
它们也是算术类型,被用来定义在程序中只能赋予其一定的散列整数值的变量
3
void类型
类型说明符void表明没有可用的值
4
派生类型
它们包括:指针类型、数组类型、结构类型、共用体类型和函数类型
数组类型和结构类型统称为聚合类型;函数的类型指的是函数返回值的类型。
为了得到某个类型或某个变量在特定平台上的准确大小,可以使用sizeof运算符。
整数类型
类型
存储大小
取值范围
char
1 byte
-128 ~ 127或0 ~ 255
unsigned char
1 byte
0 ~ 255
signed char
1 byte
-128 ~ 127
int
2或4 bytes
-32,768 ~ 32,767或-2,147,483,648 ~ 2,147,483,647
unsigned int
2或4 bytes
0 ~ 65,535或0 ~ 4,292,967,295
short
2 bytes
-32,768 ~ 32,767
unsigned short
2 bytes
0 ~ 65,535
long
4 bytes
-2,147,483,648 ~ 2,147,483,647
unsigned long
4 bytes
0 ~ 4,294,967,295
浮点类型
类型
存储大小
值范围
精度
float
4 bytes
1.2E-38 ~ 3.4E+38
6位小数
double
8 bytes
2.3E-308d ~ 1.7E+308
15位小数
long double
10 bytes
3.4E-4932 ~ 1.1E+4932
19位小数
void类型:常用于下面三种情况
序号
类型
描述
1
函数返回为空
C中有各种函数不返回值,或者说它们返回空。无返回值的函数的返回类型为空
2
函数参数为空
C中有各种函数不接受参数;不带参数的函数可以接受一个void
3
指针指向void
类型为void *的指针代表对象的地址,而不是类型。
转义字符
转义序列
含义
\\
\字符
\'
'字符
\"
"字符
\?
?字符
\a
报警警报铃声
\b
退格键
\f
换页符
\n
换行符
\r
回车
\t
水平制表符
\v
垂直制表符
\ooo
一到三位的八进制数
\xhh...
一个或多个数字的十六进制数
3.2 C变量
C语言中每个变量都有特定的类型,类型决定了变量存储的大小和布局。变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。变量基本类型与数据类型相对应。
变量可以是如下类型:char、int、float、double、void、枚举、指针、数组、结构、共用体等。
不带初始化的变量定义:带有静态存储持续时间的变量会被隐式初始化为NULL(所有字节的值都是0),其他所有变量的初始值是未定义的。
左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式;左值可以出现在赋值号的左边或右边。
右值(rvalue):指的是存储在内存中某些地址的数值;右值是不能对其进行赋值的表达式,也就是说右值只能出现在赋值号的右边。
3.3 C常量
3.3.1 什么是常量?
常量是固定值,在定义之后就不能进行修改(程序执行期间不会发生改变)。这种固定的值,又叫做字面量。常量就像常规的变量,只不过常量的值在定以后不能进行修改。
常量也可以是任意的基本数据类型,比如:整数常量、浮点常量、字符常量、字符串常量,或枚举常量。
整数常量前面可以添加前缀:0x或0X表示十六进制,0表示八进制,不带前缀表示默认十进制;也可以带U或L后缀:U表示无符号整数,L表示长整数。U或L可以大写,也可以小写,顺序任意。
浮点常量由整数部分、小数点、小数部分和指数部分组成。指数是用e或E来表示的。
字符常量是括在单引号''中的,可以是普通字符(如'x')、转义字符(如‘\t’,键转义字符表),或一个通用字符(如‘\u02c0’)。
字符串常量是括在双引号""中的, 可以是普通的字符、转义序列或通用字符。可以用空格做分隔符,表示一个很长的字符串常量。
3.3.2 常量的定义
在C中,有两种简单的方式定义常量:
使用#define预处理器;
使用const关键字;
使用#define预处理器定义常量的形式为:
#define identifier value
也可以使用const前缀声明指定类型的常量:
const type variable = value;
通常,我们使用大写字母来表示常量,这是一个很好的编程习惯。
3.4 C存储类
存储类定义了C程序中变量/函数的可见性范围和生命周期,这些存储类说明符放置在所修饰的类型之前。常见的C存储类说明符如下:
auto
register
static
extern
3.4.1 auto存储类
auto存储类是所有局部变量默认的存储类,且auto只能用在函数内,即auto只能修饰局部变量。
3.4.2 register存储类
register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个词),且不能对它应用一元的 '&' 运算符(因为它没有内存位置)。
寄存器只用于需要快速访问的变量,比如计数器。还应注意的是,定义 'register' 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。
3.4.3 static存储类
static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。
static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。
在 C 编程中,当 static 用在类数据成员上时,会导致仅有一个该成员的副本被类的所有对象共享。
3.4.4 extern存储类
extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 'extern' 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。
当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数。
extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候。
4.1 数组
数组是可以存储一个固定大小的相同类型元素的顺序集合。所有的数组都是由连续的内存位置组成。在C中声明一个数组,需要指定元素的类型的元素的数量:
type arrayName[ arraySize ];
arraySize必须是一个大于等于0的整数常量,type可以是任意有效的C数据类型。
在C中,您可以逐个初始化数组,也可以使用一个大括号{}的初始化语句。
多维数组
C支持多维数组,多维数组最简单的形式是二维数组。
type name[size1][size2]...[sizeN];
传递数组给函数
传递数组作为函数的参数,可使用如下三种方式来实现:
# 方式 1
void myFunction(int *param)
{
...
}
# 方式 2
void myFunction(int param[10])
{
...
}
# 方式 3
void myFunction(int param[])
{
...
}
函数返回数组
C语言不允许返回一个完整的数组,但是可以通过不带索引的数组名来返回一个指向数组的指针:
# 返回type类型的数组指针
type * myFunction()
{
...
}
注意:C不支持函数返回局部变量的地址,除非局部变量定义为static。
指向数组的指针
数组名是一个指向数组中第一个元素的常量指针。
# array是一个指向array[0]的指针,值为&array[0]
type array[N];
# p是一个指向type数据类型的指针
type *p;
# 给p赋值,让p指向array数组的第一个元素
p = array;
# 使用指针p来访问数组:
*p;
*p++;
*(p+3);
4.2 指针
每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问其地址的方法,它表示了内存中的一个地址。
指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址。
type *var-name;
所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。
NULL指针
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
C指针算术运算
C指针是一个用数值表示的地址,因此,可以对指针执行算术运算:++、--、+、-、==、<、>。
C指针数组
声明ptr为一个数组,每一个ptr数组的元素都是一个指向int类型值的指针。
int *ptr[MAX];
C数组指针
声明ptr为一个指针,指向一个元素个数为MAX个int类型的数组的指针。
int (*ptr)[MAX];
C指向指针的指针
指向指针的指针是一种两级间接寻址的形式,是一个指针链。当然也可以定义多级间接寻址的形式。定义指向指针的指针:
int var;
int *ptr1 = &var;
int **ptr2 = &ptr1;
C传递指针给函数
当通过指针的方式传递给函数时,我们可以在函数内部修改外部变量的值。
C从函数返回指针
C语言可以通过返回指针的方式来返回多个值,返回静态变量,返回动态分配的内存。但是要注意:C不支持在函数外返回局部变量的地址,除非定义局部变量为static变量。
4.3 字符串
在C语言中,字符串实际上是使用null字符('\0')终止的一维字符数组。C中有大量操作字符串的函数:
序号
函数 & 目的
1
strcpy(s1, s2); 复制字符串s2到字符串s1
2
strcat(s1, s2); 连接字符串s2到字符串s1的末尾
3
strlen(s1); 返回字符串s1的长度
4
strcmp(s1, s2); 如果s1和s2是相同的,则返回0;如果s1 < s2则返回小于0;如果s1 > s2则返回大于0
5
strchr(s1, ch); 返回一个指针,指向字符串s1中字符ch的第一次出现的位置。
6
strstr(s1, s2); 返回一个指针,指向字符串s1中字符串s2的第一次出现的位置。
4.4 结构体
C数组允许定义可存储相同类型数据的变量;结构是C中另一种用户自定义的可用数据类型,它可以存储不同类型的数据项。
结构体定义
struct [struct tag]
{
member definition;
member definition;
...
member definition;
}[one or more structure variable];
struct tag是可选的,每个member definition是标准的变量定义;在结构体定义的末尾,最后一个分号之前,可以指定一个或多个结构体变量,也是可选的。
访问结构成员
为了访问结构的成员,我们使用成员访问运算符(.),如果是指针的话,则使用(->)。
结构作为参数
可以把结构体作为参数,传参方式与其他基本类型的变量或指针类似,都是值传递方式。
4.5 共用体
共用体是一种特殊的数据结构,允许你在相同的内存位置存储不同的数据类型。你可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带值。
union [union tag]
{
member definition;
member definition;
...
member definition;
}[one or more union variable];
union tag是可选的,每个member definition是标准的变量定义;在共用体定义的末尾,最后一个分号之前,你可以定义一个或多个共用体变量,也是可选的。
共用体的访问方式与结构体一样,只是要注意任何时候只能有一个成员带值
4.6 位域
有些信息在存储时,并不需要占用一个完整字节,而只需要占几个或一个二进制位。为了节省存储空间,并使处理简便,C语言提供了一种数据结构,称为“位域”或“位段”。
所谓“位域”就是把一个字节中的二进制位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
struct 位域结构名
{
类型说明符 位域名1:位域长度;
类型说明符 位域名2:位域长度;
...
类型说明符 位域名n:位域长度;
}
位域的使用与结构体和共用体类似。但应注意以下几点:
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一个位域时,应从下一个单元存放该位域;也可以有意使某位域从下一单元开始,比如:
struct bs{
unsigned a:4;
unsigned
:4;
unsigned b:4;
unsigned c:4;
}
由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,另外一些编译器可能会把大于一个域的部分存储在下一个字中。
位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的。
4.7 typedef
typedef关键字可以用来为类型取一个新名字。按照惯例,定义新名字时会使用大写字母,以便提醒用户类型名称是一个象征性的缩写。如下:
typedef unsigned char BYTE
你也可以使用typedef来为用户自定义的数据类型(结构体、枚举、共用体、位域结构)取一个新名字。
typedef与define
typedef仅限于类型定义符号名称,#define不仅可以为类型定义别名,也能为数值定义别名(1定义为ONE);
typedef是由编译器执行解释的,#define语句是预编译器进行扩展处理的。
4.8 强制类型转换
强制类型转换是把变量从一种类型转换为另一种数据类型。使用强制类型转换运算符显示的转换一种类型:
(type_name) expression
类型的转换经常是隐式的,由编译器自动执行的。但是,作为一个有追求的程序员,建议都是用显示的类型转换,这也是一个良好的编程习惯。
整数提升:整数提升是指把小于int或unsigned int的整数类型转换为int或unsigned int的过程。
image
常用的算是转换不适用于赋值运算符、逻辑运算符&&和
。比如:
int i = 17;
char c = 'c';
float sum = i + c;
由于最后的值是float类型,所以编译器会先把i和c转换为浮点型,然后将其相加后赋值给sum。
任何一种编程中,作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量:
在函数或块内部的局部变量
在所有函数外部的全局变量
在形式参数的函数参数定义中
5.1 局部变量
在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。
5.2 全局变量
全局变量是定义在函数外部,通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。全局变量可以被任何函数访问。也就是说,全局变量在声明后整个程序中都是可用的。
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。
5.3 形式参数
函数的参数,形式参数,被当作该函数内的局部变量,它们会优先覆盖全局变量。
5.3 初始化局部变量和全局变量
当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动对其初始化。
数据类型
初始化默认值
int
0
char
''
float
0
double
0
pointer
NULL
正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果,因为未初始化的变量会导致一些在内存位置中已经可用的垃圾值。
注意:变量的作用域可以通过前面讲解的static和extern关键字修改。
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C语言提供了如下类型的运算符:
算符运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
杂项运算符
6.1 算术运算符
假设A为10,B为20。
运算符
描述
实例
+
把两个操作数相加
A + B将得到30
-
从第一个操作数中减去第二个操作数
A - B将得到-10
*
把两个操作数相乘
A * B将得到200
/
分子除以分母
B / A将得到2
%
取模运算符,整除后的余数
B % A将得到0
++
自增运算符,整数值增加1
A++将得到11
--
自减运算符,整数值减少1
A--将得到9
a++与++a:a++是先操作后再+1,++a是先+1后再操作。
6.2 关系运算符
假设A值为10,B值为20。
运算符
描述
实例
==
检查两个操作数的值是否相等,如果相等则条件为真
(A == B)为假
!=
检查两个操作数的值是否相等,如果不相等则条件为真
(A != B)为真
>
检查左操作数的值是否大于右操作数的值,如果是则条件为真
(A > B)为假
<
检查左操作数的值是否小于右操作数的值,如果是则条件为真
(A < B)为真
>=
检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真
(A >= B)为假
<=
检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真
(A <= B)为真
6.3 逻辑运算符
假设A的值为1,B的值为0。
运算符
描述
实例
&&
逻辑与运算符:如果两个操作数都非0,则条件为真
(A && B)为假
逻辑或运算符:如果两个操作数中有任意一个非0,则条件为真
(A
B)为真
!
逻辑非运算符:用来逆转操作数的逻辑状态,如果条件为真则逻辑非运算符将使其为假
!( A && B)为真
6.4 位运算符
假设A值为60,B值为13,则:
运算符
描述
实例
&
按位与操作,按二进制位进行‘与’运算。运算规则见下面真值表
(A & B)将得到12
按位或运算符,按二进制位进行‘或’运算。运算规则见下面真值表
(A
B)将得到61
^
按位异或运算符,按二进制位进行‘异或’运算。运算规则见下面真值表
(A ^ B)将得到48
~
按位取反运算符,按二进制位进行‘取反’运算
(~A)将得到带符号的-61
<<
二进制左移运算符,左操作数的值向左移动右操作数指定的位数(左边的二进制位丢弃,右边补0)
A << 2将得到240
>>
二进制右移运算符,左操作数的值向右移动右操作数指定的位数(正数左补0,负数左补1,右边位丢弃)
A >> 2将得到15
&、|和^位操作真值表如下:
p
q
p & q
p
q
p ^ q
0
0
0
0
0
0
1
0
1
1
1
1
1
1
0
1
0
0
1
1
6.5 赋值运算符
运算符
描述
实例
=
简单的赋值运算符,把右边操作数的值赋给左边操作数
C = A + B将把A + B的值赋给C
+=
加且赋值运算符,把左边操作数加上右边操作数的结果赋值给左边操作数
C += A相当于C = C + A
-=
减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数
C -= A相当于C = C - A
*=
乘且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数
C /= A相当于C = C*A
/=
除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数
C /= A相当于C = C/A
%=
求模且赋值运算符,把左边操作数对右边操作数取模的结果赋值给左边操作数
C %= A相当于C = C%A
<<=
左移且赋值运算符
C <<= 2等同于C = C<<2
>>=
右移且赋值运算符
C >>= 2等同于C = C>>2
&=
按位与且赋值运算符
C &= 2等同于C = C&2
=
按位或且赋值运算符
C
= 2等同于C = C
2
^=
按位异或且赋值运算符
C ^= 2等同于C = C^2
6.6 杂项运算符
运算符
描述
实例
sizeof()
返回变量占用内存的大小
sizeof(a)将返回变量a占用的内存大小
&
返回变量的地址
&a将给出变量的实际地址
*
指向一个变量
*a将指向一个变量
?:
条件表达式
如果条件为真?则值为X : 否则值为Y
6.7 运算符优先级
运算符的优先级确定表达式中项的组合优先顺序,这会影响到一个表达式如何计算。较高优先级的运算符会被优先计算。
类别
运算符
结合性
后缀
() [] -> . ++ --
从左到右
一元
+ - ! ~ ++ -- (type) * & sizeof
从右到左
乘除
* / %
从左到右
加减
+ -
从左到右
移位
<< >>
从左到右
关系
< <= > >=
从左到右
相等
== !=
从左到右
位与AND
&
从左到右
位异或XOR
^
从左到右
位或OR
从左到右
逻辑与AND
&&
从左到右
逻辑或OR
从左到右
条件
?:
从右到左
赋值
= += -= *= /= %= >>= <<= &= ^=
=
从右到左
逗号
,
从左到右
7.1 C判断
C语言把任何非零和非空的值假定为true,把零或null假定为false。
7.1.1 if语句
一个if语句由一个布尔表达式后跟一个或多个语句组成。
if(boolean_expression)
{
/* 如果布尔表达式为真将执行的语句 */
}
7.1.2 if...else语句
一个if语句后可跟一个可选的else语句,else语句在布尔表达式为假时执行。
if(boolean_expression)
{
/* 如果布尔表达式为真将执行的语句 */
}
else
{
/* 如果布尔表达式为假将执行的语句 */
}
注意:条件运算符 ? : 可以用来替代if...else语句。
7.1.3 if...else if...else
一个if语句后可跟一个可选的else if ... else语句,这可用于测试多种条件。
if(boolean_expression 1)
{
/* 当布尔表达式1为真时执行 */
}
else if(boolean_expression 2)
{
/* 当布尔表达式2为真时执行 */
}
else if(boolean_expression 3)
{
/* 当布尔表达式3为真时执行 */
}
else
{
/* 当上面条件都不为真时执行 */
}
7.1.4 嵌套if语句
可以在一个if或else if语句内使用另一个if或else if语句。
if(boolean_expression 1)
{
/* 当布尔表达式1为真时执行 */
if(boolean_expression 2)
{
/* 当布尔表达式2为真时执行 */
}
else
{
/* 当布尔表达式2为假时执行 */
}
}
else
{
/* 当布尔表达式1为假时执行 */
}
7.1.5 switch语句
一个switch语句允许测试一个变量等于多个值时的情况。每个值称为一个case,且被测试的变量会对每个switch case进行检查。
switch(expression){
case constant-expression :
statement(s);
break; /* 可选的 */
case constant-expression :
statement(s);
break; /* 可选的 */
/* 你可以有任意数量的case语句 */
default : /* 可选的 */
statement(s);
break; /* 可选的 */
}
switch语句遵循如下规则:
switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。
在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。
case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量或字面量。
当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。
当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
7.1.6 嵌套switch语句
可以把一个 switch 作为一个外部 switch 的语句序列的一部分,即可以在一个 switch 语句内使用另一个 switch 语句。即使内部和外部 switch 的 case 常量包含共同的值,也没有矛盾。
switch(ch1) {
case 'A':
printf("这个 A 是外部 switch 的一部分" );
switch(ch2) {
case 'A':
printf("这个 A 是内部 switch 的一部分" );
break;
case 'B': /* 内部 B case 代码 */
}
break;
case 'B': /* 外部 B case 代码 */
}
当然,if语句与switch之间也是可以互相嵌套使用的,只是咱们编程的时候注意嵌套层数最好不好超过3层,否则不利于代码的理解。
7.2 C循环
7.2.1 while循环
当给定条件为真时,重复语句或语句组,它会在执行循环主体之前测试条件
while(condition)
{
statement(s);
}
7.2.2 for循环
多次执行一个语句序列,简化管理循环变量的代码。
for (init; condition; increment)
{
statement(s);
}
下面是for循环的控制流程:
init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。
7.2.3 do...while循环
除了它是在循环主体结尾测试条件外;其他与while语句类似,但do...while循环至少执行一次循环。
do
{
statement(s);
}while(condition);
7.2.4 嵌套循环
可以在while、for或do...while循环内使用一个或多个循环。
// for循环嵌套
for (init; condition; increment)
{
for(init; condition; increment)
{
statement(s);
}
statements(s);
}
// while循环嵌套
while(condition)
{
while(condition)
{
statement(s);
}
statement(s);
}
// do...while循环嵌套
do
{
statement(s);
do
{
statement(s);
}while(condition);
}while(condition);
7.2.5 循环控制语句
break语句:终止loop或switch语句,程序流将继续执行紧接着loop或switch的下一条语句;若是嵌套循环,break语句会停止最内层的循环。
continue语句:引起循环跳过主体的剩余部分,立即重新开始测试条件。
goto语句:将控制转移到被标记的语句,但不建议在程序中使用goto语句。
注意:在任何编程语言中,都不建议使用 goto 语句。因为它使得程序的控制流难以跟踪,使程序难以理解和难以修改。任何使用 goto 语句的程序可以改写成不需要使用 goto 语句的写法。
7.2.6 无限循环
如果条件永远为真,则循环将变成无限循环。一般情况下,使用for(;;)结构来表示一个无限循环。
可以按Ctrl + C键终止一个无限循环。
8.1 函数定义
C语言定义函数的一般形式为:
return_type function_name(parameter_list)
{
body of the functioin
}
在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:
返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
函数主体:函数主体包含一组定义函数执行任务的语句。
8.2 函数声明
函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。函数声明包括以下几个部分:
return_type function_name(parameter_list)
8.3 函数调用
当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。
8.3 函数参数
如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。
形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。当调用函数时,有两种向函数传递参数的方式:
调用类型
描述
传值调用
该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
引用调用
该方法把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
默认情况下,C使用传值调用来传递参数(函数内的代码不能改变用于调用函数的实际参数)。
8.4 递归
递归是以自相似的方式重复项目的处理过程。同样地,在编程语言中,在函数内部调用函数自身,称为递归调用。
在使用递归时,程序员需要注意定义一个从函数退出的条件,否则会进入无限循环。递归函数在解决许多数学问题上起了至关重要的作用,比如计算一个数的阶乘、生成斐波那契数列,等等。
数的阶乘:
int factorial(unsigned int i)
{
if(i <= 1)
return 1;
return i*factorial(i - 1);
}
斐波那契数列:
int fibonaci(int i)
{
if(i == 0)
return 0;
if(i == 1)
return 1;
return fibonaci(i - 1) + fibonaci(i - 2);
}
一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节。C语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件。
9.1 打开文件
fopen()函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FILE 包含了所有用来控制流的必要的信息:
FILE *fopen(const char *filename, const char *mode);
filename是字符串,用来命名文件,访问模式mode的值可以是下列值的一个:
模式
描述
r
打开一个已有的文本文件,允许读取文件
w
打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容
a
打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容
r+
打开一个文本文件,允许读写文件
w+
打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件
a+
打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式
9.2 关闭文件
当使用完文件时,需要调用fclose()关闭对应的文件,否则会造成资源浪费:
int fclose(FILE *fp);
如果成功关闭文件,fclose()函数返回零,如果关闭文件时发生错误,函数返回EOF。这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。
9.3 写入文件
int fputc(int c, FILE *fp);
int fputs(const char *s, FILE *fp);
int fprintf(FILE *fp, const char *format, ...);
fputc()把参数c的字符值写入到fp所指向的输出流中,写入成功返回写入的字符,发生错误则返回EOF;使用fputs()可以把以null结尾字符串s写入fp指向的输出流中,写入成功返回一个非负值,发生错误则返回EOF;也可以使用fprintf()函数来格式化输出字符串到fp指向的输出流中。
9.4 读取文件
int fgetc(FILE *fp);
char *fgets(char *buf, int n, FILE *fp);
int fscanf(FILE *fp, const char *format, ...);
fgetc()函数从fp所指向的输入文本中读取一个字符,返回读取的字符,错误则返回EOF;fgets()从fp所指向的输入流中读取n-1个字符,将读取到的字符串复制到缓冲区buf,并在最后追加一个null字符来终止字符串;也可使用fscanf()函数从文件格式化读取要获取的值。
9.5 二进制I/O函数
下面两个函数用于存储块的读写,常用于数组或结构体:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);
10.1 C预处理器
C预处理不是编译器的组成部分,但它是编译过程中的一个步骤。
所有的预处理器命令都是以井号(#)开头,它必须是第一个非空字符,为了增加可读性,预处理器指令应从第一列开始。常见的预处理器指令如下:
指令
描述
#define
宏定义
#include
包含一个源代码文件
#undef
取消已定义的宏
#ifdef
如果宏已经定义,则返回真
#ifndef
如果宏没有定义,则返回真
#if
如果给定条件为真,则编译下面代码
#else
#if的替代方案
#elif
如果前面的#if给定条件不为真,elif后面为真则编译下面的代码
#endif
结束一个#if ... #else条件编译块
#error
当遇到标准错误时,输出错误信息
#pragma
使用标准化方法,向编译器发布特殊的命令到编译器中
ANSI C定义了许多宏,在编译中你可以使用这些宏,但不能直接修改这些预定义的宏:

描述
_DATE_
当前日期,一个以“MM DD YYYY”格式表示的字符常量
_TIME_
当前时间,一个以“HH:MM:SS”格式表示的字符常量
_FILE_
这会包含当前文件名,一个字符串常量
_LINE_
这会包含当前行号,一个十进制常量
_STDC_
当编译器以ANSI标准编译时,则定义为1
一个宏通常写在一个单行上,但如果宏太长,单行容不下则可以使宏延续运算符(\)。
在宏定义中,当需要把一个宏的参数转换为字符串常量时,可以使用字符串常量化运算符(#)。
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
message_for(Carole, Debra)的结果是Carole and Debra: We love you!
宏定义内的标记粘贴运算符(##)会合并两个参数,它允许在宏定义中两个独立的标记被合并为一个标记。
#define tokenpaster(n) printf("token" #n " = %d\n", token##n)
int token32 = 40;
tokenpaster(32);
以上结果会打印:token32 = 40
预处理器defined运算符用在常量表达式中,用来确定一个标识符是否已经使用#define定义过,如果已定义则为真(非零),否则为假(零)。
#if !defined (MESSAGE)
#define MESSAGE "You wish!"
#endif
10.2 C头文件
头文件是扩展名为.h的文件,包含了C函数声明和宏定义,被多个源文件中引用共享。有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。
A simple practice in C或C++程序中,建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这个头文件。
如果一个头文件被引用两次,编译器会处理两次头文件的内容,这将产生错误。为了防止这种情况,标准的做法是把文件的整个内容放在条件编译语句中:
#ifndef HEAD_FILE
#define HAED_FILE
the entire header file file
#endif // HEAD_FILE
如上这种结构就是常说的包装器#ifndef。有时候需要从多个不同的头文件中根据条件选择一个引用到程序中,则可以通过一系列宏条件来实现:
#if SYSTEM_1
#include "system_1.h"
#elif SYSTEM_2
#include "system_2.h"
#elif SYSTEM_3
...
#endif
10.3 C错误处理
C 语言不提供对错误处理的直接支持,但是作为一种系统编程语言,它以返回值的形式允许您访问底层数据。在发生错误时,大多数的C或UNIX函数调用返回1或NULL,同时会设置一个错误代码errno,该错误代码是全局变量,表示在函数调用期间发生了错误。您可以在 <error.h>头文件中找到各种各样的错误代码。
所以,C程序员可以通过检查返回值,然后根据返回值决定采取哪种适当的动作。开发人员应该在程序初始化时,把errno设置为0,这是一种良好的编程习惯。0值表示程序中没有错误。
C语言提供了perror()和strerror()函数来显示与errno相关的文本消息:
perror()函数显示您传给它的字符串,后跟一个冒号、一个空格和当前errno值的文本表示形式。
strerror()函数返回一个指针,指针指向当前error值的文本表示形式。
10.5 C可变参数
有时候可能会碰到希望函数带有可变数量的参数,而不是预定义数量的参数。在C语言中,函数func()最后一个参数写成省略号(...),省略号之前的那个参数总是int,代表了要传递的可变参数的总个数:
int func(int, ...)
{
...
}
C语言还提供了stdarg.h实现了可变参数功能的函数和宏,具体操作步骤如下:
定义一个函数,最有一个参数为省略号,省略号前面的那个参数总是int,表示可变参数的个数;
在函数定义中创建一个va_list类型变量,该类型是在stdarg.h头文件中定义的;
使用int参数和va_start宏来初始化va_list变量为一个参数列表。宏va_start是在stdarg.h头文件定义的;
使用va_arg宏和va_list变量来访问参数列表中的每个项;
使用宏va_end来清理赋予va_list变量的内存。
下面函数实现计算数据平均值的功能:
double average(int num, ...)
{
int i;
va_list valist;
double sum = 0.0;
va_start(valist, num);
for(i = 0; i < num; i++)
sum += va_arg(valist, int);
va_end(valist);
return sum/num;
}
10.6 C命令行参数
执行程序时,可以从命令行传值给C程序。这些值被称为命令行参数,它们对程序很重要,特别是当您想从外部控制程序,而不是在代码内对这些值进行硬编码时,就显得尤为重要了。
命令行参数是使用main()函数参数来处理的,其中,argc是指传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数。
argv[0]存储程序的名称,argv[1]是一个指向第一个命令行参数的指针,*argv[n]是最后一个参数。如果没有提供任何参数,argc将为1,否则,如果传递了一个参数,argc 将被设置为2。
多个命令行参数之间用空格分隔,但是如果参数本身带有空格,那么传递参数的时候应把参数放置在双引号""或单引号''内部。
10.7 内存管理
C语言为内存的分配和管理提供了如下接口(在stdlib.h头文件中):
序号
函数和描述
1
void *calloc(int num, int size);该函数分配一个带有num个元素的数组,每个元素的大小为size字节
2
void free(void *address);该函数释放address所指向的address内存块
3
void *malloc(int num);该函数分配一个num字节的数组,并把它们进行初始
4
void *realloc(void *address, int newsize);该函数重新分配内存,把内存扩展到newsize大小

我要回帖

更多关于 三个数相加减的方法有哪些 的文章

 

随机推荐