程序设计语言的基本成分包括数据、运算、控制和传输等。
1、程序设计语言的数据成分
程序设计语言的数据成分指一种程序设计语言的数据类型。数据对象总是对应着应用系统中某些有意义的东西,数据表示则指明了程序中值的组织形式。数据类型用于代表数据对象,还用于在基础机器中完成对值的布局,同时还可用于检查表达式中对运算的应用是否正确。
数据是程序操作的对象,具有存储类别、类型、名称、作用域和生存期等属性,在使用时要为它分配内存空间。数据名称由用户通过标识符命名,标识符是由字母、数字和下划线"_"组成的标记;类型说明数据占用内存的大小和存放形式;存储类别说明数据在内存中的位置和生存期;作用域则说明可以使用数据的代码范围;生存期说明数据占用内存的时间特点。从不同角度可将数据进行不同的划分。
1)常量和变量
按照程序运行时数据的值能否改变,将数据分为常量和变量。程序中的数据对象可以具有左值和(或)右值,左值指存储单元(或地址、容器),右值是值(或内容)。变量具有左值和右值,在程序运行过程中其右值可以改变;常量只有右值,在程序运行过程中其右值不能改变。
2)全局量和局部量
数据按在程序代码中的作用范围(作用域)可分为全局量和局部量。一般情况下,全局变量的作用域为整个文件或程序,系统为全局变量分配的存储空间在程序运行的过程中是不改变的,局部变量的作用域为定义它的函数或语句块,为局部变量分配的存储单元是动态改变的。
3)数据类型
按照数据组织形式的不同可将数据分为基本类型、用户定义类型、构造类型及其他类型。C(C++)的数据类型如下。
(1)基本类型:整型(int)、字符型(char)、实型(float、double)和布尔类型(bool)。
(2)特殊类型:空类型(void)。
(3)用户定义类型:枚举类型(enum)。
(4)构造类型:数组、结构、联合。
(5)指针类型:type*。
(6)抽象数据类型:类类型。
其中,布尔类型和类类型由C++语言提供。
2、程序设计语言的运算成分
程序设计语言的运算成分指明允许使用的运算符号及运算规则。大多数高级程序设计语言的基本运算可以分成算术运算、关系运算和逻辑运算等,有些语言(如 C、C++)还提供位运算。运算符号的使用与数据类型密切相关。为了明确运算结果,运算符号要规定优先级和结合性,必要时还要使用圆括号。
3、程序设计语言的控制成分
控制成分指明语言允许表述的控制结构,程序员使用控制成分来构造程序中的控制逻辑。理论上已经证明,可计算问题的程序都可以用顺序、选择和循环这3种控制结构来描述。
1)顺序结构
顺序结构用来表示一个计算操作序列。计算过程从所描述的第一个操作开始,按顺序依次执行后续的操作,直到序列的最后一个操作,如下图所示。在顺序结构内也可以包含其他控制结构。
2)选择结构
选择结构提供了在两种或多种分支中选择其中一个的逻辑。基本的选择结构是指定一个条件P,然后根据条件的成立与否决定控制流计算A还是计算B,从两个分支中选择一个执行,如下图所示。
选择结构中的计算A或计算B还可以包含顺序、选择和重复结构。程序设计语言中还通常提供简化了的选择结构,也就是没有计算B的分支结构,如下图所示。
3)循环结构
循环结构描述了重复计算的过程,通常由三部分组成:初始化、循环体和循环条件,其中初始化部分有时在控制的逻辑结构中不进行显式的表示。循环结构主要有两种形式:while型循环结构和do-while型循环结构。
while型结构的逻辑含义是先判断条件P,若成立,则执行循环体A,然后再去判断循环条件,否则控制流就退出重复结构,如下图所示。
do-while 型结构的逻辑含义是先执行循环体A,再判断条件P,若成则继续执行A,然后再判断条件P,否则控制流就退出循环结构,如下图所示。
4) C(C++)语言提供的控制语句
(1)复合语句。复合语句用于描述顺序控制结构。复合语句是一系列用"{“和”}"括起来的声明和语句,其主要作用是将多条语句组成一个可执行单元。在语法上能出现语句的地方都可以使用复合语句。复合语句是一个整体,要么全部执行,要么一条语句也不执行。
(2)if语句和switch语句。
①if语句实现的是双分支的选择结构,其一般形式为:
i
f
(表达式)语句
1
;
e
l
s
e
语句
2
;
if(表达式)语句1;else 语句2;
if(表达式)语句1;else语句2;
其中,语句1和语句2可以是任何合法的C(C++)语句,当语句2为空语句时,可以简化为:
i
f
(表达式)语句
1
;
if(表达式)语句1;
if(表达式)语句1;
在使用if语句时,需要注意if和else的匹配关系。C(C++)语言规定,else总是与离它最近的尚没有else的if相匹配。
② switch语句描述了多分支的选择结构,其一般形式为:
switch(表达式){
case 常量表达式1:语句 1;
case 常量表达式2:语句2;
…
case 常量表达式n:语句n;
default: 语句n+1;
}
在执行switch语句时,首先计算表达式的值,然后用所得的值与列举的常量表达式值依次比较,若任一常量表达式都不能与所得的值相匹配,则执行default的"语句序列n+1",然后结束switch语句。若表达式的值与常量表达式i(i=1,2,…,n)的值相同,则执行"语句序列i",当case i的语句序列i中无break语句时,执行随后的语句序列i+1,语句序列i+2,……直到执行完语句序列n+1后退出switch语句;或者遇到break时跳出switch语句。如果要使程序在执行"语句序列i"后结束整个switch语句,则语句序列i中应包含控制流能够到达的break语句。
表达式可以是任何类型的,常用的是字符型或整型表达式。多个常量表达式可以共用一个语句组。语句组可以包括任何可执行语句,且无须用"{“和”}"括起来。
(3)循环语句。C(C++)语言提供了3种形式的循环语句用于描述循环计算的控制结构。
① while语句。while语句描述了先判断条件再执行循环体的控制结构,其一般形式为:
w
h
i
l
e
(条件表达式)循环体语句;
while(条件表达式) 循环体语句;
while(条件表达式)循环体语句;
其中,循环体语句是内嵌的语句,当循环体语句多于一条时,应使用 “{” 和 “}” 括起来。在执行while语句时,先计算条件表达式的值,当值为非0时,执行循环体语句,然后重新计算条件表达式的值再进行判断,否则就结束while语句的执行过程。
② do-while 语句。do-while 语句描述了先执行循环体再判断条件的控制结构,其一般形式为:
do
循环体语句;
while(条件表达式);
do-while循环语句是先执行循环体语句,然后再计算条件表达式的值,若值为非0,则再一次执行循环体语句和计算条件表达式并进行判断,直到条件表达式的值为0时结束do-while 语句的执行过程。
③ for语句。for语句的基本形式为:
f
o
r
(表达式
1
;表达式
2
;表达式
3
)
循环体语句;
for(表达式1;表达式2;表达式3) 循环体语句;
for(表达式1;表达式2;表达式3)循环体语句;
可用while语句等价地表示为:
表达式1;
while(表达式2){
循环体语句;
表达式3;
}
for语句的使用是很灵活的,其内部的3个表达式都可以省略,但用于分隔3个表达式的分号 “;” 不能省略。
C语言中还提供了实现控制流跳转的goto、break和continue语句,由于goto会破坏程序的逻辑结构,因此不提倡使用。
4、程序设计语言的传输成分
程序设计语言的传输成分指明语言允许的数据传输方式,如赋值处理、数据的输入和输出等。
5、函数
C程序由一个或多个函数组成,每个函数都有一个名字,其中有且仅有一个名字为main 的函数作为程序运行时的起点。函数是程序模块的主要成分,它是一段具有独立功能的程序。函数的使用涉及3个概念:函数定义、函数声明和函数调用。
1)函数定义
函数的定义包括两部分:函数首部和函数体。函数的定义描述了函数做什么和怎么做。函数定义的一般形式为:
返回值的类型 函数名(形式参数表) //函数首部
{
函数体;
}
函数首部说明了函数返回值的数据类型、函数的名字和函数运行时所需的参数及类型。函数所实现的功能在函数体部分进行描述。
C(C++)程序中所有函数的定义都是独立的。在一个函数的定义中不允许定义另外一个函数,也就是不允许函数的嵌套定义。
2)函数声明
函数应该先声明后引用。如果程序中对一个函数的调用在该函数的定义之前进行,则应该在调用前对被调用函数进行声明。函数原型用于声明函数。函数声明的一般形式为:
返回值类型 函数名(参数类型表);
使用函数原型的目的在于告诉编译器传递给函数的参数个数、类型以及函数返回值的类型,参数表中仅需要依次列出函数定义时参数的类型,从而使编译器能够检查源程序中对函数的调用形式是否正确。
3)函数调用
当在一个函数(称为调用函数)中需要使用另一个函数(称为被调用函数)实现的功能时,便以名字进行调用,称为函数调用。在使用一个函数时,只要知道如何调用就可以了,并不需要关心被调用函数的内部实现。因此,调用函数需要知道被调用函数名字、返回值和需要向被调函数传递的参数(个数、类型、顺序)等信息。
函数调用的一般形式为:
函数名(实参表);
在C程序的执行过程中,通过函数调用实现了函数定义时描述的功能。在函数体中若调用自己,则称为递归调用。
C和C++通过传值方式将数据传递给形参。调用函数和被调用函数之间交换信息的方法主要有两种:一种是由被调用函数把返回值返回给主调函数,另一种是通过参数带回信息。函数调用时实参与形参间交换信息的方法有值调用和引用调用两种。
(1)值调用(Call by Value)。若实现函数调用时将实参的值传递给相应的形参,则称为是传值调用。在这种方式下形参不能向实参传递信息。
在C语言中,要实现被调用函数对实参的修改,必须用指针作为参数。即调用时需要先对实参进行取地址运算,然后将实参的地址传递给指针形参。其本质上仍属于值调用。这种方式实现了间接内存访问。
(2)引用调用(Call by Reference)。引用是C++中引入的概念,当形式参数为引用类型时,形参名实际上是实参的别名,函数中对形参的访问和修改实际上就是针对相应实参所做的访问和改变。例如:
void swap(int &x, int &y){/交换x和y*/
int temp;
temp=x; x=y; y=temp;
函数调用:swap(a,b);
在实现swap(a,b)调用时,x、y就是a、b的别名,因此,函数调用完成后,交换了a和b的值。