程序2-1: |
|
1.//simple.cpp是一个简单的C++程序 2.#include <iostream.h> 3.void main(void) 4.{ 5. int i; 6. cout<<"Hello C++!"; 7. cout<<"请输入一个整数:\n"; 8. cin>>i; 9. cout<<"您输入的整数是:"; 10. cout <<i; 11. cout <<'\n'; 12.}
|
|
我们对这个程序逐行加以解释: (1)第一行是C++语言的注释。其中,"//"是C++语言的一种注释符号,自"//"开始,一直到本行结束,所有内容都会被当作注释对待。C++注释也可以写成下面的形式: /*注释内容*/ 即夹在"/*"与"*/"号间的部分是要注释的内容,例如,本句可以改为: /*simple.cpp是一个简单的C++程序*/ 我们进行程序设计时,这两种注释形式都会经常用到。它们的区别在于:前者只能注释一行内容,而后者可以注释多行内容。它可以用在程序的任何地方,编译器在编译时将这些信息忽略,注释就是用来帮助阅读和理解程序的信息,也可使用注释来帮助用户调试程序。 (2)第2行使用预处理指令#include将头文件iostream.h包含到程序中来, iostream.h是标准的C++头文件,它包含了输入和输出的定义。 (3)第3行定义了一个称为main的函数。 ◇ 一个函数有0个或多个参数,它们出现在函数名后的一对圆括号中。 ◇ 括号中的void表示main没有参数。 ◇ 一个函数可以有一个返回类型,它在函数名的左边。 ◇ main函数左边的返回类型为void,表示没有返回值。 ◇ C++程序的执行总是从main函数开始的。 (4)第4行是一个花括号,是main函数体开始的标记。 (5)第5行是一个语句。 ◇ 一个语句可能是定义或声明一个变量,也可能是得到一个数值的计算步骤。 ◇ 一个语句用分号(;)结尾,C/C++用分号来分隔语句。 ◇ 这个语句定义了一个整型变量i。 ◇ 一个变量能够保存一种特定类型的数据,整型变量能够保存一个整型数据。 (6)第6行也是一个语句。 ◇ 这个语句将字符串"Hello C++!"发送到cout输出流。 ◇ 一个字符串是一个用双引号包围的字符系列。 (7)第7行也是一个语句。 ◇ 这个语句将字符串"请输入一个整数:"发送到cout输出流。 ◇ 字符串的最后一个字符(\n)是一个换行符。 ◇ 流是执行输入和输出的对象。 ◇ cout是C++标准的输出流,标准输出通常是指计算机屏幕。 ◇ 符号<<是一个输出运算符,带一个输出流作为它的左操作数,一个表达式作为它的右操作数。后者被发送到前者,字符串"请输入一个整数:\n"发送到cout的效果是把字符串打印到计算机屏幕上。 (8)第8行也是一个语句。 ◇ 这个语句将cin输入流抽取到变量i。 ◇ cin是C++标准的输入流,标准输入通常是指计算机键盘。 ◇ 符号>>是一个输入运算符,带一个输入流作为它的左操作数,一个变量作为它的右操作数。前者被抽取到后者,cin输入流抽取到变量i的效果是将键盘的输入值复制到变量i中。 (9)第9、10、11行分别是在屏幕上打印"您输入的整数是:"、变量i和和换行符。这三行实际上可以综合为一个语句: cout<<"您输入的整数是:" <<i <<'\n'; 它的效果与使用三个语句是一样的。 (10)第12行的花括号是main函数体结束的标记。 运用第一章介绍的知识,我们在Visual C++6的开发环境里,编译、连接、运行该程序,可以得到下面的提示: Hello C++!请输入一个整数: 假定我们输入整数5,即: 5↙ ↙表示键入了"ENTER"键(或称为回车键),则得到运行结果: 您输入的整数是:5 通过这个实例,我们对C++程序的结构、语句、变量、函数、预处理指令、输入和输出等,已有了一个初步的印象,在后面的章节中,我们还将作更详细的介绍。 由于我们定义main( )函数的返回类型为void,所以最后就不用返回值了。如果我们定义main的返回类型的int,则要返回一个整型值: int main() { … return 0; } 要注意的是C/C++是区分大小写的,不能随便更改,cout是C++标准的输出流,而Cout不是,如果没有预先定义,编译器就不认识这个Cout。大多数C++命令使用小写字母,大多数常量使用大写字母,而大多数变量是大小写混合使用。
|
|
表2-2 C++关键字 |
|
asm |
default |
float |
operator |
static_cast |
union |
auto |
delete |
for |
private |
struct |
unsigned |
bool |
do |
friend |
protected |
switch |
using |
break |
double |
goto |
public |
template |
virtual |
case |
dynamic_cast |
if |
register |
this |
void |
catch |
else |
inline |
reinterpret_cast |
throw |
volatile |
char |
enum |
int |
return |
true |
wchar_t |
class |
explicit |
long |
short |
try |
while |
const |
export |
mutable |
signed |
typedef |
. |
const_cast |
extern |
namespace |
sizeof |
typeid |
. . |
Continue |
false |
new |
static |
typename |
. . |
|
|
|
|
|
表2-3 基本的数据类型及其表示范围 |
|
类型名 |
类型 |
字节 |
表示范围 |
char |
字符型 |
1 |
-128 ~127 |
unsigned char |
无符号字符型 |
1 |
0 ~255 |
signed char |
有符号字符型(与字符型相同) |
1 |
-128 ~127 |
int |
整型 |
* |
与机器有关 |
unsigned int |
无符号整型 |
* |
与机器有关 |
signed int |
有符号整型(与整型相同) |
* |
与机器有关 |
short int |
短整型 |
2 |
-32,768~ 32,767 |
unsigned short int |
无符号短整型 |
2 |
0~65,535 |
signed short int |
有符号短整型(与短整型相同) |
2 |
-32,768~ 32,767 |
long int |
长整型 |
4 |
-2,147,483,648 ~2,147,483,647 |
signed long int |
有符号长整型(与长整型相同) |
4 |
-2,147,483,648 ~ 2,147,483,647 |
unsigned long int |
无符号长整型 |
4 |
0~4,294,967,295 |
float |
浮点型 |
4 |
3.4E +/- 38 (7位有效数字) |
double |
双精度型 |
8 |
1.7E +/- 308 (15位有效数字) |
long double |
长双精度型 |
10 |
1.2E +/- 4932 (19位有效数字)
|
|
|
|
如果一个双目运算符两边的操作数类型不同,先要将它们转换为相同的类型,即较低类型转换为较高类型,然后再参加运算。所谓类型的高低,跟所占的存储空间大小有直接关系,所占存储空间越大的类型,级别越高。 图中横向的箭头表示必须的转换,如两个float型数参加运算,虽然它们类型相同,但仍要先转换成double型再进行运算,结果亦为double型。纵向箭头表示当运算符两边的操作数为不同类型时的转换,如一个long型数据与一个int型数据一起运算,需要先将int型数据转换为long型,然后两者再进行运算,结果为long型。所有这些转换都是由系统自动进行的,使用时只需了解结果的类型即可。
|
|
程序2-2 |
|
#include <iostream.h> void main(void) { char a = 'x'; int b = 3,f = 2; float c = 2.5678; double d = 5.2345 long e = 32L; cout<<a - b + d / c - e * f<<endl; } |
|
下面我们来分析一下这段程序: (1) 进行d / c运算时,要将c转换成double型,运算的中间结果为double型; (2) 进行e * f运算时,将f转换为long型,运算的中间结果为long型; (3) 进行a - b运算时,将a转换为int型(数值为ASCⅡ码值120),运算的中间结果为int型; (4) 当(3)的中间结果与(1)的中间结果运算时,将(3)的中间结果转换为double型,运算的中间结果为double型; (5) 当(4)的中间结果与(2)的中间结果运算时,将(2)的中间结果转换为double型,得出最后结果。 于是,程序最后的运行结果为55.038515。
|
|
表2-4 |
|
从 |
到 |
方法 |
char |
short |
符号位扩展 |
char |
long |
符号位扩展 |
char |
unsigned char |
最高位失去符号位意义,变为数据位 |
char |
unsigned short |
符号位扩展到short;然后从short转到 unsigned short |
char |
unsigned long |
符号位扩展到long; 然后从long 转到unsigned long |
char |
float |
符号位扩展到long; 然后从long 转到float |
char |
double |
符号位扩展到long; 然后从long 转到double |
char |
long double |
符号位扩展到long; 然后从long 转到long double |
short |
char |
保留低位字节 |
short |
long |
符号位扩展 |
short |
unsigned char |
保留低位字节 |
short |
unsigned short |
最高位失去符号位意义,变为数据位 |
short |
unsigned long |
符号位扩展到long; 然后从long转到unsigned double |
short |
float |
符号位扩展到long; 然后从long 转到float |
short |
double |
符号位扩展到long; 然后从long 转到double |
short |
long double |
符号位扩展到long; 然后从long 转到double |
long |
char |
保留低位字节 |
long |
short |
保留低位字节 |
long |
unsigned char |
保留低位字节 |
long |
unsigned short |
保留低位字节 |
long |
unsigned long |
最高位失去符号位意义,变为数据位 |
long |
Float |
使用单精度浮点数表示。可能丢失精度。 |
long |
double |
使用双精度浮点数表示。可能丢失精度。 |
long |
long double |
使用双精度浮点数表示。可能丢失精度。 |
|
|
|
|
表2-5 |
|
从 |
到 |
方法 |
unsigned char |
char |
最高位作为符号位 |
unsigned char |
short |
0扩展 |
unsigned char |
long |
0扩展 |
unsigned char |
unsigned short |
0扩展 |
unsigned char |
unsigned long |
0扩展 |
unsigned char |
float |
转换到long; 再从 long 转换到float |
unsigned char |
double |
转换到long; 再从 long 转换到double |
unsigned char |
long double |
转换到long; 再从 long 转换到double |
unsigned short |
char |
保留低位字节 |
unsigned short |
short |
最高位作为符号位 |
unsigned short |
long |
0扩展 |
unsigned short |
unsigned char |
保留低位字节 |
unsigned short |
unsigned long |
0扩展 |
unsigned short |
float |
转换到long; 再从 long 转换到float |
unsigned short |
double |
转换到long; 再从 long 转换到double |
unsigned short |
long double |
转换到long; 再从 long 转换到double |
unsigned long |
char |
保留低位字节 |
unsigned long |
short |
保留低位字节 |
unsigned long |
long |
最高位作为符号位 |
unsigned long |
unsigned char |
保留低位字节 |
unsigned long |
unsigned short |
保留低位字节 |
unsigned long |
float |
转换到long; 再从 long 转换到float |
unsigned long |
double |
Convert directly to double |
unsigned long |
long double |
转换到long; 再从 long 转换到double |
|
|
|
|
下面是一个使用变量的程序实例:
|
|
程序2-3: |
|
#include <iostream.h> int main (void) { 1. int workDays = 5; 2. float workHours, payRate, weeklyPay; 3. workHours = 7.5; payRate = 38.55; 4. weeklyPay = workDays * workHours * payRate; 5. cout << "Weekly Pay = " << weeklyPay << '\n'; } |
|
第一行定义了一个整型变量workDays,并初始化为5,表示一周的工作天数。 第二行定义了三个实型变量,分别表示每天工作的小时数、每小时应支付的薪水及每周应支付的薪水。 第三行是两个赋值语句。7.5 赋给变量workHours,38.55赋给变量payRate。 第四行是计算每周的工资,即三个变量workDays、workHours、payRate的积,*是乘运算符,结果保存在变量weeklyPay变量中。 第五行输出字符串"Weekly Pay = "、变量weeklyPay 的值和换行符。 本程序的运行结果如下: Weekly Pay = 1445.625 如果我们定义一个变量时,没有给它赋初值,它的值是不定的。例如,在上面的第四行执行前,weeklyPay的值是不定的。 变量第一次赋值称之为初始化,变量在使用之前应当先初始化。
|
|
|
|
C++语言把字符型变量当作一个较小的整型量,可以象整型量一样使用它。下面举一个例子说明:
|
|
程序2-6 |
|
#include <iostream.h> void main() { char c1 = 'a'; char c2 = 'b'; char c3,c4; c3 = c1 - ('a' - 'A'); c4 = c2 - ('a' - 'A'); cout<<c3<<c4<<endl; } 运行结果为: A B |
|
程序中的'a' - 'A'是大小写字母之间的差值,其值为32。所以我们也可以把程序写成: c3 = c1 - 32; c4 = c2 - 32; 如果我们想看一看c3、c4中到底存储的值是多少,可以这样: cout<<(int)c3<<(int)c4<<endl; 其运行结果为: 65 66 注意:在内存中,字符数据以ASCII码存储,即以整数表示,'0'和0是不同的。
|
|
例2-1: |
|
'\n' // 换行 '\r' // 回车 '\t' // 水平tab '\v' // 垂直tab '\b' // 退格 '\f' // 进纸 '\'' // 单引号 (') '\"' // 双引号 (") '\\' // 反斜杠 (\) |
|
|
|
例2-2: |
|
'\12' //换行(10进制编码 = 10) '\11' // 水平tab (10进制编码= 9) '\101' // 'A' (10进制编码= 65) '\0' // null (10进制编码= 0) |
|
|
|
|
|
下面给出一个有常量定义的实例程序,这个程序是打印给定半径的圆的面积和周长。
|
|
例2-6: |
|
void main() { const double PI = 3.1415926535898; //定义圆周率常量PI double radius; //定义圆半径变量 double area; //定义圆面积变量 double circumference; //定义圆周长变量 cout << "Enter radius : "; cin >> radius; area = PI*radius*radius; circumference = 2.0*PI*radius; cout << "Area of circle of radius " << radius << " is " << area << " \n"; cout << "and its circumference is " << circumference << " \n"; } 运行该程序,并输入半径值10.0: Enter radius : 10.0↙ 则输出结果为: Area of circle of radius 10.0 is 314.159 and its circumference is 62.8319 |
|
常量就是在程序运行过程中其值不发生变化的量。常量可分为直接常量与符号常量。直接常量就是平常我们所说的常数,例如: `r` // r为字符型直接常量 3.1415926 // 3.1415926为双精度直接常量 符号常量就是用一个标识符代表某个常量。符号常量可用关键字const声明,其格式如下: const 数据类型 常量名=常数值; 例如: const int a= 1234; //定义a为整型常量其值为1234 const char b=`a` //定义b 为字符型常量其值为a 在程序设计中,尽量使用符号常量来代替常数,这是一种好的编程习惯,这样可以增加程序的可读性、可维护性。例如,在数值计算中,我们会经常遇到一些常量,比如圆周率。如果把它定义成符号常量,当需要更改常量值的时候,只需要更改符号常量的定义语句即可。 也可以使用预处理语句定义符号常量,例如我们用: #define PI 3.14159 定义符号常量PI,然后在程序中使用PI,跟使用常数3.14159的效果是一样的。编译器在编译时,把符号PI替换成3.14159,当需要修改PI的值时,只需要修改上面的语句即可。但是我们不推荐这样做:因为预定义符号与符号常量不同,在编译时使用常数替代了所有的预定义符号,这样在代码中相应位置实际都是常数。程序中过多的常数会导致程序代码量变大,而且在多个源文件中定义了同样的符号,会产生符号重定义的问题。使用常量优于#define宏,优点在于可指定类型信息。
|
|
例2-7: |
|
const double PI = 3.1415927; //圆周率π const long number = 49L; const char TAB = '\t'; const char QUERY = '?'; const double SOMENUM = 1.235E75;
|
|
2.7.1 标准输出 输出内置的数据类型到标准的输出设备,用<<运算符和cout输出流。例如: cout << d; // 输出d cout << d << endl; // 输出d并换行 cout << "This is the value of d : " << d << endl; // 输出字符串、d并换行 一个语句中多次使用<<等价于<<单独使用多次,即最后一个语句等价于: cout << "This is the value of d : " ; cout << d; cout << endl; 符号endl的功能是换行,并清除输出缓冲区。变量的值以缺省的格式打印,改变打印格式方法在后面介绍。
|
经验:如何记<<和>>:cout是c出,出了就小(<<)了; cin是c进,进则收入,就大(>>) 注意:cin流不使用指针引用变量,不应给cin传递一个指向变量的指针,如果这样做cin将返回错误。例如,下面的程序cin_err.cpp ,当编译它时将返回六个错误:
|
|
例2-8: |
|
#include <iostream.h> void main(void) { int age; float salary; char name[128]; cout << "Enter your first name age salary: "; cin >> &name >> &age >> &salary; cout << name << " " << age << " " << salary; } |
|
|
|
例2-9: |
|
cout << " Enter the value of n : " << endl; cin >> n; 而不要写成: cout << " Enter the value of n : "; cin >> n; |
|
|
C++使用操纵符(在<iomanip.h>和<iostream.h>中定义),而C提供了一系列的说明符,参见表2-10。这些说明符用于输出,也可用于输入。
|
|
表2-10: |
|
说明符 |
类型 |
%wd |
int 或char |
|
w = 宽度 |
%w.df |
double w = 总的宽度(包括小数点) d = 小数位数 |
%wc |
char 或int w = 宽度 |
%ws |
char * (字符串) 格式 w = 宽度 |
%wu |
unsigned int w = 宽度 |
%wo |
八进制 |
%wx |
十六进制 |
%m.dddddde±xx %m.ddddddE±xx %m.ddddddg±xx %m.ddddddG±xx |
指数记数法 |
|
|
下面,我们给出一些格式实例,假定有下面的变量说明:
|
|
表2-11: |
|
变量说明 |
int x = 98; float y = 1.34567889; char letter = 'A'; char word[] = "Hello"; |
|
|
下表给出了输出这些变量的缺省的格式:
|
|
表2-12: |
|
语句 |
printf("Default formats: %d %f %c %s\n", x,y,letter,word); |
结果 |
Default formats: 98 1.345679 A Hello |
|
|
我们也可以改变缺省的格式。需要注意的是:输出结果是右对齐的,也就是说,当输出结果的宽度小于指定的宽度时,空格填充到左边:
|
|
表2-13: |
|
格式说明 |
语句 |
printf("Width specified: %5d %10.4f %5c %10s\n", x,y,letter,word); |
结果 |
Width specified: 98 1.3457 A Hello |
|
|
我们也可以打印变量的内存地址信息,但要使用unsigned格式说明符:
|
|
表2-14: |
|
打印内存地址 |
语句 |
printf("Address of x: %u Address of y: %u\n", &x, &y); |
结果 |
Address of x: 4026528400 Address of y: 4026528396 |
|
|
|
|
|
|
|
|
|
|
|