您好,欢迎访问三七文档
当前位置:首页 > 金融/证券 > 投融资/租赁 > 北大裘宗燕《从问题到程序》第三章 变量、函数和控制结构
从问题到程序裘宗燕北京大学数学学院2005年第三章变量、函数和控制结构已讨论机制的局限性:•只能描述由基本数据出发的简单计算;•只能描述特定计算。我们希望:•描述更为复杂的计算过程•使程序有一定通用性,能解决一类问题,完成对不同数据的类似计算因此需要有更多的程序机制。3.1语句和复合结构语法:语句的形式必须符合语言要求。语义:形式合法的语句表达了某种含义(程序执行时的效果),称为语句的语义。语句是程序的基本单位。函数调用是一种“基本”语句。还有其他一些基本语句(下面要介绍)。为描述复杂的计算,语言提供一些组合简单语句的结构,实现对执行过程的控制。复合结构(复合语句)语法:一对花括号,其中可有0个或多个语句。语义:顺序执行其中的各个语句。空复合结构中没有语句,执行时立即结束。{}前面简单C程序的主要部分是个复合语句:intmain(){printf(Goodmorning!\n);return0;}3.2变量的概念、定义和使用在硬件里,数据存储概念是内存单元和地址,变量是它们在高级语言里的反映。变量:存储数据的命名对象。通过变量名可以使用存于变量中的数据。变量名是标识符。基本操作:赋值,取值。变量能保存值。给某变量赋一个值之后,每次使用它总得到这个值,直到下次赋值。在程序执行过程中,一个变量的值可以变化。变量有固定的类型,只能保存这个类型的值。整型变量(保存int值的变量),双精度变量(保存double值),字符变量等。变量定义:变量必须先定义后使用定义所需信息:变量名和类型。例子:intm;doublex;可以同时定义多个同类型的变量:intk,n,sum,count;longdoubley,z;•关键字不能用做变量名•提倡采用有意义名字复合结构中可以定义局部变量。•在内部使用•变量定义应出现在所有语句之前{变量定义序列语句序列}一个复合结构里不能定义多个同名的变量。复合结构的执行(修正的语义):先定义变量,而后顺序执行各语句。变量的取值与赋值取值:计算中遇到变量,取其值参与计算:x+sin(3.2*y)-pow(x,2)表达式里有变量,计算结果将依赖于变量值。printf(“%d\n”,n*2);赋值:用赋值运算符(=,赋值号)表示:x=5.0•左边是赋值目标,右边是提供值的表达式•赋值运算的主要效果是把表达式的值赋给左边变量赋值运算符优先级很低。例:x=2+3*y赋值语句:赋值表达式后加分号(语法)•是最基本的语句,完成程序里最重要的操作•程序中一般用赋值语句描述赋值动作•赋值表达式也可独立存在(后面讨论)例:重写由三边3、5、7求三角形面积的程序。计算中多次用半周长,定义变量保存这个值,可避免重复计算。#includestdio.h#includemath.hintmain(){doubles;s=(3.+5.+7.)/2.;printf(Area:%f\n,sqrt(s*(s-3.)*(s-5.)*(s-7.)));return0;}变量的最主要用途:保存计算的中间结果赋值运算符的值与结合性•赋值运算也有值,就是右边表达式的值。•赋值表达式的值通常不用。赋值表达式的值可以用。例(不提倡):y=(x=5)+8;人们有时用同一表达式为多个变量赋值。y=(z=(x=1.0));赋值运算符从右向左结合。上面语句可以简化(也称多重赋值):y=z=x=1.0;赋值与类型•被赋值变量有类型(由变量定义确定);•赋值号右边表达式的值有类型。规定:若表达式值与被赋值变量类型不同,该值先转换到变量类型的值,然后赋值。在前面程序例子里把赋值语句改写成:s=(3+5+7)/2;运行时发现程序的结果不对,为什么?请考虑:运算在哪个类型里进行变量初始化定义时指定初始值。可用数值或者数值表达式为类型合适的变量做初始化:doubles=(3+5+7)/2.0;longdoublex=4.5L,y=3.24L;初始化只能一次对一个变量做。赋值表达式有值,下面是合法语句:x=2.0;y=(x=3.0)+x;执行后y的值是什么?赋值与数学中的“等于”完全不同。例:x=x+1;“x=x+1”在数学里为矛盾。上语句则合法(常用)。这个问题没有回答,因为第二个语句不正确。C语言未规定加法对两个运算对象的求值顺序,“这种表达式的结果没有定义”。变量的名字变量类型35.70图3.1 变量的属性变量的值doublex1变量存储位置 地址:0x00002f30程序中的注释注释:为帮助人阅读/理解程序而写在程序里,起注解作用的说明性文字。注释对程序意义(执行)没有影响。(各种语言都允许写注释)形式:/*任何字符的序列*/程序里的注释相当于一个空格。程序中加入必要注释是一种好的编程习惯。对于复杂的大程序,注释的意义更大。简单计算程序#includestdio.h/*如用数学函数,要写#includemath.h*/intmain(){/*若干变量定义(及可能的初始化)*//*若干计算和赋值语句*//*若干输出语句*/return0;}这是C程序的基本形式,后面逐步扩充3.3函数定义(初步)函数可看作对C语言基本功能的扩充。函数是特定计算过程的抽象,有通用性,可按规定方式(参数个数/类型)对具体数据使用。例:标准函数sin,类型特征是:doublesin(double)标准函数有限,需求无限程序设计中有定义函数的需求例:求一些圆盘的面积,圆盘半径分别为:3.24、2.13、0.865、3.746、12.3364、8.421设圆周率用3.1416。可写出下面程序:#includestdio.hintmain(){printf(radius:%f,area:%f\n,3.24,3.24*3.24*3.1416);printf(radius:%f,area:%f\n,2.13,2.13*2.12*3.1415);……/*实际程序里不能有省略号*/}繁琐的东西很容易弄错,上面程序就有错。如果有以半径为参数计算圆盘面积的函数:doublec_area(double)程序就可简化。如第一个语句可写为:printf(radius:%f,area:%f\n,3.24,c_area(3.24));如有打印圆盘面积的函数pc_area,只需写:pc_area(3.24);pc_area(2.13);......函数能使程序变短,变得易写/易理解/易修改函数定义把一段计算定义成函数并给以命名。定义函数c_area的程序片段:doublec_area(doubler){returnr*r*3.1416;}定义后就可以通过名字调用,用在任何需要的地方。半径3.24高2.4的圆锥体积:2.4*c_area(3.24)/3.0外半径5.3,内半径3.07,高4.2的空心圆柱:(c_area(5.3)-c_area(3.07))*4.2#includestdio.h/*定义函数,重写程序*/doublec_area(doubler){returnr*r*3.1416;/*很容易修改圆周率近似值*/}intmain(){printf(Radius:%f,area:%f\n,3.24,c_area(3.24));printf(Radius:%f,area:%f\n,2.13,c_area(2.13));printf(Radius:%f,area:%f\n,0.865,c_area(0.865));printf(Radius:%f,area:%f\n,3.746,c_area(3.746));printf(Radius:%f,area:%f\n,12.3364,c_area(12.3364));printf(Radius:%f,area:%f\n,8.421,c_area(8.421));return0;}函数定义函数头部说明函数名和类型特征。包括:函数返回值类型,函数名,参数表。参数表声明参数的个数和各参数的类型。参数命名是为了在函数里使用实际参数的值。c_area定义的函数头部是:doublec_area(doubler)函数体:复合结构,其中定义的变量是本函数的局部变量。参数也看作局部变量。形式:函数头部函数体函数体里的特殊语句:return/返回语句:return表达式;return;使函数结束:先算表达式,以其值作为函数返回值。函数调用函数名(实际参数表)多个参数用逗号分隔。函数的执行:函数体的复合语句在参数具有特定实参值的情况下开始执行。多个参数的函数参数表里写多对类型/参数,逗号分隔。例:定义已知三角形三边长度求面积的函数。t_area,3个double参数返回double。类型特征:doublet_area(double,double,double)函数定义可写为:doublet_area(doublea,doubleb,doublec){doubles=(a+b+c)/2.0;return(sqrt(s*(s-a)*(s-b)*(s-c)));}定义无返回值的函数若函数不需要返回值,可定义无返回值的函数。形式:返回值类型处写void。•执行到达作为函数体末尾时函数结束•无返回值的函数不能用在表达式中例:根据半径计算并输出圆盘面积的函数:voidpc_area(doubler){printf(Radius:%f,area:%f\n,r,3.1416*r*r);}#includestdio.hvoidpc_area(doubler){printf(Radius:%f,area:%f\n,r,3.1416*r*r);}/*很容易修改输出格式,圆周率等*/intmain(){pc_area(3.24);pc_area(2.13);pc_area(0.865);pc_area(3.746);pc_area(12.3364);pc_area(8.421);return0;}函数和程序完整程序必须有一个名为main的函数(主函数)。intmain(){……}函数main表示程序的执行过程。程序从main的体开始执行,直到该复合结构结束(语句执行完或者退出)其他函数不经调用就不会执行。main在程序启动时被自动调用(由运行系统调用)。程序里不允许调用main。函数与类型返回语句中表达式的值应能转换到函数返回值类型,语句执行时将计算结果(转换后)作为返回值。例:intfun(intm){return3.2*m+5;}定义时的类型问题:头部定义返回值类型与返回语句中表达式的类型可能不一致。调用时的类型问题:实参个数应符合函数定义的要求,各实参应能转换到对应形参的类型。当实参类型与形参类型不同时,先转换为所需类型的值后再传给形参intfun(intm){return3.2*m+5;}语句:x=fun(2.5+6);设x是双精度变量,语句执行时有几次转换?类型转换的各种情况:•计算中可能出现类型转换•赋值时可能出现类型转换•参数传递时可能出现类型转换•产生函数返回值时可能出现类型转换t图3.2 函数的调用、执行与返回函数调用点,控制权转移到函数,原程序等待函数执行完毕,控制返回主程序,原程序继续程序的执行函数的执行认识函数调用包含一个/多个函数定义的程序模式:#include………/*函数定义写在这里*/intmain(){……/*主程序体,包含函数调用*/}建议写程序时采用这种形式更一般的形式后面介绍3.4关系表达式/逻辑表达式/条件表达式已有机制的编程能力还很弱。例如需要写一个函数,返回两参数中的较大值:doubledmax(double,double)需要:•比较数据大小(判断)•根据判断结果决定做什么(分情况处理)本节主要讨论如何描述逻辑判断,判断的结果如何确定,怎样利用逻辑判断控制计算过程关系运算符/关系表达式关系运算符确定数据间是否存在某种关系。关系表达式的结果可用于控制计算过程。关系运算符共6个:==大于/大于等于/小于等于/小于==!=等于/不等于关系运算符可用于算术类型。如果被比较对象的类型不同,按算术运算规则转换后再做判断。关系的成立与否(真/假
本文标题:北大裘宗燕《从问题到程序》第三章 变量、函数和控制结构
链接地址:https://www.777doc.com/doc-4896638 .html