前言:经过第一章的绪论,我们现在开始真正接触一个C++程序。
一.简单的C++程序
例一:计算两个整数之和:
#include<iostream>//注意和C语言区别||输入输出流类库
using namespace std;//在不同的IDE中存在不同的情况,前两句可写成#include<iostream.h>
//使用命名空间std 可直接使用cout cin endl
int add(int ,int); //函数声明,注意加“;”
int main()
{
int x,y,sum;
cout<<"Please input two integers:"<<endl;//输出语句 ,并换行
cin>>x>>y;//输入语句
int sum=add(x,y);
cout<<x<<"+"<<y<<"="<<sum<<endl;
return 0;
}
int add(int x,int y)//外部函数
{
return x+y;
}
注意C++程序中输入输出关键字使用方法
二.C++程序的结构特性
一个面向对象的C++程序一般由类的定义和类的使用两部分。类的使用一般由主函数及有关子函数组成。(主函数中有且只有一个主函数main,它是第一个被执行的函数)
三.C++程序的编辑、编译、连接和运行
C源程序文件扩展名为“.c”,而C++源程序文件名为“.cpp”。
四.C++在非面向对象方面的扩充
1.C++的输入输出:
cin是输入流对象,在程序中用于代表标准输入设备,通常指键盘。运算符>>表示将从输入流对象(即键盘)读取的数值传送给右方指定的变量。
*注意:*运算符">>”在C++中仍保持"右移”功能;
重点:
(1)在默认情况下,运算符">>”将跳过空白符,然后读入后面的与变量类型相对应的值。因此,给一组变量输入值时可用空白符(空格、回车或Tab键)将键入的数值间隔开。例如
int i;
float x;
cin>>i>>x;
在输入时只需输入下面形式即可:
23 56.78(中间有空格)
或
23
56.78
(2)当输入字符串时,运算符">>”的作用是跳过空白,读入后面的非空白字符,直到遇到另一个空白字符为止,并在串尾放一个字符‘\0’。
例如:
#include<iostream>
using namespace std;
int main()
{
char str[30];
cin>>str;
cout<<endl<<str<<endl;
return 0;
}
当键入的字符串为:
Object_Oriented Programming!
结果是:
str指向的字符串为:”Object_Oriented”,此时空格后面内容被忽略
解决方法:
#include<iostream>
using namespace std;
char str[30];
void getstring()
{ cout<<"请输入字符串:"<<endl;
gets(str);
}
int main()
{
getstring();
cout<<endl<<str<<endl;
return 0;
}
当键入的字符串为:
Object_Oriented Programming!
结果是:
str指向的字符串为:
"Object_Oriented Programming!”
(3) cout是输出流对象,在程序中用于代表标准输出设备,通常指屏幕。运算符<<表示将右方变量f的值写到输出流对象cout中,即显示在屏幕上。
- 运算符"<<” 在C++中仍保持"左移”功能;
- 运算符"<<” 允许用户连续输出一连串数据,也可以输出表达式的值,例如:
int n=456;
double d=3.1416;
cout<<″n=″<<n<<″,d=″<<d<<'\n';
运行结果:n=456,d=3.1416
3.前面用cout和cin输出输入数据时, 使用了系统默认的格式。实际上,可以对输入和输出的格式进行控制。
例如我们可用设置域宽的操纵符setw(n),来控制输出数据的宽度
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
cout<<123<<endl;
cout<<setw(6)<<456<<endl;
return 0;
}
//运行结果:123
// 456
2.灵活的局部变量说明:
C语言要求全局变量声明必须在任何函数之前,局部变量必须集中在可执行语句之前。而C++中变量声明非常灵活,它允许变量声明与可执行语句在程序中交替出现。这样程序员可以在使用一个变量时才声明它。
例:该函数在C语言中不正确,在C++中正确。
f()
{
int i;
i=10;
int j;
j=25;
.
.
.
}
C++允许在代码中的任何地方说明局部变量,它所说明的变量从其说明点到该变量所在的最小分程序末的范围内有效。需要强调的是,局部变量说明一定要符合“先定义,后使用”的规定。注意:在大函数中,在最靠近使用变量的位置说明变量较为合理;而在较短的函数中,把局部变量集中在函数开始处说明比较好。
3.结构、联合和枚举名可直接作为类型名
在C++中,结构名、联合名、枚举名可直接作为类型名。在定义变量时,不必在结构名、联合名或枚举名前冠以struct、union、enum,例如:
enum Bool{ FALSE,TRUE};
struct String
{
char * ptr;
int length;
};
在传统的C中,定义变量时,必须写成:
enum Bool done;
struct String str;
在C++中定义变量时,可以说明为:
Bool done; //省略了enum
String str; //省略了struct
4.const修饰符
在C中,习惯使用宏定义#define来定义常量,例如:
#define PI 3.14159
PI没有类型,不占用存储单元
实际上,#define只是在预编译时进行字符置换,把程序中出现的字符串PI全部置换为3.14159。在预编译后,程序中不再有PI这个标识符。
在C++常使用const修饰符来定义常量,例如:
const float PI=3.14159;
常量PI是有类型的,它占用存储单元,有地址,可以用指针指向这个值,但不能修改它。
为什么C++中使用const定义常量?
例如:使用#define的不安全性。
#include<iostream>
using namespace std;
int main()
{
int a=1;
#define T1 a+a
#define T2 T1-T1
cout <<"T2 is"<<T2<<endl;
return 0;
}
运行结果:2(实际我们想要得到0)
用const取代#define
#include<iostream>
using namespace std;
int main()
{
int a=1;
const int T1=a+a;
const int T2=T1-T1;
cout << " T2 is " <<T2<<endl;
return 0; }
运行结果:T2 is 0
**注意:**const的作用与#define相似,但它消除了#define的不安全性。
因此建议用 const取代#define定义常量。
const可以与指针一起使用,它们的组合情况可归纳为以下三种:
1.指向常量的指针(常量指针)
只能够读取内存中数据,却不能够修改内存中数据属性的指针。
例如:
const char* pc="abcd”;
这个语句的含义是:声明一个名为pc的指针变量,它指向一个字符型常量,初始化pc为指向字符串“abcd”,由于使用了const,不允许改变指针所指地址中的常量。
所以pc[3]=′x′ 是正确的 pc="efgh" 是错误的。
2.常指针(指针常量)
不可改变指针的指向,但可以通过指针来修改所指的值。
例如:
char* const pc="abcd";
这个语句的含义是:声明一个名为pc的指针变量,该指针是指向字符型数据的常指针,用“abcd”的地址初始化该常指针。创建一个常指针,就是创建一个不能移动的固定指针,即不能改变指针所指的地址,但是它所指地址中的数据可以改变。
所以pc[3]=′x′ 是正确的 pc= "efgh” 是错误的。
3.指向常量的常指针
这个指针变量所指的地址不能改变,它所指向的地址中的数据也不能改变。
例如:
const char*const pc="abcd"
这个语句的含义是:声明了一个名为pc的指针变量,它是一个指向字符型常量的常指针,用"abcd"的地址初始化该指针。
所以:pc[3]=′x′ pc= "efgh" 都不正确。
注意:
1.如果用const定义的是一个整型常量,关键字int可以省略。(建议不要省略)
例如:
下面的两行定义是等价的:
const int bufsize=200;
const bufsize=200;
2.常量一旦被建立,在程序的任何地方都不能再更改
3.与#define定义的常量有所不同,const定义的常量可以有自己的数据类型,这样C++的编译程序可以进行更加严格的类型检查,具有良好的编译时的检测性。
4.函数的形参也可以用const说明,用于保证形参在该函数内部不被改动,即在函数中对这些参数只许读,而不许写。
例如, 希望通过函数i_Max求出整型数组a[200]中的最大值,函数原型是:
int i_Max(const int ptr);
调用时的格式可以是:
i_Max(a);
调用后,能够找出数组中的最大元素,但对200个数组元素的操作只许读,而不许写。
这样做的目的是确保原数组中的数据不被破坏,即在函数中对数组元素的操作只许读,而不许写。
5.函数原型
C语言建议*编程者为程序中的每一个函数建立原型,
而C++要求为每一个函数建立原型,以说明函数的名称、参数类型与个数,以及函数返回值的类型。
其主要的目的是让C++编译程序进行类型检查,即形参与实参的类型匹配检查,以及返回值是否与原型相符,以维护程序的正确性。
如果函数调用在前,定义在后,必须加上函数原型声明,用于说明函数的名称、参数类型与个数,以及函数返回值的类型。
#include<iostream>
using namespace std;
void writestr(char *s);(函数声明+;)
void main()
{ writestr("Hello,world!");
}
void writestr(char *s) (函数定义不加;)
{ cout<<s;
}
当一个函数的定义在前,而对它的调用在后时,不必给出函数的原型。
#include<iostream>
using namespace std;
void writestr(char *s)//函数定义的首部
{
cout<<s;
}
void main()
{
writestr("Hello,world!");
}
注意:
(1) 函数原型的参数表中可不包含参数的名字,而只包含它们的类型。
例如: long Area(int,int);
但是加上参数名将使原型更加清楚,如:
long Area(int length,int width);
(2) 函数定义由函数说明和函数体两个部分构成。函数说明部分与函数原型基本一样,但函数说明部分中的参数必须给出参数的名字,而且不能包含结尾的分号,例如:
long Area(int length,int width)//函数的说明部分
{
…
return(length*width);
}
(3)主函数main不必进行原型说明,因为它被看成一个自动说明原型的函数。主函数是第1个被执行的函数,而且不存在被别的函数调用的问题。
(4) 原型说明中没有指出返回类型的函数(包括主函数main),C++默认该函数的返回类型是int。标准C++要求main函数必须声明为int型,即要求主函数带回一个整形函数值。C++通常是这样处理的:如果程序正常结束,则在main函数的最后加一句return 0; 向操作系统返回数值0;如果函数执行不正常,则返回数值-1。
(5) 如果一个函数没有返回值,则必须在函数原型中注明返回类型为void。
这样在主函数中就不必有"return 0;”了。
(6) 如果函数原型中未注明参数,C++假定该函数的参数表为空(void)。
例如:
以下的原型说明在C++中是完全一样的:
f( ); //表示该函数不带任何参数
f(void); //表示该函数不带任何参数
在C中,以下的两个原型说明是不同的:
f(void): //表示该函数不带任何参数
f( ); //表示该函数的参数信息没有
给出,很可能它带有多个参数