main { printf("This is a c program.\n"); getchar getch(); } 他说是。错误 1.c 2: 说明语法错误

当前位置: >>
C语言基本语法成分
1、3C 语言基本语法成分1、C 语言字符集:字符是 C 语言的最基本的元素,C 语言字符集由字母、数字、空白、标点 和特殊字符组成(在字符串常量和注释中还可以使用汉字等其它图形符号)。由字符集 中的字符可以构成 C 语言进一步的语法成分(如,标识符,关键词,运算符等)。 (1)字母:A-Z,a-z (2)数字:0-9 (3)空白符
:空格,制表符(跳格),换行符(空行)的总称。空白符除了在字符,字符 串中有意义外,编译系统忽略其它位置的空白。空白符在程序中只是起到间隔作用。 在程序的恰当位置使用空白将使程序更加清晰,增强程序的可读性。 (4)标点符号、特殊字符: ! # % ^ & + * / = ~ & & \ | . , ; : ? ‘ “ ( ) [ ] { }2、标识符(名字):用来标识变量名、符号常量名、函数名、数组名、类型名等实体(程序 对象)的有效字符序列。标识符由用户自定义(取名字)。 C 语言标识符定义规则: 1)标识符只能由字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线。 例如: 合法的标识符:sum,average,_total,Class,day,stu_name,p4050 不合法的标识符:M.D.John,$123,#33,3D64,a&b 2)大小写敏感。C 程序员习惯:变量名小写,常量名大写,但不绝对,如 windows 编程, 应当使用匈牙利表示法(大小写混用, 每个单词词首第一个大写, 其余小写, WinMain)。 如 例如:sum 不同 Sum。BOOK 不同 book。 3)ANSI C 没有限制标识符长度, 但各个编译系统都有自己的规定和限制(TC 32 个字符, MSC 8 个字符)。 例如:student_name,student_number 如果取 8 个,这两个标识符是相同的。 4)标识符不能与“关键词”同名,也不与系统预先定义的“标准标识符”同名。 5)建议:标识符命名应当有一定的意义,做到见名知义。 3、关键词(保留字):C 语言规定的具有特定意义的字符串。参阅 P234 附录 V。 4、运算符:运算符将常量、变量、函数连接起来组成表达式,表示各种运算。运算符可以 由一个或多个字符组成。参阅 P233 附录 IV。 运算符根据参与运算的操作数的个数分为:单目、双目、三目运算符。 5、分隔符:逗号,空格。起分隔、间隔作用。 6、注释符:“/*”和“*/”构成一组注释符。编译系统将/* ... */之间的所有内容看作为 注释,编译时编译系统忽略注释。 注释在程序中作用:提示、解释作用。 注释与软件的文档同等重要,要养成使用注释的良好习惯,这对软件的维护相当重要。 记住: 程序是要给别人看的, 自己也许还会看自己几年前编制的程序 (相当别人看你的程序) , 清晰的注释有助于他人理解您的程序、算法的思路。 在软件开发过程中,还可以将注释用于程序的调试-暂时屏蔽一些语句。 例如,在调式程序时暂时不需要运行某段语句,而你又不希望立即从程序中删除它们,可以 使用注释符将这段程序框起来,暂时屏蔽这段程序,以后可以方便地恢复。1、4例 1.1: main() {C 程序结构1、4、1 简单的 C 程序介绍printf(“This is a C program.\n”); } 说明:本程序的功能是输出一行信息:This is a C program. 其中: 1、main 表示“主函数”。每个 C 语言程序都必须有一个 main 函数,它是每一个 C 语言程 序的执行起始点(入口点)。main()表示“主函数”main 的函数头。 2、用{}括起来的是“主函数”main 的函数体。main 函数中的所有操作(或:语句)都在这 一对{}之间。也就是说 main 函数的所有操作都在 main 函数体中。 3、“主函数”main 中只有一条语句,它是 C 语言的库函数,功能是用于程序的输出(显示 在屏幕上),本例用于将一个字符串“This is a C program.\n”的内容输出。即在屏幕上显 示: This is a C program. _ (回车/换行)4、注意:每条语句用“;”号结束语句。例 1.2: main() /* 计算两数之和 */ { int a,b, /* 这是定义变量 */ a=123;b=456; /* 以下 3 行为 C 语句 */ sum=a+b; printf(“sum=%d\n”,sum); } 说明:本程序计算两数之和,并输出结果。 1、同样此程序也必须包含一个 main 函数作为程序执行的起点。{}之间为 main 函数的函数 体,main 函数所有操作均在 main 函数体中。 2、/* */括起来的部分是一段注释,注释只是为了改善程序的可读性,在编译、运行时不起 作用(事实上编译时会跳过注释,目标代码中不会包含注释)。注释可以放在程序任何 位置,并允许占用多行,只是需要注意“/*”、“*/”匹配,一般不要嵌套注释。 3、int a,b,是变量声明。声明了三个具有整数类型的变量 a,b,sum。C 语言的变量必须 先声明再使用。 4、a=123;b=456;是两条赋值语句。 将整数 123 赋给整型变量 a, 将整数 456 赋给整型变量 b。 a,b 两个变量分别为 123,456。注意这是两条赋值语句,每条语句均用“;”结束。 也可以将两条语句写成两行,即: a=123; b=456; 由此可见 C 语言程序的书写可以相当随意,但是为了保证容易阅读要遵循一定的规范。 5、sum=a+b;是将 a,b 两变量内容相加,然后将结果赋值给整型变量 sum。此时 sum 的内容 为 579。 6、printf(“sum=%d\n”,sum);是调用库函数输出 sum 的结果。%d 为格式控制表示 sum 的值 以十进制整数形式输出。程序运行后,输出(显示): sum=579 1、4、2 C 程序结构 综合上述三个例子,我们对 C 语言程序的基本组成和形式(程序结构)有了一个初步了解: 1、C 程序由函数构成(C 是函数式的语言,函数是 C 程序的基本单位)(以例 1.3 说明) 一个 C 源程序至少包含一个 main 函数,也可以包含一个 main 函数和若干个其它函 数。函数是 C 程序的基本单位。 被调用的函数可以是系统提供的库函数, 也可以是用户根据需要自己编写设计的函 数。C 是函数式的语言,程序的全部工作都是由各个函数完成。编写 C 程序就是编 写一个个函数。 C 函数库非常丰富,ANSI C 提供 100 多个库函数,Turbo C 提供 300 多个库函数。2、main 函数(主函数)是每个程序执行的起始点(以例 1.3 说明) 一个 C 程序总是从 main 函数开始执行, 而不论 main 函数在程序中的位置。 可以将 main 函数放在整个程序的最前面,也可以放在整个程序的最后,或者放在其它函数之间。3、一个函数由函数首部和函数体两部分组成(以例 1.3 的 max 函数说明) (1)函数首部:一个函数的第一行。 返回值类型 函数名([函数参数类型 1 函数参数名 1][,…,函数参数类型 2, 函数参数名 2]) 注意:函数可以没有参数,但是后面的一对()不能省略,这是格式的规定。(2)函数体:函数首部下用一对{}括起来的部分。如果函数体内有多个{},最外层是函数体 的范围。函数体一般包括声明部分、执行部分两部分。 { [声明部分]:在这部分定义本函数所使用的变量。 [执行部分]:由若干条语句组成命令序列(可以在其中调用其它函数)。 } 4、C 程序书写格式自由 一行可以写几个语句,一个语句也可以写在多行上。 C 程序没有行号,也没有 FORTRAN,COBOL 那样严格规定书写格式(语句必须从某一列 开始)。 每条语句的最后必须有一个分号“;”表示语句的结束。5、可以使用/* */对 C 程序中的任何部分作注释 注释可以提高程序可读性,使用注释是编程人员的良好习惯。 实践中, 编写好的程序往往需要修改、完善,事实上没有一个应用系统是不需要修改、完善的。 很多人会发现自己编写的程序在经历了一些时间以后, 由于缺乏必要的文档、 必要的注 释,最后连自己都很难再读懂。需要花费大量时间重新思考、理解原来的程序。这浪费 了大量的时间。如果一开始编程就对程序进行注释,刚开始麻烦一些,但日后可以节省 大量的时间。 一个实际的系统往往是多人合作开发,程序文档、注释是其中重要的交流工具。6、C 语言本身不提供输入/输出语句,输入/输出的操作是通过调用库函数(scanf,printf) 完成。 输入/输出操作涉及具体计算机硬件,把输入/输出操作放在函数中处理,可以简化 C 语言和 C 的编译系统, 便于 C 语言在各种计算机上实现。 不同的计算机系统需要对函数库中 的函数做不同的处理,以便实现同样或类似的功能。 不同的计算机系统除了提供函数库中的标准函数外, 还按照硬件的情况提供一些专门的 函数。因此不同计算机系统提供的函数数量、功能会有一定差异。 1、源程序、目标程序、可执行程序的概念(补充)程序:为了使计算机能按照人们的意志工作,就要根据问题的要求,编写相应的程序。 程序是一组计算机可以识别和执行的指令,每一条指令使计算机执行特定的操作。 源程序: 程序可以用高级语言或汇编语言编写, 用高级语言或汇编语言编写的程序称为 源程序。C 程序源程序的扩展名为“.c” 事实上我们编写的程序,不管采用什么计算机语言,都是源程序,有几个人还会用机器语言 去编程! 源程序不能直接在计算机上执行,需要用“编译程序”将源程序翻译为二进制形式的代码。目标程序:源程序经过“编译程序”翻译所得到的二进制代码称为目标程序。目标程序 的扩展名为“.obj” 目标代码尽管已经是机器指令,但是还不能运行,因为目标程序还没有解决函数调用问题, 需要将各个目标程序与库函数连接,才能形成完整的可执行的程序。可执行程序: 目标程序与库函数连接, 形成的完整的可在操作系统下独立执行的程序称 为可执行程序。可执行程序的扩展名为“.exe”(在 dos/windows 环境下)第二章 基本数据类型2、1 C 的数据类型程序、算法处理的对象是数据。数据以某种特定的形式存在(如整数、实数、字符), 而且不同的数据还存在某些联系(如由若干整数构成的数组)。数据结构就是指数据的组织 形式(逻辑结构、物理结构)。处理同样的问题如果数据结构不同,算法也不同,应当综合 考虑算法和数据结构、选择最佳的数据结构和算法。 C 语言的数据结构是以数据类型的形式体现。也就是说 C 语言中数据是有类型的,数据 的类型简称数据类型。例如,整型数据、实型数据、整型数组类型、字符数组类型(字符串) 分别代表我们常说的整数、实数、数列、字符串。 C 语言的数据类型: 整数(长长;有有有有) 基基数数 字有数(有有有有) 单单单数 实数(浮浮数) 枚枚数数 数数数数 数数数数 构构数数 结构结数数 共共结数数 指指数数 C语语有语语语数数数数 空数数注意: 1、不同的数据类型有不同的取值范围。如有符号整数取值范围-3,浮点数 -3.4e-38~3.4e38。 2、不同的数据类型有不同的操作。如整型数可以取余操作,实型数据却不行;整型、 实型数据可以有加法,字符数组不行。 3、不同的数据类型即使有相同的操作有时含义也不同,如指针数据自增 1 与整数自增 1 含义是不同的。 4、不同的数据类型对计算机可能出现的错误不同。如整型数的溢出错误,浮点数的精 度的丢失(有效数字位数不够)。 5、C 语言的数据类型可以构造复杂的数据结构。如使用结构体数组可以构造线性表。 使用指针类型、结构体类型可以构造线性链表(栈、队列)、树、图。(在《数据结构》课 程介绍) 6、C 语言中的数据有变量与常量,它们分别属于上述这些类型。双单单数2、2注意:常量与变量2、2、1 常量:在程序的运行过程中,其值不能改变的量称为常量。1、常量有不同的类型,如 12、0、-3 为整型常量,4.6、-1.23 为实型常量,’a’、’d’字符 常量。常量可以从字面形式即可判断-字面常量或直接常量。 2、符号常量 #define PI 3.1416 使用符号常量的好处: (1)含义清楚、见名知意。 (2)修改方便、一改全改。 例 2-1:符号常量应用 #define PI 3.14 main() { area=10*10*PI; printf(&area=%f\n&,area); } 结果:area=314.0000002、2、2 变量:在程序的运行过程中,其值可以改变的量称为变量。 注意: 1、变量名(用标识符表示)、变量在内存中占据的存储单元、变量值三者关系。 变量名在程序运行过程中不会改变,变量的值可以改变。变量名遵守标识符准则。2、C 语言中变量:“先定义,后使用”。即就是说,C 要求对所有用到的变量做强制定义。 1)只有申明过的变量才可以在程序中使用,这使得变量名的拼写错误容易发现。BASIC 却 不是这样。 有时你会用了两个相近似变量而你根本没有发现, 却当作同一个变量在使用。 2)申明的变量属于确定的类型,编译系统可方便地检查变量所进行运算的合法性。 3)在编译时根据变量类型可以为变量确定存储空间,“先定义后使用”使程序效率高。2、3整型数据2、3、1 整型常数的表示方法 三种形式:(+/-) 1)十进制。 例如 123,-456,0。 2)八进制。以 0 开头,后面跟几位的数字(0-7)。 例如:0123=(123)8=(83)10;-011=(-11)8=(-9)10。 3)十六进制。以 0x 开头,后面跟几位的数字(0-9,A-F)。 例如:0x123=291,-0x12=-18。 4)整型常量的类型(整型常数的后缀)-在整型变量部分介绍,这里只要知道怎么表示。 整型常量后可以用: u 或 U 明确说明为无符号整型数 l 或 L 明确说明为长整型数.2、 3、2 整型变量 1、整型数据在内存中的存放形式 数据在内存中以二进制形式存放,事实上以补码形式存放。 例如:定义一个整型变量 i=10,补充知识(参考《微机原理》等课程): 1)带符号数的表示,原码、反码、补码。 2)原码-补码相互转化。正数的补码与其原码相同,负数的补码是其对应的原码数值位按位 取反+1。例题:10,-10 的计算机机内表示。 思路:先将数值表示为二进制形式(十进制=&二进制,除 2 取余),即获得数值的原码。将 原码转化为补码,就是机内表示。 10 =(1010)2 =(,)原=(,)补。 -10=(-1010)2=(,)原=(,)补。 从 10,-10 的计算机机内表示可以看出正数、负数机内表示(补码表示)看上去明显不同。2、整型变量的分类 整型变量的基本类型为 int。通过加上修饰符,可定义更多的整数数据类型。 1)根据表达范围可以分为:基本整型 (int)、短整型(short int)、长整型(long int)。 用 long 型可以获得大范围的整数,但同时会降低运算速度。 2)根据是否有符号可以分为:有符号(signed,默认),无符号(unsigned)-目的:扩大 表示范围,有些情况只需要用正整数。 有符号整型数的存储单元的最高位是符号位(0:正、1:负),其余为数值位。无符号整型 数的存储单元的全部二进制位用于存放数值本身而不包含符号。归纳起来可以用 6 种整型变量: 有符号基本整型 :[signed]int 有符号短整型 有符号长整型 :[signed]short[int] :[signed]long[int]无符号基本整型 :unsigned [int] 无符号短整型 :unsigned short [int] 无符号长整型 :unsigned long [int] 例子:保存整数 13 的各种整型数据类型。n() { a=; b=3333; printf(&a=%f,b=%f\n&,a,b); }2、4、3 实型常量的类型 1、许多 C 编译系统将实型常量作为双精度实数来处理,这样可以保证较高的精度,缺点是 运算速度降低。在实数的后面加字符 f 或 F,如 1.65f、654.87F,使编译系统按单精度 处理实数。 2、实型常量可以赋值给一个 float、double、long double 型变量。根据变量的类型截取实 型常量中相应的有效数字。2、6 变量赋初值程序中常常需要对一些变量预先设置初值,C 语言允许在定义变量的同时使变量初始化。 例如:int a=3; float f=3.56; char c=’a’;/* 指定 a 为整型变量,初值为 3 */ /* 指定 f 为实型变量,初值为 3.56 */ /* 指定 c 为字符型变量,初值为’a’ */ 可以只对定义的一部分变量赋初值。int a,b=2,c=5; /* 指定 a,b,c 为整型变量,只对 b、c 初始化,b 的初值为 2 ,c 的初值为 5*/初始化不是在编译阶段完成的, 而是在程序运行时执行本函数时赋予初值的, 相当于有一个 赋值语句。int a=3; 相当于:2、7 各类数值型数据(整型、实型、字符型)的混合运算整型(包括 int,short,long)和实型(包括 float,double)数据可以混合运算,另 外字符型数据和整型数据可以通用,因此,整型、实型、字符型数据之间可以混合运算。 例如:表达式 10+’a’+1.5-*’b’是合法的。 转换的方法有两种: 在进行运算时, 不同类型的数据先转换成同一类型, 然后进行计算, 自动转换(隐式转换);强制转换。1、自动动转换(隐式转换) 自动转换发生在不同类型数据进行混合运算时,由编译系统自动完成。转换规则: (参 看图 2-1) (1) 类型不同,先转换为同一类型,然后进行运算。 (2) 图中纵向的箭头表示当运算对象为不同类型时转换的方向。可以看到箭头由低级别 数据类型指向高级别数据类型,即数据总是由低级别向高级别转换。即按数据长度 增加的方向进行,保证精度不降低。 (3) 图中横向向左的箭头表示必定的转换(不必考虑其它运算对象)。如字符数据参与 运算必定转化为整数,float 型数据在运算时一律先转换为双精度型,以提高运算 精度(即使是两个 float 型数据相加,也先都转换为 double 型,然后再相加)。 (4) 赋值运算,如果赋值号“=”两边的数据类型不同,赋值号右边的类型转换为左边的 类型。这种转换是截断型的转换,不会四舍五入。 (教材 P19 倒数 18 行“四舍五入” 有异议?)例子:教材 P19。算式。(自学)2、强制转换 强制转换是通过类型转换运算来实现。 一般形式:(类型说明符)表达式 功能:把表达式的结果强制转换为类型说明符所表示的类型。 例如: (int)a 将 a 的结果强制转换为整型量。(int)(x+y) 将 x+y 的结果强制转换为整型量。 (float)a+b 将 a 的内容强制转换为浮点数,再与 b 相加。 说明: (1)类型说明和表达式都需要加括号(单个变量可以不加括号) (2)无论隐式转换,强制转换都是临时转换,不改变数据本身的类型和值。例 2-9:强制类型转换(P.20) main() { float f=5.75; printf(&(int)f=%d\n&,(int)f); /* 将 f 的结果强制转换为整型,输出 */ printf(&f=%f\n&,f); /* 输出 f 的值 */ } 结果: (int)f=5 f=5.750000第三章3、1 C 运算符简介运算符与表达式运算符:狭义的运算符是表示各种运算的符号。 表达式:使用运算符将常量、变量、函数连接起来,构成表达式。 C 语言运算符丰富,范围很宽,把除了控制语句和输入/输出以外的几乎所有的基本操 作都作为运算符处理,所以 C 语言运算符可以看作是操作符。C 语言丰富的运算符构成 C 语 言丰富的表达式(是运算符就可以构成表达式)。运算符丰富、表达式丰富、灵活。 在 C 语言中除了提供一般高级语言的算术、 关系、 逻辑运算符外, 还提供赋值符运算符, 位操作运算符、自增自减运算符等等。甚至数组下标,函数调用都作为运算符。C 的运算符有以下几类:++,-- 本章主要介绍算术运算符(包括自增自减运算符)、赋值运算符、逗号运算符,其它运 算符在以后相关章节中结合有关内容陆续进行介绍。3、2 算术运算符和算术表达式1、算术运算符 +(加法运算符。如 3+5) -(减法运算符或负值运算符。如 5-2,-3) *(乘法运算符。如 3*5) /(除法运算符。如 5/3,5.0/3) %(模运算符或求余运算符,%要求两侧均为整型数据。如 7%4 的值为 3)。 除了负值运算符-单目运算符外,其它都是双目运算符。 说明: (1)两个整数相除的结果为整数,如 5/3 的结果为 1,舍去小数部分。但是如果除数或被 除数中有一个为负值,则舍入的方向是不固定的,多数机器采用“向 0 取整”的方法 (实际上就是舍去小数部分,注意:不是四舍五入)。(2)如果参加+,-,*,/运算的两个数有一个为实数,则结果为 double 型,因为所有实数都 按 double 型进行计算。 (3)求余运算符%,要求两个操作数均为整型,结果为两数相除所得的余数。求余也称为求 模。一般情况,余数的符号与被除数符号相同。 例如:-8%5=-3;8%-5=32、算术表达式 算术表达式:用算术运算符和括号将运算对象(也称操作数)连接起来的、符合 C 语法 规则的式子,称为算术表达式。运算对象可以是常量、变量、函数等。 例如,下面是一个合法的 C 算术表达式。a*b/c-1.5+’a’。 注意: C 语言算术表达式的书写形式与数学表达式的书写形式有一定的区别: (1) C 语言算术表达式的乘号(*)不能省略。例如:数学式 b -4ac,相应的 C 表达式应 该写成:b*b-4*a*c。 (2) C 语言表达式中只能出现字符集允许的字符。例如,数学πr 相应的 C 表达式应该 写成:PI*r*r。(其中 PI 是已经定义的符号常量) (3) C 语言算术表达式不允许有分子分母的形式。例如,(a+b)/(c+d)。 (4) C 语言算术表达式只使用圆括号改变运算的优先顺序(不要指望用{}[])。可以使 用多层圆括号,此时左右括号必须配对,运算时从内层括号开始,由内向外依次计 算表达式的值。2 23、(算术)运算符的优先级与结合性(P.233 附录 IV) C 语言规定了进行表达式求值过程中,各运算符的“优先级”和“结合性”。 (1)C 语言规定了运算符的“优先级”和“结合性”。在表达式求值时,先按运算符的“优 先级别”高低次序执行。 如表达式:a-b*c 等价于 a-(b*c),“*”运算符优先级高于“-”运算符。(2)如果在一个运算对象两侧的运算符的优先级别相同,则按规定的“结合方向”处理。 例如:a-b+c,到底是(a-b)+c 还是 a-(b+c)?(b 先与 a 参与运算还是先于 c 参与运算?) 查附录 IV 可知:+/-运算优先级别相同,结合性为“自左向右”,即就是说 b 先与左边的 a 结合。所以 a-b+c 等价于(a-b)+c。 左结合性(自左向右结合方向):运算对象先与左面的运算符结合。 右结合性(自右向左结合方向):运算对象先与右面的运算符结合。(3)在书写多个运算符的表达式时,应当注意各个运算符的优先级,确保表达式中的运算符 能以正确的顺序参与运算。对于复杂表达式为了清晰起见可以加圆括号“()”强制规定计 算顺序。3、3 赋值运算符和赋值表达式1、赋值运算符、赋值表达式 赋值运算符:赋值符号“=”就是赋值运算符。 赋值表达式:由赋值运算符组成的表达式称为赋值表达式。一般形式: 〈变量〉〈赋值符〉〈表达式〉赋值表达式的求解过程: 将赋值运算符右侧的表达式的值赋给左侧的变量, 同时整个赋 值表达式的值就是刚才所赋的值。 赋值的含义: 将赋值运算符右边的表达式的值存放到左边 变量名标识的存储单元中。 例如:x=10+y; 执行赋值运算(操作),将 10+y 的值赋给变量 x,同时整个表达式的值就 是刚才所赋的值。说明: (1) 赋值运算符左边必须是变量,右边可以是常量、变量、函数调用或常量、变量、函 数调用组成的表达式。 例如:x=10 y=x+10 y=func()都是合法的赋值表达式。(2) 赋值符号“=”不同于数学的等号,它没有相等的含义。(“==”相等) 例如:C 语言中 x=x+1 是合法的(数学上不合法),它的含义是取出变量 x 的值加 1,再存 放到变量 x 中。(3) 赋值运算时,当赋值运算符两边数据类型不同时,将由系统自动进行类型转换。 转换原则是:先将赋值号右边表达式类型转换为左边变量的类型,然后赋值。 将实型数据(单、双精度)赋给整型变量,舍弃实数的小数部分。 将整型数据赋给单、双精度实型变量,数值不变,但以浮点数形式存储到变量中。 将 double 型数据赋给 float 型变量时,截取其前面 7 位有效数字,存放到 float 变量的存储单元中(32bits)。但应注意数值范围不能溢出。将 float 型数据赋给 double 型变量时,数值不变,有效位数扩展到 16 位(64bits)。 字符型数据赋给整型变量时,由于字符只占一个字节,而整型变量为 2 个字节,因 此将字符数据(8bits)放到整型变量低 8 位中。有两种情况: 如果所使用的系统将字符处理为无符号的量或对 unsigned char 型变量赋值, 则将字符 的 8 位放到整型变量的低 8 位,高 8 位补 0。 如果所使用的系统将字符处理为带符号的量(signed char)(如 Turbo C),若字符 最高位为 0,则整型变量高 8 位补 0;若字符最高位为 1,则整型变量高 8 位全补 1。这 称为符号扩展,这样做的目的是使数值保持不变。 将一个 int,short,long 型数据赋给一个 char 型变量时,只是将其低 8 位原封不 动地送到 char 型变量(即截断)。 将带符号的整型数据(int 型)赋给 long 型变量时,要进行符号扩展。即,将整型 数的 16 位送到 long 型低 16 位中,如果 int 型数值为正,则 long 型变量的高 16 位补 0,如果 int 型数值为负,则 long 型变量的高 16 位补 1,以保证数值不变。 反之,若将一个 long 型数据赋给一个 int 型变量,只将 long 型数据中低 16 位原 封不动地送到整型变量(即截断)。 将 unsigned int 型数据赋给 long int 型变量时,不存在符号扩展问题,只要将高 位补 0 即可。将一个 unsigned 类型数据赋给一个占字节相同的整型变量,将 unsigned 型变量的内容原样送非 unsigned 型变量中,但如果数据范围超过相应整 数的范围,则会出现数据错误。 将非 unsigned 型数据赋给长度相同的 unsigned 型变量,也是原样照赋。 总之: 不同类型的整型数据间的赋值归根到底就是: 按照存储单元的存储形式直接传送。 (由长型整数赋值给短型整数, 截断直接传送; 由短型整数赋值给长型整数, 低位直接传送, 高位根据低位整数的符号进行符号扩展)。 (4) C 语言的赋值符号“=”除了表示一个赋值操作外,还是一个运算符,也就是说赋值 运算符完成赋值操作后,整个赋值表达式还会产生一个所赋的值,这个值还可以利 用。 赋值表达式的求解过程是: 先计算赋值运算符右侧的“表达式”的值 将赋值运算符右侧“表达式”的值赋值给左侧的变量。 整个赋值表达式的值就是被赋值变量的值。 例如:分析 x=y=z=3+5 这个表达式。根据优先级:原式 向左): x=(y=(z=(3+5))) x=(y=(z=3+5)) x=y=z=(3+5);根据结合性(从右z=3+5:先计算 3+5,得值 8 赋值给变量 z,z 的值为 8,(z=3+5)整个赋值表达式值为 8; y=(z=3+5):将上面(z=3+5)整个赋值表达式值 8 赋值给变量 y,y 的值为 8,(y=(z=3+5)) 整个赋值表达式值为 8; x=(y=(z=3+5)):将上面(y=(z=3+5))整个赋值表达式值 8 赋值给变量,z 的值为 8,整个表 达式 x=(y=(z=3+5))的值为 8。 最后,x,y,z 都等于 8运算步骤: 序号 1 2 3 表达式 z=3+5 y=(z=3+5) x=(y=(z=3+5)) 变量及值 z(8) y(8) x(8) 表达式的值 8 8 8将赋值表达式作为表达式的一种, 使赋值操作不仅可以出现在赋值语句中, 而且可以以 表达式的形式出现在其它语句中。2、复合赋值运算符 在赋值符“=”之前加上某些运算符,可以构成复合赋值运算符,复合赋值运算符可以 构成赋值表达式。C 语言中许多双目运算符可以与赋值运算符一起构成复合运算符,即: +=,-=,*=,/=,%=,&&=,&&=,&=,|=,^= &变量&&双目运算符&=&表达式& 复合赋值表达式一般形式: &变量&=&变量&&双目运算符&&表达式& 等价于:例如: n+=1 等价于 n=n+1 注意: 赋值运算符、 复合赋值运算符的优先级比算术运算符低。x*=y+1 等价于 x=x*(y+1)3、赋值运算符、赋值表达式举例 (1) a=5 (2) a=b=5 (3) a=(b=4)+(c=3) (4) 假如 a=12,分析:a+=a-=a*a a+=a-=a*a a*a) a+=a-=(a*a) a+=(a-=(a*a)) a+=(a=a-(a*a)) a+=(a=a-a*a) a=a+(a=a-3、4++i,i++ 注意:自增、自减运算符--i,i―单目运算符,使变量的值增 1 或减 1。如:(1) ++i,--i(前置运算):先自增、减,再参与运算;i++,i―(后置运算):先参与运 算, 再自增、减。 例如:i=3,分析 j=++i; j=i++;(2) 自增、减运算符只用于变量,而不能用于常量或表达式。 例如:6++,(a+b)++,(-i)++都不合法。(3) ++,--的结合方向是“自右向左”(与一般算术运算符不同)。 例如:-i++ -(i++) 合法。 (4) 自增、自减运算符常用于循环语句中,使循环变量自动加 1,也用于指针变量,使 指针指向下一个地址。有关表达式使用过程中的问题说明 (1)C 运算符和表达式使用灵活,利用这一点可以巧妙处理许多在其它语言中难以处理的 问题。但是 ANSI C 并没有具体规定表达式中的子表达式的求值顺序,允许各编译系统 自己安排。这可能导致有些表达式对不同编译系统有不同的解释,并导致最终结果的 不一致。 例 1:a=f1()+f2()中 f1,f2 哪个先调用。 例 2:i=3,表达式(i++)+(i++)+(i++)的值。有些系统等价 3+4+5,Turbo C 等价 3+3+3 (2)C 语言有的运算符为一个字符, 有的由两个字符组成, 编译系统在处理时尽可能多地 C 将若干字符组成一个运算符(在处理标识符、关键字时也按同一原则处理)。如 i+++j 将解释为(i++)+j 而不是 i+(++j)。为避免误解,最好采用大家都能理解的写法,比如 通过增加括号明确组合关系,改善可读性。 (3)C 语言中类似的问题还有函数调用时,实参的求值顺序,C 标准也无统一规定。 如:i=3,printf(“%d,%d”,i,i++);有些系统执行的结果为 3,3;有些系统为 4,3。总之,不要写别人看不懂(难看懂)、也不知道系统会怎样执行的程序。3、5 逗号运算符和逗号表达式C 语言提供一种特殊的运算符-逗号运算符(顺序求值运算符)。用它将两个或多个表 达式连接起来,表示顺序求值(顺序处理)。用逗号连接起来的表达式称为逗号表达式。 例如:3+5,6+8 表达式 1,表达式 2,…表达式 n 逗号表达式的一般形式:逗号表达式的求解过程是:自左向右,求解表达式 1,求解表达式 2,…,求解表达式 n。 整个逗号表达式的值是表达式 n 的值。 例如:逗号表达式 3+5,6+8 的值为 14。 例题:a=3*5,a*4 查运算符优先级表可知,“=”运算符优先级高于“,”运算符(事实上,逗 号运算符级别最低)。所以上面的表达式等价于: (a=3*5),(a*4). 所以整个表达式计算后值为:60(其中 a=15)例题main() { int x,a; x=(a=3,6*3); x=a=3,6*a; } /* a=3 x=18 */ /* a=3 x=3 */printf(&%d,%d\n&,a,x); printf(&%d,%d\n&,a,x);逗号表达式主要用于将若干表达式“串联”起来,表示一个顺序的操作(计算),在许 多情况下, 使用逗号表达式的目的只是想分别得到各个表达式的值, 而并非一定需要得到和 使用整个逗号表达式的值。 第四章 顺序程序设计程序设计时,通常采用三种不同的程序结构,即顺序结构、选择结构和循环结构。其中 顺序结构是最基本、最简单的程序结构。通过本章顺序程序设计的学习,使大家可以开始最 简单的 C 程序设计。4、1C 语句概述C 语言的语句用来向计算机系统发出操作指令。 一个语句经过编译后产生若干条机器指 令。实际程序包含若干条语句。语句都是用来完成一定操作任务的。声明部分的内容不应当 称为语句。函数包含声明部分和执行部分,执行部分由语句组成。 C 程序结构:一个 C 程序可以由若干个源程序文件组成,一个源文件可以由若干个函数 和预处理命令以及全局变量声明部分组成, 一个函数由数据定义部分和执行语句组成。 程序 包括数据描述(由声明部分来实现)和数据操作(由语句来实现)。数据描述主要定义数据 结构(用数据类型表示)和数据初值。数据操作的任务是对已提供的数据进行加工。C 语句可以分为以下 3 大类: 4、1、1 控制语句-完成一定控制功能的语句(主要用于控制程序流程)。 C 有 9 种控制语句,它们是: 4、 1、2 表达式语句-用表达式构成语句,表示一个运算或操作。 表达式语句是在表达式最后加上一个 ” “; 组成。 一个表达式语句必须在最后出现分号, 分号是表达式语句不可缺少的一部分。C 程序中大多数语句是表达式语句(包括函数调用语 句)。 表达式语句的一般形式: 例如: 表达式 a=3(赋值表达式) getch()(函数调用-表达式) 函数调用也属于表达式 i++(自增表达式) ch=getch()(函数调用表达式, 赋值表达式) x+y(算术表达式) i++;(一般表达式语句) ch=getch(); (一般表达式语句) x+y;(一般表达式语句)x+y; 是一个语句, 其作用是完成 x+y 操作, 是合法的, 但是并不将结果赋 给另外的变量,所以并无实际意义表达式;表达式语句 a=3;(赋值语句) getch();(函数调用语句)说明getch();合法且有意义,只关心是 否有击键,不关心具体的值表达式语句常见的形式可以有:赋值语句、函数调用语句、空语句。1、 赋值语句:由赋值表达式加上一个分号构成赋值语句。 C 语言的赋值语句先计算赋值运算符右边的子表达式的值, 然后将此值赋值给赋值运算 符左边的变量。C 语言的赋值语句具有其它高级语言的赋值语句的一切特点和功能。2、 函数调用语句:由函数调用表达式加一个分号构成函数调用语句。 例如:printf(“This is a C statement.”);3、 空语句:只有一个分号的语句,它什么也不做(表示这里可以有一个语句,但是目前不 需要做任何工作)。 例如: (1)空循环 100 次,可能表示一个延时,也可能表示目前还不必在循环体中做什么事情。 for(i=0;i&100;i++); /* 循环结构要求循环体, 但目前什么工作都不要做。 表示循环体 */ ; (2)如果条件满足什么都不做,否则完成某些工作。(;表示 if 块,什么都不做) if() ; else { ...... }4、1、3 复合语句 用{}把一些语句(语句序列,表示一系列工作)括起来成为复合语句,又称语句块、分 程序。 一般情况凡是允许出现语句的地方都允许使用复合语句。 在程序结构上复合语句被看作 一个整体的语句,但是内部可能完成了一系列工作。注意:C 语言允许一行写几个语句,也允许一个语句拆开写在几行上,书写格式无固定 要求。一般将彼此关联的、或表示一个整体的一组较短的语句写在一行上。比如第 1A 章各 个算法的赋初值语句可以写在一行上(避免罗嗦,看上去也清晰)。 4、2输入/输出及其 C 语言的实现(补充)1、计算机由主机(CPU、内存),外围设备(输入/输出设备),接口组成。CPU内内I/O接接主打 外外外外 键硬键键 显显显 打打打 硬硬 软软2、 输入/输出:从计算机向外部设备(如显示器、打印机、磁盘等)输出数据称为“输出”, 从外部设备(如键盘、鼠标、扫描仪、光盘、磁盘)向计算机输入数据称为“输入”。 输入/输出是以计算机主机为主体而言的。 3、 C 语言本身不提供输入/输出语句,输入/输出操作由函数实现。在 C 标准函数库中提供 了一些输入/输出函数, printf 函数, 如 scanf 函数。 不要将两者看作是输入/输出语句。 实际上完全可以不用这两个函数,而另外编制输入/输出函数。 C 编译系统与 C 函数库是分别设计的, 因此不同的计算机系统所提供函数的数量、 名字、 功能不完全相同。但是,有些通用的函数各种计算机系统都提供,成为各种计算机系统的标 准函数。 C 函数库中有一批“标准输入/输出函数”,它是以标准的输入/输出设备(一般为终端) 为输入/输出对象的。其中有:putchar(输出字符),getchar(输入字符),printf(格式 化输出),scanf(格式化输入),puts(输出字符串),gets(输入字符串)。4、 在使用 C 库函数时,要用预编译命令“#include”将有关的“头文件”包含到用户源文 件中。头文件包含库中函数说明,定义的常量等。每个库一般都有相应的头文件。 比如 printf 等函数属于标准输入/输出库,对应的头文件是 stdio.h。也就是说如果要使用 printf 等函数,应当在程序的开头#include &stdio.h&。又如 fabs 函数属于数学库,对应 的头文件是 math.h,如果要使用 fabs 函数计算绝对值,那么应当在程序的开头#include &math.h&。 注意: 1、函数说明检查函数调用,进行数据类型转换,并产生正确的调用格式。许多编译系统强 制要求函数说明(函数原型声明),否则编译不成功。 2、Turbo C 中可以用^F1 查看一个函数的说明(包含属于哪个头文件)。4、3格式输入/输出4、3、1 printf 函数(格式输出函数) 功能:按照用户指定的格式,向系统隐含的输出设备(终端)输出若干个任意类型的数据。 1、printf 函数的一般格式: printf(格式控制字符串,输出表列)例如:函数参数包括两部分: (1)“格式控制”字符串是用双引号括起来的字符串,也称“转换控制字符串”, 它指定 输出数据项的类型和格式。 它包括两种信息: 格式说明项:由“%”和格式字符组成,如%d,%f 等。格式说明总是由“%”字符开始, 到格式字符终止。 它的作用是将输出的数据项转换为指定的格式输出。 输出表列中的每 个数据项对应一个格式说明项。 普通字符:即需要原样输出的字符。例子中的逗号和换行符。 (2)“输出列表”是需要输出的一些数据项,可以是表达式。 例如:假如 a=3,b=4,那么 printf(“a=%d b=%d”,a,b);输出 a=3 b=4。其中两个“%d”是格 式说明,表示输出两个整数,分别对应变量 a,b,“a=”,“b=”是普通字符,原样输出。 由于 printf 是函数, “格式控制” 因此 字符串和 “输出表列” 实际上都是函数的参数。 printf 函数的一般形式可以表示为: printf(参数 1、参数 2、参数 3、…参数 n) printf 函数的功能是将参数 2-参数 n 按照参数 1 给定的格式输出。2、格式字符(构成格式说明项)对于不同类型的数据项应当使用不同的格式字符构成的格式说明项。 常用的有以下几种格式 字符:(按不同类型数据,列出各种格式字符的常用用法)(1)d 格式符。用来输出十进制整数。有以下几种用法: %d,按照数据的实际长度输出 %md,m 指定输出字段的宽度(整数)。如果数据的位数小于 m,则左端补以空格(右对 齐),若大于 m,则按照实际位数输出。 %-md,m 指定输出字段的宽度(整数)。如果数据的位数小于 m,则右端补以空格(左 对齐),若大于 m,则按照实际位数输出。 %ld,输出长整型数据,也可以指定宽度%mld。(2)O 格式符。以八进制形式输出整数。注意是将内存单元中的各位的值按八进制形式输 出,输出的数据不带符号,即将符号位也一起作为八进制的一部分输出。 int a=-1; printf(“%d,%o,%x”,a,a,a); -1 的原码:00,0001。 -1 在内存中的补码表示为: 11,,111,111,111,111=1,7,7,7,7,7=ffff 输出:-1,177777,ffff -1 是十进制,177777 是八进制,ffff 是十六进制。(3)x 格式符。以十六进制形式输出整数。与 o 格式一样,不出现负号。 (4)u 格式符。用来输出 unsigned 无符号型数据,即无符号数,以十进制形式输出。 一个有符号整数可以用%u 形式输出,反之,一个 unsigned 型数据也可以用%d 格式输出。 (5)c 格式符。用来输出一个字符。一个整数只要它的值在 0-255 范围内,也可以用字符 形式输出。反之,一个字符数据也可以用整数形式输出。 main() { char c=’a’; int i=97; printf(“%c,%d\n”,c,c); printf(“%c,%d\n”,i,i); } 运行结果: a,97 a,97也可以指定字段宽度。%mc,m-整数(6)s 格式符。用来输出一个字符串。有几种用法: %s,输出字符串 %ms,输出的字符串占 m 列,如果字符串长度大于 m,则字符串全部输出;若字符串长 度小于 m,则左补空格(右对齐)。 %-ms,输出的字符串占 m 列,如果字符串长度大于 m,则字符串全部输出;若字符串长 度小于 m,则右补空格(左对齐)。 %m.ns,输出占 m 列,但只取字符串左端 n 个字符,左补空白(右对齐)。 %-m.ns,输出占 m 列,但只取字符串左端 n 个字符,右补空白(左对齐)。(7)f 格式符。用来输出实数(包括单、双精度,单双精度格式符相同),以小数形式输 出。有以下几种用法: %f,不指定宽度,使整数部分全部输出,并输出 6 位小数。注意,并非全部数字都是有效数字,单精度实数的有效位数一般为 7 位(双精度 16 位)。%m.nf, 指定数据占 m 列,其中有 n 位小数。 如果数值长度小于 m,左端补空格 (右对齐) 。 %-m.nf, 指定数据占 m 列,其中有 n 位小数。 如果数值长度小于 m,右端补空格 (左对齐) 。(8)e 格式符,以指数形式输出实数。可用以下形式: %e,不指定输出数据所占的宽度和小数位数,由系统自动指定,如 6 位小数,指数占 5 位-e 占 1 位,指数符号占 1 位,指数占 3 位。数值按照规格化指数形式输出(小数点 前必须有而且只有 1 位非 0 数字)。 例如:1.2。(双精度) %m.ne 和%-m.ne,m 总的宽度,n 小数位数。(9)g 格式符,用来输出实数,它根据数值的大小,自动选 f 格式或 e 格式(选择输出时 占宽度较小的一种),且不输出无意义的 0(小数末尾 0)。 #include &stdio.h& main() { float f=123.0; printf(&%f,%e,%g\n&,f,f,f); } 123..2 以上介绍的 9 种格式符,归纳如下表:教材 p32-p34 的 4、2、4 节是将格式说明项分为几个部分依次说明各个部分的作用,并 对每个部分进行说明,课后请对照笔记仔细阅读,总结一般规律,切忌死记硬背。 Turbo C 中 printf 函数格式字符串的一般形式:% h/l± 格式字符m.n[开始符][标志字符][宽度指示符][精度指示符][长度修正符][格式转换符] 3、使用 printf 函数的几点说明: (1)除了 X,E,G 外,其它格式字符必须用小写字母。如%d 不能写成%D。 (2)可以在“格式控制”字符串中包含转义字符。如“…\n…” (3)格式符以%开头,以上述 9 个格式字符结束。中间可以插入附加格式字符。 (4)如果想输出字符%,则应当在“格式控制”字符串中用两个%表示。4、3、2 scanf 函数(格式输 入函数) 1、scanf 函数的一般格式: scanf(格式控制字符串,地址列表)其中: (1)格式控制字符串的含义与 printf 类似,它指定输入数据项的类型和格式。 (2)地址列表是由若干个地址组成的列表,可以是变量的地址(&变量名)或字符串的首地 址。例如,用 scanf 函数输入数据。 main() { int a,b,c; scanf(“%d%d%d”,&a,&b,&c); printf(“%d,%d,%d\n”,a,b,c); } &是地址运算符, 指变量 a 的地址。 &a scanf 的作用是将键盘输入的数据保存到&a,&b,&c 为地址的存储单元中,即变量 a,b,c 中。 %d%d%d 表示要求输入 3 个十进制整数。输入数据时,在两个数据之间以一个或多个空 格分隔,也可以用回车键,跳格键(tab)分隔。这种格式不能用逗号分隔数据。 例如,合法的输入: 3 3 4 5 3(按 tab 键)4 5 非法的输入:3,4,5 4 52、格式说明 与 printf 函数中的格式说明相似, 以%开始, 以一个格式字符结束, 中间可以插入附加字符。 说明: (1)对 unsigned 型变量所需的数据,可以用%u,%d 或%o,%x 格式输入。 (2)可以指定输入数据所占列数,系统自动按它截取所需数据。 如: int i1,i2; scanf(“%3d%3c%3d”,&i1,&c,&i2); 输入:123---456 后,i1=123,i2=456,c=’-’(3)如果%后有“*”附加格式说明符,表示跳过它指定的列数,这些列不赋值给任何变量。 如: scanf(“%3d%*3c%2d”,&i1,&i2); 输入: 后,i1=123,i2=78,(456 被跳过) 在利用现有的一批数据,有时不需要其中某些数据,可以用此方法“跳过”它们。(4)输入数据时可以指定数据字段的宽度,不能规定数据的精度。 例如,scanf(“%7.2f”,&a);是不合法的。不能指望使用这种形式通过输入 1234567 获得 a=12345.67。3、使用 scanf 函数应当注意的问题 (1)scanf 函数中“格式控制”后面应当是变量地址,而不应是变量名。 例如:scanf(“%d,%d”,a,b);不合法。(原因:C 是传值调用,不能由形参返回值) (2)如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时在对 应位置应当输入与这些字符相同的字符。建议不要使用其它的字符。 例 1:scanf(“%d,%d,%d”,&a,&b,&c); 应当输入 3,4,5;不能输入 3 4 5。 例 2:scanf(“%d:%d:%d”,&h,&m,&s); 应当输入 12:23:36 例 3:scanf(“a=%d,b=%d,c=%d”,&a,&b,&c); 应当输入 a=12,b=24,c=36(太罗嗦)(3)在用“%c”格式输入字符时,空格字符和转义字符都作为有效字符输入。%c 只要求读 入一个字符,后面不需要用空格作为两个字符的间隔。 对于 scanf(“%c%c%c”,&c1,&c2,&c3); 输入:a b c&CR&后,c1=’a’,c2=’ ’,c3=’b’(4)在输入数据时,遇到下面情况认为该数据结束: 遇到空格,或按“回车”或“跳格”(tab)键。 int a,b,c; scanf(“%d%d%d”,&a,&b,&c); 输入:12 34 (tab) 567&CR&后,a=12,b=34,c=567 按指定的宽度结束 遇到非法的输入 float a,c; scanf(“%d%c%f”,&a,&b,&c); 输入:&CR&后,a=1234.0,b=’a’,c=123.0(而不是希望的 1230.26)C 语言的格式输入输出的规定比较繁琐,重点掌握最常用的一些规则和规律即可,其它 部分可在需要时随时查阅。

我要回帖

更多关于 getch 的文章

 

随机推荐