版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
编写C程序的基础知识1.1C程序的编写、调试和运行1.2算法1.3程序中的数据1.4常用表达式和运算符 1.1C程序的编写、调试和运行
1.1.1C程序的结构
1. C语言程序的结构分析
在使用C语言编写程序时,必须按其规定的格式进行编写。下面从几个简单的C语言程序入手,分析C语言程序的结构特点和书写格式。图1-1例1-1程序运行结果
程序分析如下:
(1)这是一个完整的C程序,包含一个main函数(也称为主函数)。
(2)“main()”为主函数的函数首部,随后的“{……}”为主函数的函数体。
(3)该程序中只有一条语句“printf(”Hello,world!\n“);”,该语句能够在屏幕上输出“Hello,world!”,语句以分号“;”为结束符。
(4)“/*……*/”是对程序起到说明作用的注释部分,程序执行时并不执行注释部分。
(5)“#include<stdio.h>”是编译预处理命令。printf是系统提供的标准库函数之一,使用这些函数时,应该在程序开始处使用编译预处理命令,将相应的头文件包含进来。常用的系统标准库函数及对应的头文件见附录D。图1-2例1-2程序运行结果程序分析如下:
(1)函数体由声明部分(也称为定义部分)和执行部分组成。
(2)声明部分是函数体中使用的变量定义及某些函数的声明。
(3)执行部分由语句构成,用来完成函数所要实现的功能。图1-3例1-3程序运行结果
程序分析如下:
(1)该程序由主函数main及函数名为hello、star的函数组成。
(2)在主函数main中使用到了hello、star函数,我们称之为调用。关于函数的具体知识将在第5单元进行详细介绍。
2. C语言程序的结构特点
从上面的例子可以总结出C程序结构的主要特点:
(1)函数是组成C语言程序的基本单元。编写C程序其实就是定义一个个函数。函数构成如图1-4所示。图1-4函数构成
(2)一个C程序中有且仅有一个主函数即main函数,可以没有或有多个其他函数。主函数的位置没有特别要求,只要不嵌套定义在其他函数内部。
(3)一个C程序总是从main函数开始执行,main函数执行结束,整个程序即结束。
3.C语言程序的书写格式
从上面的例子也可以总结出C程序的书写格式:
(1) C程序使用分号“;”作为语句的终止符,复合语句除外。
(2) C程序书写格式自由,一条语句可以分多行写,一行上也可以写多条语句。
(3)C语言严格区分大小写。C程序习惯上用小写字母,但符号常量、宏定义等习惯用大写字母,所有的关键字必须采用小写字母。
(4)在程序中使用注释对程序进行说明和解释,可增强程序的可读性。注释部分的格式如下:
/*注释内容*/
(5)适当采用缩进格式很有必要。采用缩进格式,可使程序更加清晰、易读。1.1.2C程序的调试与运行
1.调试运行步骤
从编写一个C程序到运行并得到结果一般需要经过四个步骤:编辑、编译、连接、运行。此过程如图1-5所示。图1-5C程序调试运行步骤
(1)编辑:将编写的C语言源程序输入到计算机中以文件的形式保存起来。C语言源程序的扩展名为“c”,在VisualC++6.0集成开发环境中通常将C程序保存为扩展名为“cpp”的文件,如“f.c”或“f.cpp”。
(2)编译:C语言源程序编辑好之后,应将其编译为二进制的目标代码。在编译时,还会对源程序进行语法检查,如果源程序存在语法错误,用户应该返回编辑状态,根据错误提示信息查找错误并改正,再次重新编译,直到没有语法错误,生成目标程序文件,扩展文件名为“obj”,如“f.obj”。
(3)连接:将各个模块的二进制目标代码与系统标准模块进行连接处理,得到最终的可执行文件。连接成功将生成可执行文件,扩展文件名为“exe”,如“f.exe”。
(4)运行:可执行文件没有语法错误,但可能有设计上的错误而导致运行结果不正确。若运行结果不正确,还需要返回到编辑状态查找并修改错误,重新编译、连接、运行,直至运行结果正确。
2.在VisualC++6.0集成开发环境中运行C程序
C语言的集成开发环境有TurboC、BorlandC、VisualC++等。VisualC++6.0功能强大、灵活性好,是目前较为流行的C语言集成开发环境。下面以具体的例子为例,介绍在VisualC++ 6.0集成开发环境中编辑、编译、连接、运行C程序的方法。
(1)创建工作文件夹。
在用VisualC++6.0进行C程序设计时,一般先要创建一个工作文件夹,以便集中管理和查找文件。如创建文件夹“C:\源程序”。
(2)启动VisualC++6.0。
选择“开始”→“程序”→“MicrosoftVisualStudio6.0”→“MicrosoftVisualC++6.0”,运行VisualC++6.0,进入VisualC++6.0开发环境,如图1-6所示。图1-6VisualC++6.0开发环境
(3)创建C源程序文件。
选择“文件”菜单→“新建”命令,或直接按【Ctrl】+【N】组合键打开“新建”对话框。选择“文件”选项卡中的“C++SourceFile”,在右边的“文件”文本框中输入文件名,如“1-4”;单击“目录”文本框右侧的
按钮修改保存文件的位置,如“C:\源程序”,如图1-7所示;单击“确定”按钮,即可进入VisualC++6.0的代码编辑区编辑程序。图1-7新建C程序
(4)编辑代码并保存。
①编辑代码:在代码编辑区输入1-4.cpp的源代码,完成后如图1-8所示。源代码如下:
【例1-4】
编辑、编译、连接、运行如下C程序。
②保存源程序文件:选择“文件”菜单→“保存”命令(“另存为”命令可修改文件名或文件存放位置),也可单击工具栏中的“保存”按钮
来保存文件。图1-8在编辑区编辑源程序
(5)编译。
选择“组建”菜单(由于汉化版本不同,有的版本此处为“编译”菜单)→“编译”命令,也可单击工具栏的“编译”按钮
,或按【Ctrl】+【F7】组合键,在弹出的“创建默认项目工作空间”对话框中选择“是”按钮,如图1-9所示,然后系统开始对当前的源程序进行编译。图1-9“创建默认项目工作空间”对话框
若编译过程中没有发现语法错误,则在输出区窗口中显示如图1-10所示的编译信息。图1-10输出区窗口中的编译信息
(6)连接。
选择“组建”菜单→“组建”命令,也可单击工具栏的“连接”按钮
,或按【F7】键进行连接。若连接没有错误,则在输出区窗口中显示如图1-11所示的连接信息。图1-11输出区窗口中的连接信息
(7)运行。
选择“组建”菜单→“执行”命令,也可单击工具栏的“执行”按钮
,或按【Ctrl】+【F5】组合键运行程序,即可看到控制台程序窗口中的运行结果,如图1-12所示。图1-12程序1-4.cpp的运行结果
(8)关闭工作空间。
完成了对程序的操作后,应保存好已经建立的程序与数据,并关闭工作空间。选择“文件”菜单→“关闭工作空间”命令,可关闭工作空间。
关闭工作空间后,可重复以上步骤,进行其他程序文件的操作。
3.编译错误的处理
若在编译过程中系统发现程序存在编译错误,会将错误信息、显示在输出区窗口中,如图1-13所示。图1-13存在语法错误的程序1-4.cpp的编译结果
源程序错误分为三种类型:致命错误fatalerror、一般错误error和警告warning。致命错误通常是内部编译错误。一般错误指程序的语法错误、磁盘或内存存取错误或命令错误。发生致命错误及一般错误时,必须采取一些适当的措施并重新编译,只有修改这两类错误后,程序才能继续连接、运行。警告并不阻止编译进行,它指出一些值得怀疑的情况,可以说warning是编译器为程序员提供的友善建议和意见,我们应当认真查看产生warning的原因。
错误信息中指出了错误所在行号和错误原因(可将输出区的垂直滚动条向上拖动),如图1-14所示。双击错误信息,将会在编辑区提示错误在程序中的大致位置,通常是错误所在的行或附近。查找出错误,修改后重新编译直至成功,方可连接、运行。图1-14编译错误信息
1.2算
法
计算机尽管可以完成许多极其复杂的工作,但实质上这些工作都是按照人们事先编好的程序进行的,所以人们常把程序称为计算机的灵魂。有这样一个著名的公式:
程序 = 算法 + 数据结构
这个公式说明:对于面向过程的程序设计语言而言,程序由算法和数据结构两大要素构成。其中,数据结构是指数据的组织和表示形式;而算法就是进行操作的方法和步骤,是程序的灵魂。这里我们重点讨论算法。1.2.1算法的定义和特性
1.算法的定义
算法是为解决一个具体问题而采用的确定、有效的方法和操作步骤。
【例1-5】
已知圆的半径为10,求其面积。描述解决该问题的算法。
算法描述如下:
(1)半径r=10;
(2)面积s=πr2;
(3)输出面积s,结束。
【例1-6】
有三只杯子:A杯中装满酒,B杯中装满醋,C杯是空杯。利用C杯将A杯与B杯装的东西对换。描述解决该问题的算法。
算法描述如下:
(1) A杯倒入C杯;
(2) B杯倒入A杯;
(3) C杯倒入B杯,结束。
2.算法的特性
计算机所能执行的算法必需具备以下五个特性。
(1)有穷性。计算机按照算法的规定执行有限次数的操作后终止。
(2)确定性。算法中的每个步骤都应是确定的,不允许有歧义。
(3)可行性。算法中规定的每个操作都是计算机可以执行的操作。
(4) 0或多个输入。算法可以无输入,也可以在程序运行时由用户通过输入设备(如键盘)将需要使用到的一组数据输入到计算机中。
(5) 1或多个输出。算法的实现以得到处理结果为目的,没有输出的算法是没有任何意义的。1.2.2算法的描述
进行算法设计时,可以使用不同的算法描述工具,如自然语言、流程图、伪代码、计算机语言等。
1.自然语言
自然语言就是人们日常生活中使用的语言。自然语言比较符合人们日常的思维习惯,通俗易懂,初学者容易掌握。但其描述文字显得冗长,表达时容易出现疏漏,并引起理解上的歧义,不易直接转化为程序。
2.流程图
流程图是一种流传很广的描述算法的方法。这种以特定的图形符号加上说明来描述算法的图,称为流程图。
1)传统的流程图
传统的流程图由一些图框和流程线组成。其中:图框表示各种操作的类型,图框中的文字和符号表示操作的内容,文字可以用中文、英文,也可以用数学上的写法,还可以用计算机命令,但要简洁、明了、易懂,决不能有二义性;流程线表示操作的先后次序、流程走向。常用的符号及其功能如图1-15所示。图1-15常用的流程图符号
【例1-7】
画出火车站托运行李按重量w计算费用f的算法流程图,收费标准如下:图1-16例1-7的传统流程图
2) N-S流程图
传统流程图中灵活的流程线是程序中隐藏问题的祸根。针对这一弊病,美国学者I.Nassi和B.Shneiderman提出了一种新的流程图形式,称为N-S流程图。这种流程图完全去掉了流程线,算法的每一步都用一个矩形框来描述,将一个个矩形框按执行的次序连接起来就是一个完整的算法描述。
例1-7的N-S流程图如图1-17所示。图1-17例1-7的N-S流程图
3.伪代码
伪代码是介于自然语言和计算机语言之间的一种伪码,它不受计算机语言严格语法的限制,描述算法灵活方便,易于转化为计算机程序。
4.计算机语言
用计算机语言描述算法就是计算机程序,在计算机上执行就可得到结果。1.2.3常用算法举例
有了正确算法,方能使用计算机编程语言进行程序设计。因此我们在此处先掌握一些最基础的算法,了解程序设计基本思路,为后续学习编写程序打下基础。
无论算法有多复杂,其基本结构只有三种:顺序结构、选择结构、循环结构。
1.顺序结构
顺序结构的程序算法描述最为简单,只要按照解决问题的顺序写出步骤即可,算法步骤执行次序为自上而下,依次执行。例1-1和例1-2均为顺序结构。例1-2的算法描述如图1-18所示。图1-18例1-2的流程图
2.选择结构
选择结构对给定的条件进行判断,根据判断的结果来控制程序的流程。例1-7为选择结构。
【例1-8】
输入两个数给变量a和b,输出较大的数值。
算法描述如图1-19所示。
可用不同的算法解决同一问题。如例1-8的算法还可以用图1-20来描述。图1-19例1-8的流程图1图1-20例1-8的流程图2
3.循环结构
【例1-9】
求s=1 + 2 + 3 + 4 + … + 100。
按照人可以理解的自然语言方式描述算法如下:
(1) 1 + 2 + 3 + 4 + … + 100→s;
(2)输出s,结束。
虽然人可以理解步骤(1)中“…”的含义,但计算机是不能理解的,违反了算法的确定性原则,无法转化为计算机程序。
考虑到一个步骤中将算式全部写出不现实,将其拆分成若干步,描述如下:
(1) s=0;
(2) s+1→s;
(3) s+2→s;
(4) s+3→s;
…
(101) s+100→s;
(102)输出s,结束。
这样描述每一步骤简练,但步骤太多,同样其中的“…”不能省略。
因此,我们需要考虑的是有没有方法能够自动地完成上面的步骤(2)~步骤(101)。仔细观察步骤(2)~步骤(101)可以发现,这100个步骤的内容非常相似,只是加入到s中的数值从1变化到了100。是否可以只写1个步骤,同时想办法让它重复执行100次呢?重复执行某些步骤的结构就是循环结构。上述算法改写为循环算法如下:
(1) s=0,i=1;
(2) s+i→s,i+1→i;
(3) i≤100转步骤(2),否则转下一步;
(4)输出s,结束。
上面的算法描述只需要4个步骤,但实际上步骤(2)会在步骤(3)的控制下重复100次,这便是循环结构,即描述一遍,执行若干遍。该算法可用如图1-21所示的流程图来描述。图1-21例1-9的流程图1.2.4算法拓展
【例1-10】
输入三个数给变量a、b、c,输出最大的数值。
按照例1-8的第一种算法思路求解本题,该算法可用如图1-22所示的流程图来描述。图1-22例1-10的流程图1
按照例1-8的第二种算法思路求解本题,该算法可用如图1-23所示的流程图来描述。
对比图1-22及图1-23两种算法,都可以求解问题,但第二种算法更简单,且可以拓展到4个数、5个数、…、n个数,当然若数较多,可使用循环结构。图1-23例1-10的流程图2图1-24例1-11的流程图
【例1-11】
输入10个数,输出最大的数值。
继续按照例1-10的第二种算法思路求解本题,但由于是10个数,要重复比较9次,因此使用循环结构。该算法可用如图1-24所示的流程图来描述。
【例1-12】
设我国2010年的人口是13亿,若放开计划生育,按5%的年增长率,哪一年达到20亿?
我们应逐渐适应计算机程序求解问题的思路。计算机求解该题的思路是使用循环结构重复计算,即图1-25例1-12的流程图
这个算法循环的次数我们无需知道,s每一年(即每循环一次)都在增加,必然会超出20,s超出20则停止循环,此时的y值即问题的答案。 1.3程序中的数据
1.3.1变量与常量
1.标识符命名规则
在程序中有许多需要命名的对象,如变量、符号常量、函数、自定义类型等,为这些对象所取的名称称为标识符。每种程序设计语言都规定了自己的标识符的命名规则。
C语言标识符的命名规则如下:
(1)只能由字母、数字和下划线三种字符组成;
(2)第一个字符只能为英文字母或下划线“_”;
(3)标识符不允许与关键字重名。
例如,下面是合法的标识符:
abcdx12345m_n_op_123for
以下是非法的标识符:
3dmax123a+bx.y-123for
还需注意的是:
(1)要考虑标识符的有效长度。标识符的最大长度根据每个C编译系统规定有所不同,但组成标识符的字符个数不要太多,一般不要超过32个。
(2)要考虑标识符的易读性。标识符在命名时尽量做到“望名见义”,方能达到提高易读性的目的。如代表总和的变量名用s或sum,代表平均分的变量名用aver,代表年份的变量名用y或year等。
2.变量
计算机程序中的变量用于保存数据,对应计算机硬件内存储器的一个或者多个存储单元。在程序运行过程中,变量的值可以被改变。
1)变量三要素
变量具有三要素:名称、类型和值。变量的名称用来区分并引用不同的变量;变量的类型表明变量用来存放什么类型的数据;在变量的存储单元中存放的数据称为变量的值。
2)变量定义
C语言中的变量遵循“先定义,后使用”的原则,即必须先对将要使用的变量进行变量定义才能使用该变量。
变量定义的一般形式如下:
类型说明符
变量名1[,变量名2,…];
其中,方括号内的内容为可选项。
例如:
inta,b; /*定义a、b为整型变量*/
floatx,y;
/*定义x、y为实型变量*/
charc; /*定义c为字符型变量*/
定义变量时应注意:
(1)变量定义必须在变量使用之前进行,一般放在函数体的声明部分。
(2)允许同时定义同一数据类型的多个变量,各变量名之间用逗号分隔。
(3)最后一个变量名之后必须以“;”号结束。
(4)类型说明符与变量名之间至少要用一个空格分隔。
4)对变量的基本操作
变量一旦定义后,就可以通过引用变量来进行赋值、取值等操作。所谓引用变量,就是使用变量名来引用变量的内存空间。由于变量是内存空间的一个标识,因此对变量的操作也就是对其内存空间的操作。
有两个对变量的基本操作:一是向变量中存入数据,这个操作被称为给变量赋值,变量中的旧值将被替换为赋予的新值;二是取得变量当前的值,以便在程序运行过程中使用,这个操作被称为“取值”,取值操作不会改变变量中的值。例如:
inta,b; /*定义a、b为整型变量*/
a=3; /*给a赋值*/
b=a; /*取a值并赋值给b*/
其中,“=”是赋值运算符。“a=3;”是对变量的赋值操作,即将运算符“=”右侧的数据3存储到左侧变量a的内存空间中(赋值操作)。而“b=a;”包括两个过程:先获取a的内存空间中存储的值3(取值操作),然后将该值3存储到b的内存空间中(赋值操作)。其操作过程可用图1-26来表示。图1-26变量赋值、取值操作
3.常量
常量是在程序运行过程中值保持固定不变的数据。
1)常量
在C程序中,为了能给变量直接赋初值或用数据参与运算,经常需要使用数值、字符、字符串等。这些数据通常能直接从字面形式判别其类型,称为字面常量,或称为直接常量。如1、-3、0为整数,1.2、-3.6为实数,'a'、'B'为字符,"China"为字符串等。
2)符号常量
在C语言中还可为常量命名,称为符号常量。符号常量跟变量一样必须遵循“先定义,后使用”的原则,常量命名遵循标识符命名规则。
C语言中定义符号常量的一般形式如下:
#define符号常量名
常量
其中“#define”是宏定义命令的专用定义符,在后面单元中将讲到。例如:
#definePI3.14159
#defineMAX100
以上定义符号常量PI为常数3.14159,符号常量MAX为常数100,在该程序中但凡出现“PI”之处,就以数值3.14159替换,但凡出现“MAX”之处,就以数值100替换。
需要注意的是,符号常量仍是常量,不允许改变符号常量的值,企图对符号常量进行赋值的操作是不合法的。
符号常量名一般采用大写字母,而变量名采用小写字母。1.3.2基本数据类型
为了能将程序中指定的数据精确地用相应的内存单元来存储和操作,C语言内部预定义了一些数据类型,这些类型称为基本数据类型,其名称是预定义的关键字。同时,为了在程序中能直接访问内存单元,C语言还提供了指针类型。除此之外,C语言还允许用户根据基本数据类型和指针类型构造出更为复杂的数据类型,如数组、结构体、共用体等用于多个或多项数据的描述。C语言中的数据类型可分为基本类型、构造类型、指针类型和空类型四类,如图1-27所示。图1-27C语言的数据类型
1.整数类型
1)数据类型
C语言的整数类型有6种。其中,有符号类型3种:基本整型(int)、短整型(short或shortint)、长整型(long或longint);无符号类型3种:无符号基本整型(unsigned或unsignedint)、无符号短整型(unsignedshort或unsignedshortint)、无符号长整型(unsignedlong或unsignedlongint)。
short、int、long的存储空间大小不同,如图1-28所示。需要注意的是,ANSIC的int类型整数在计算机中是用2字节的连续内存单元来存储的,但是VisualC++6.0所支持的int为4字节。由于本书的开发环境为VisualC++6.0,因此本书中的int及unsignedint类型是按照4字节存储的形式讲解的。个别例题有可能在不同的编译系统中,由于int及unsignedint类型存储为2或4字节的不同而导致得到不同的运行结果。图1-28不同整型的存储空间大小
2)整型常量
(1)整型常量的表示方法。
整型常量就是整数,在C语言中,整数可用十进制、八进制和十六进制三种形式表示。
①十进制形式。十进制形式整数,其数码为0~9,数值前可以有+、-符号。注意,十进制整数的数值前面不允许加0,如0123不是十进制整数。
以下各数是合法的十进制整型常量:
135
-246 67890
以下各数不是合法的十进制整型常量:
3. 0396 26D
②八进制形式。八进制形式整数,其数码为0~7,必须以0开头,即以0作为八进制数的前缀。
以下各数是合法的八进制整型常量:
011 0102 0177777
以下各数不是合法的八进制整型常量:
123
0129
③十六进制形式。十六进制形式整数,其数码为0~9及A~F或a~f,必须以0x或0X开头,即以0x或0X作为十六进制数的前缀。
以下各数是合法的十六进制整型常量:
0x11
0XA9 0xabcd
以下各数不是合法的十六进制整型常量:
23AB 0x5H
(2)整型常量的类型。
整型常量也有其类型,具体判别方法如下:
①如不特别指明,一个整型常量被认为是int类型。
②如果一个整型常量加后缀L或l,则被认为是long类型,如123L、-78l。
③如果一个整型常量加后缀U或u,则被认为是unsigned类型,如3U、-1u。-1u被理解为无符号数,即4294967295。
3)整型变量
使用整型的六种类型说明符之一对变量进行定义后,就可以使用整型变量了。
【例1-13】
整型变量的定义与使用。图1-29例1-13程序运行结果
2.实数类型
由于计算机中的实型数据是以浮点形式表示的,即小数点的位置可以是浮动的,因此实型数据也称为浮点型数据。
1)数据类型
C语言的实数类型有三种:单精度实型(float)、双精度实型(double)、长双精度实型(longdouble)。但由于longdouble类型在不同的编译系统中存储字节数不同,有的是8字节,有的是10、12或16字节,且该类型使用不多,因此不展开讲解。
float、double、longdouble类型数据的存储空间大小不同,如图1-30所示。图1-30不同实型的存储空间大小
有效数字是指数据在计算机中存储时能够精确表示的数字位数。实型数据的存储形式决定了能提供的有效位数有限,有效数字位数以外的数字是不准确的,因此实型数据的表示可能存在误差。
(2)实型常量的类型。
实型常量的类型判别方法如下:
①如不特别指明,一个实型常量被认为是double类型。
②如果一个实型常量加后缀F或f,则被认为是float类型,如12.56F、2.1e5f。
3)实型变量
使用实型的三种类型说明符之一对变量进行定义后,就可以使用实型变量了。
程序运行结果如图1-31所示。注意本例的输出结果出现误差,并非预期的8888.888880的结果,这是因为单精度实型数据的有效数字位数只有6~7位。图1-31例1-14程序运行结果
3.字符类型
计算机处理的数据不仅有整数、实数,还包括字符这样的非数值数据。在C语言中字符数据包括字符和字符串两种。
1)数据类型
C语言的字符类型关键字为char,所占存储空间为1字节。字符型数据在计算机中存储,是字符的ASCII码值的二进制形式。
2)字符常量
C语言中有两种形式的字符常量:普通字符和转义字符。
(1)普通字符:用单引号括起来的单个字符,如‘a’、‘Y’、‘@’、‘5’。
(2)转义字符:以“\”开头的具有特殊含义的字符。转义字符有其特定的含义,不同于字符原本的含义,故称其为“转义”字符。常用的转义字符及其含义见表1-3。图1-32例1-15程序运行结果
3)字符型变量
使用类型说明符char对变量进行定义后,就可以使用字符型变量了。
由于字符型变量在内存中存放的是字符的ASCII码值,因此也可以把它们看成是整型量。字符型数据与整型数据之间的转换比较方便。字符数据可以参与算术运算,也可以与整型量相互赋值,还可以按照整数形式输出。图1-33例1-16程序运行结果
字符
‘a’
的ASCII值为97,字符
‘A’
的ASCII值为65。变量的输出形式取决于printf函数格式控制字符串中的格式符:当格式符为“%c”时,输出的形式为字符;当格式符为“%d”时,输出的形式为整数。
【例1-17】
大小写字母的转换。
#include<stdio.h>
main()
{ charc1,c2;
c1='a'; c2='B';
c1=c1-32; c2=c2+32;
printf("%c,%c\n",c1,c2);
}
图1-34例1-17程序运行结果
4.字符串常量
C语言中的字符串常量是由一对双引号括起的字符序列。以下字符串均为合法的字符串常量:
“Howareyou”“12345”“x”“”(空串)
字符串中字符的个数称为字符串的长度,以上4个字符串的长度分别为11、5、1、0。
字符串在计算机中存储,是将一个个字符按顺序放在连续的存储单元中,每一个字符占1字节存储单元保存其ASCII码值,最后还要额外使用1字节存储单元保存字符串结束符'\0'。因此,长度为n的字符串需要n+1字节的存储单元保存。上面的4个字符串在内存中所占的字节数分别为12、6、2、1。【例1-18】
字符串的长度及在内存中所占字节数。
#include<stdio.h>
#include<string.h>
main()
{ printf("%d\n",strlen("Hello"));
printf("%d\n",sizeof("Hello"));
printf("%d\n",strlen("ab\nc\103de"));
printf("%d\n",sizeof("ab\nc\103de"));
}
图1-35例1-18程序运行结果1.3.3知识拓展——数据的表示方法
1.内存单元的概念
为了便于内存管理,通常将8位(bit)组成一个基本的内存单元,称为1字节(Byte)。为了便于内存单元的访问,计算机系统还为每一个内存单元分配了一个相对固定的编码,该编码就是内存单元的地址。
2.原码、反码和补码
在计算机内部,所有的信息要用二进制来表示,二进制表示的数值称为机器数。不考虑正、负的机器数称为无符号数,考虑正、负的机器数称为有符号数。为了在计算机中正确地表示有符号数,通常规定最高位为符号位,并用0表示正,用1表示负,余下各位表示数值。整数常用的表示方式有原码、反码、补码。
1)原码
原码表示法在数值前面增加了一位符号位,即最高位为符号位:正数的该位为0,负数的该位为1(0有两种表示:+0和-0),其余位表示数值的大小。如数值11的原码为00001011,-11的原码为10001011。
原码的符号位不能直接参与运算,必须和其他位分开,这就增加了硬件的开销和复杂性。
2)反码
反码表示法规定:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。如数值11的反码为00001011,-11的反码为11110100。
3)补码
补码表示法规定:正数的补码与其原码相同;负数的补码是在其反码的末位加1。如数值11的补码为00001011,-11的补码为11110101。
对于整数来说,在计算机内部都是用补码来存储的。
(1)用补码理解整数类型的表示范围。
1字节(8位)存储单元存储二进制数补码的有符号数范围是:
00000000~01111111~10000000~11111111
0127-128-1
-128~127即-27~27-1。
2字节(16位)存储单元存储二进制数补码的有符号数范围是-32 768~32 767,即-215~215-1。4字节的有符号数范围则是-231~231-1。
1字节(8位)存储单元存储二进制数补码的无符号数范围是00000000~11111111,最高位的0或1不再是符号位而是数值部分,则数据范围为0~255,即0~28-1。
2字节存储单元存储二进制数补码的无符号数范围是0~65 535,即0~216-1。4字节的无符号数范围则是0~232-1。(2)用补码理解有符号数、无符号数的转换。
【例1-19】
有符号数、无符号数的转换。
#include<stdio.h>
main()
{ unsignedshorta;
a=-1;
printf(“%u\n”,a);
}
程序运行结果如图1-36所示。图1-36例1-19程序运行结果
例1-19中变量a为unsignedshort类型,是用2字节存储的无符号数。-1的补码为1111111111111111,赋值给a时,由于a是无符号数,最高位的1不是符号位而表示数值215。1111111111111111=215+214+…+21+20=216-1=65535。
3.字符数据的表示
计算机中的字符数据也需用二进制编码才能在计算机中存储、传输并进行处理,即字符编码。英文字符包括数字、字母、符号、控制符号等。目前广泛采用美国标准信息交换编码(AmericanStandardCodeInformationInterchange,ASCII)作为英文字符的编码标准,该编码已被国际标准化组织ISO采用,成为一种国际通用的信息交换用标准代码。附录B中列出了ASCII码字符集。
1.4常用表达式和运算符
1.4.1表达式、运算符概述
1.表达式
表达式是由运算对象(操作数)、运算符(操作符)按照C语言的语法规则构成的符号序列。表达式可以通过运算产生一个结果或完成某种操作。正是由于C语言具有丰富的多种类型的表达式,才得以体现出C语言所具有的表达能力强、使用灵活、适应性好的特点。
2.运算符
C语言的运算符很丰富,运算符是C语言用于描述对数据进行运算的符号。
运算符可按其运算对象的个数分为3类:单目运算符、双目运算符、三目运算符。
运算符还可以按其功能分为算术运算符、关系运算符、条件运算符、逻辑运算符、赋值运算符、逗号运算符、位运算符及其他运算符等。
3.优先级和结合性
当一个表达式中出现多种不同的运算符时,如何进行运算?这涉及运算符的两个重要概念,即优先级和结合性(又称结合方向)。
优先级指不同运算符进行运算时的优先次序。C语言规定了各个运算符的优先等级,用数值来反映优先等级的高低,数值越小,优先级越高。在同一表达式中出现不同运算符时,优先级较高的运算符将优先进行运算,如数学中四则运算的“先乘除后加减”。C语言中,通常所有单目运算符的优先级高于双目运算符的优先级。()、[]、->、· 的优先级最高,而逗号运算符的优先级最低。
结合性是指同一表达式中相同优先级的多个运算是自左向右还是自右向左进行运算,如数学中的四则运算就是自左向右运算。通常,在C语言中,单目运算符的结合方向是自右向左;双目运算符的结合方向大部分是自左向右,只有赋值和复合赋值运算符的结合方向是自右向左;三目运算符的结合方向是自右向左。
关于C语言运算符的含义、类型、优先级、结合性等问题见附录C。
1.4.2算术运算符及表达式
数值的算术运算是程序中常见的。C语言中的算术运算符只能实现四则运算等基本功能,没有乘方、开方等运算符,这些功能是通过头文件“math.h”中定义的数学函数来实现的(详见附录D)。
1.算术运算符
1)单目算术运算符
(1) +:正号运算符,优先级2级,具有右结合性,如+3,+1.25。
(2) -:负号运算符,优先级2级,具有右结合性,如-a。
2)双目算术运算符
(1) *:乘法运算符,优先级3级,具有左结合性,如3*2,a*b。
(2) /:除法运算符,优先级3级,具有左结合性,如5 / 2,a/b。
(3) %:求余运算符,优先级3级,具有左结合性,注意要求%两侧运算对象均为整型数据。求余运算结果的符号与被除数(左操作数)的符号相同。
求余运算符也称为求模运算符,它最常用的功能如下:
①用a%b是否等于0判断a是否能被b整除。
②用x%10截取x的个位数,用x%100截取x的低2位数等。
(4) + :加法运算符,优先级4级,具有左结合性。
(5) - :减法运算符,优先级4级,具有左结合性。
2.算术表达式
算术表达式是用算术运算符和括号将运算对象连接起来的、符合C语言语法规则的式子。
使用算术表达式时应注意以下几点:
(1)操作数类型自动转换。
①双目算术运算对象的数据类型一致。运算对象的数据类型一致时,运算结果的类型也将一致(char、short类型除外)。如当运算对象均为整数时,运算结果也为整数,故5 / 2的结果是2。
②双目算术运算对象的数据类型不一致。若运算对象的数据类型不一致,系统自动按规律先将运算对象转换为同一类型,然后再进行运算。C语言编译器会自动将低类型的操作数向高类型进行转换,称为类型的自动转换。转换的规则如图1-37所示。图1-37标准类型数据参与算术运算的转换规则
图中:横向箭头表示必须的转换,如两个char类型数据参与算术运算,尽管类型相同,但两者仍要先转换为int类型再进行算术运算,运算结果也为int类型。纵向箭头表示当算术运算符两侧的运算对象为不同类型时的转换方向,如一个double型数据与一个int型数据一起运算,需要由低向高先将int型数据转换为double型,然后再进行运算,运算结果为double型。这些转换由系统自动进行,使用时只需要了解这种转换、知道结果的类型即可。
注意:在VisualC++6.0中,float类型数据无需转换为double类型即可参与算术运算。
(2)代数式与表达式。
为了能让C程序进行数值计算,还必须将代数式写成C语言合法的表达式。例如,若有代数式:
②适当加上圆括号。使用圆括号可以改变表达式的运算顺序,还应有意识地加上一些圆括号来增强程序可读性,多层括号均使用圆括号“()”,注意左右括号必须成对出现。事实上,()也是运算符,它的优先级最高,所以先求解括号内的子表达式。
③数据类型。由于算术表达式运算时操作数的数据类型对结果的数据类型是有影响的,因此在书写表达式时要注意。如:
若将表达式写成1/2*a*b*c,则无论a、b、c的值是多少,表达式的结果均为0。这是因为按照算术表达式的运算规则,首先计算1/2,其结果为0,再乘以其他数据结果也必然为0了。为了保证计算结果的正确性,应尽可能将操作数的类型写成表达式中的最高类型,即上述表达式应写成1.0/2.0*a*b*c。图1-38例1-20程序运行结果
例1-20中,表达式i/100可截取变量i百位以上的数据,结果为2;表达式i%10可获取i个位上的数值,结果为6;表达式i/10%10先截取变量i十位以上的数据25,再由%10获取个位上的数值,结果为5;a、b、c分别获取了i (变量i当前的数值为一个3位数256)的百、十、个位数。
表达式9/2*f1,先计算9/2,结果为4,4*f1为8.0,故f2的值为8.0。1.4.3赋值运算符及表达式
赋值运算符用来构成赋值表达式给变量进行赋值操作。
1.普通赋值运算符及表达式
1)赋值运算符
赋值运算符用赋值符号“=”表示,其功能为将赋值运算符右侧的数据赋给赋值运算符左侧的变量。
赋值运算符的优先级很低,仅高于逗号运算符,具有右结合性。
2)赋值表达式
由赋值运算符将一个变量和一个表达式连接起来的表达
式称做赋值表达式。它的一般形式如下:
变量名=表达式
赋值表达式将赋值运算符右侧的表达式的运算结果赋给赋值运算符左侧的变量。注意:赋值表达式中,赋值运算符的左侧必须是变量。图1-39例1-21程序运行结果
例1-21中,表达式a=b=8是合法的,在表达式中出现了2个赋值运算符,优先级相同,由于赋值运算符具有右结合性,因此先求解子表达式b=8,b赋值为8,然后再求解子表达式a=b,a赋值为8。
3)赋值表达式的类型转换
当赋值运算符两侧运算对象的数据类型不同时,系统也将进行自动类型转换,但该自动转换的规则不同于算术运算的由低向高的转换规则。
赋值运算的类型转换规则为:将赋值运算符右侧表达式的类型转换为左侧变量的类型。因为左侧的变量一经定义,其数据类型不再改变,当中存放的数据自然是此数据类型。
2.复合赋值运算符及表达式
1)复合赋值运算符
C语言还允许赋值运算符“=”与算术运算符和位运算符联合使用,构成复合赋值运算符,使得表达式更加精练。
复合赋值运算符有:
+=、-=、*=、/=、%=、|=、&=、^=、<<=、>>=
所有赋值运算符的优先级全部相同,为14级,均具右结合性。2)复合赋值表达式
复合赋值表达式的一般形式如下:
变量名
复合赋值运算符
表达式
复合赋值表达式的作用等价于:
变量名=变量名运算符(表达式)
图1-40例1-22程序运行结果1.4.4自增、自减运算符及表达式
自增、自减运算符为变量加1、减1提供了简单有效的方法。
1.一般使用方法
(1) ++:自增运算符,使变量的值增加1。
(2) --:自减运算符,使变量的值减少1。
两者均为单目运算符,优先级2级,具有右结合性。
当自增表达式单独形成语句使用时,无论是其前置运算形式“++变量”,还是其后置运算形式“变量++”,都是仅对变量自增1,两种形式没有区别。自减表达式亦然。图1-41例1-23程序运行结果
2.前置、后置运算应用于表达式的区别
自增、自减的前置、后置表达式单独使用时是没有区别的,但当它们作为子表达式出现在其他表达式内部时就有着明显的区别。
1)前置运算
前置运算:将 ++ 或 -- 运算符置于变量之前,一般形式如下:
++变量
--变量
其功能是使变量的值增、减1,然后再以变化后的变量值参与表达式中的其他运算,即先增减、后运算。
2)后置运算
后置运算:将 ++ 或 -- 运算符置于变量之后,一般形式如下:
变量++
变量--
其功能是变量先参与表达式中的其他运算,然后再使变量的值增、减1,即先运算、后增减。图1-42例1-24程序运行结果
3.关于自增、自减运算符及表达式的说明
(1)自增、自减运算符实际上也是做赋值运算,因此不能应用于常量和表达式,其操作对象只能是变量。如6--、(a+3)++是非法的表达式。
(2)一般自增、自减表达式或是以表达式语句的形式出现,或是出现在for循环语句中使循环控制变量加、减1,或应用于指针变量,使指针指向下、上一个地址。将自增、自减表达式应用于另一个表达式内部的形式,初学者在尚未熟练掌握时尽量不要使用。
(3)尽量不要使用诸如i+++j、(i++)+(i++)此类容易产生歧义的形式。1.4.5逗号运算符及表达式
逗号运算符“,”用于将多个表达式连接起来,构成一个逗号表达式。逗号运算符又称顺序求值运算符。
逗号运算符为双目运算符,其优先级是C中所有运算符中最低的,为15级,具有左结合性。
逗号运算符可以扩展为n元运算的形式:
表达式1,表达式2,…
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度许可合同:危险物品运输与储存3篇
- 2024年合作伙伴代理业务合同一
- 2024年度核能利用与技术服务全面合同
- 2024年度城市公共自行车系统建设合同
- 2024年度物业服务合同管理与维修责任
- 2024版城市更新项目弃土堆放地租用合同2篇
- 二零二四年度版权转让合同的标的及转让条件2篇
- 2024年学校退学条款详细合同版
- 2024年合同法变动:单方终止合同的合法性2篇
- 二零二四年度物业管理合同规定物业范围与管理服务内容3篇
- 淋巴管炎的护理查房课件
- 十八项医疗核心制度培训课件
- 关于身体、心理、行为异常学生排查工作致家长的一封信
- 互联网信息审核员考试题库大全-上(单选题汇总)
- 教科版三年级综合实践活动上册全册教案
- 广东检测鉴定协会非金属考试试题
- 深圳市幼儿园课程建设指导意见
- 外科学:肝脏疾病完整版
- 某露营基地项目建议策划方案(PPT45张)
- 2023建筑设计防火规范讲解大全
- 标准日本语第23课课件
评论
0/150
提交评论