C++程序设计学习之认识C++的对象(代码实例)
一、一个简单的c++示例程序
/** * c++预处理程序语句都以位于首行的"#"开始,预处理语句有3种,分别是宏定义、文件包含和条件编译,下面的预处理是文件包含语句。 * 文件包含语句除了使用尖括号还可以使用#include "filename"这种形式,采用尖括号是引用系统提供的包含文件,采用双引号是引用 * 定义的包含文件,引用自己定义的文件可以指定用户当前的目录,如:#include "e:\c++\test.h" */ #include //c++标准输入输出的头文件是iostream /** * c语言一直使用扩展名".h"标识头文件,新的c++标准引入了新的标准类库头文件载入方式,即省略".h",但这必须使用下述声明命名空间语句。 * 所谓命名空间,是一种将程序库名称封装起来的方法,它提高了程序的性能和可靠性。 */ using namespace std;//使用命名空间,让命名空间std内的名称曝光 /** * c++必须要先声明后使用,如果没有声明语句,编译器扫描到"a = result(a,b);"时就会报错 */ int result(int,int);//自定义函数原型声明,声明时并不需要给出参数名称,只需要给出参数类型即可,当然也可以给出参数名称 /** * c语言一般使用"#define"定义常量,在c++中建议使用const来代替宏定义,const是放在定义之前的,因此可以进行类型判别, * 使用const修饰的标识符是一种特殊的常量,称为符号常量。不过c++中依然可以使用宏定义。无参数的宏作为常量,而带参数的宏 * 则可以提供比函数调用更高的效率,但预处理只会进行简单的文本代替,而不会进行语法检查,所以很容易出问题。 */ const int k = 2;//也可以使用"const int k(2)"这种构造函数方法进行初始化 struct calculate{ int x,y; }; //主函数功能:将结构对象的两个域值相加,乘以2再加50 int main(){//如果函数不需要返回值,这里定义时可以不使用int,用void标识,这里函数结尾就不需要使用"return 0"了,否则编译出错 /** * 定义对象包括为它命名并赋予它数据类型,一般来说,即便初值只用来表示该对象尚未具有真正意义的值,也应将每个对象进行初始化 */ int a(0), b(50);//使用构造函数初始化,"int a(0)"相当于"int a = 0" calculate c; /** * c++将数据从一个对象流向另一个对象的流动抽象为流,从流中获取数据的操作称为提取操作,向流中添加数据的操作称为插入操作 */ cout << "输入两个整数(以空格区分):";//向输出流中插入字符,<<是插入操作符,cout用来处理标准输出,即屏幕输出 cin >> c.x >> c.y;//从输入流中提取字符,>>是提取操作符,cin用来处理标准输入,即键盘输入 a = (c.x + c.y)*k; a = result(a,b); cout << "计算结果如下:" << endl;//cout << endl和cout << "\n"都代表换行 cout << "(a.x+a.y)*k + b=" << a; /** * 打印结果: * 输入两个整数(以空格区分):100 20 * 计算结果如下: * (a.x+a.y)*k + b=290 */ return 0;//返回0用来表示函数结束 } int result(int x, int y){ return x + y; }
二、认识c++面向对象特点
1、函数重载
c++允许为同一个函数定义几个版本,从而使一个函数名具有多种功能,这称为函数重载
#include using namespace std; int max(int,int);//声明2个参数的函数原型 int max(int,int,int);//声明3个参数的函数原型 int main(){ int a,b,c; cout << "请输入两个整数值(使用空格区分):" << endl; cin >> a >> b; int result = max(a,b); cout << a << "和" << b << "中最大的整数值为:" << result << endl; cout << "请输入三个整数值(使用空格区分):" << endl; cin >> a >> b >> c; int result1 = max(a,b,c); cout << a << "、" << b << "、" << c << "中最大的整数值为:" << result1 << endl; /** * 运行结果: * 请输入两个整数值(使用空格区分): * 25 68 * 25和68中最大的整数值为:68 * 请输入三个整数值(使用空格区分): * 45 85 12 * 45、85、12中最大的整数值为:85 * */ return 0; } //对两个数求最大值 int max(int x, int y){ return (x>y)x:y; } //对三个数求最大值 int max(int x, int y, int z){ int a = max(x,y); return (a>z)a:z; }
2、新的基本数据类型和注意事项
① void是无类型标识符,只能用来声明函数的返回值类型,不能用来声明变量;
② c++标准限定int和short至少要有16位,而long至少32位,short不得长于int,int不得长于long,int使用4字节;
③ 地址运算符"&"用来获取对象存储的地址,存储地址用16进制表示,例如下:
//声明并定义一个对象,使用"&"来获取对象的存储地址并输出 void example1(){ int x = 50; cout << &x;//打印结果:0x62ff1c }
④ c++中的整数常量有四种类型:十进制常量、长整型常量、八进制常量和十六进制常量,并用前缀和后缀进行分类标识
//整数常量示例 void example2(){ //十进制常量 -32768 0 32767 +123 -456 987 //长整型常量(后缀l或l) 123l -457l 0l 1l //八进制常量(前缀0) 0123 05 //十六进制常量(前缀0x) 0x10 0x1a }
⑤可以用后缀表示浮点常量的类型,带f或f的是float类型;l或l表示它是long double类型;没有后缀则是double类型
//浮点型常量示例 void example3(){ //double型浮点常量 3. 123.4 0.002 52.4 //float型浮点常量 3.2f 4.5f 0.002f //长浮点常量 0.2l 4.5l }
3、动态分配内存
在使用指针时,如果不使用对象地址初始化指针,可以自己给它分配地址,如下示例:
void example4(){ const int size = 3; int *i = new int[size];//声明int型指针并分配3个int型数据的存储空间 cout << "请输入3个整数(以空格区分):" << endl; for(int t=0;t> *(i+t); } for(int k=0;k4、引用引用就是为现有的对象起一个别名,选定命名时使用“引用”运算符"&",它将一个新标识符与一块已经存在的存储区域相关联,引用并没有分配新的存储区域,它本身并不是新的数据类型。如下简单示例:
void example5(){ int x = 25;//定义并初始化变量x int &a = x;//声明a是x的引用,此时a和x的地址相同 cout << "x的值是:" << x << ",变量x的内存地址是:" << &x << ",引用a的值是:" << a << ",引用a的内存地址是:" << &a << endl; a = 30;//改变引用a的值,同时就改变了该内存地址中的值 cout << "x的值是:" << x << ",变量x的内存地址是:" << &x << ",引用a的值是:" << a << ",引用a的内存地址是:" << &a << endl; /** * 打印结果: * x的值是:25,变量x的内存地址是:0x62ff18,引用a的值是:25,引用a的内存地址是:0x62ff18 * x的值是:30,变量x的内存地址是:0x62ff18,引用a的值是:30,引用a的内存地址是:0x62ff18 */ }理解引用的两点:
①引用实际上就是变量的别名,它同变量在使用形式上是完全一样的,它只作为一种标识对象的手段。不能直接声明对数组的引用,不能声明引用的引用,可以声明对指针的引用,也可以声明指向引用的指针。
②引用与指针有相似之处,它可以对内存地址上存在的变量进行修改,但它不占用新的地址,从而节省开销。指针是低级的直接操作内存地址的机制,指针功能强大但极易产生错误;引用则是较高级的封装了指针的特性,它并不直接操作内存地址,不可以由强制类型转换而得,因而具有较高的安全性。
如何建立对数组的引用,可以通过typedef来实现,如下示例:
void example6(){ const int size = 5;//声明const常量 typedef int array[size];//定义一个int型的数组标识符array array a = {10,20,30,40,50};//对数组进行初始化 array &b = a;//引用数组a a[1] = 100;//改变数组a中的值 for(int i = 0;i5、对指针使用const限定符①指向常量的指针指向常量的指针是在非常量指针前面使用const,例如:const int *p;它告诉编译器"*p"是常量,不能将"*p"作为左值来操作,如下:
const int y = 50; const int *p = &y;//指向常量的指针指向y,y是常量,不可以作为左值再比如:
int x = 20; const int *p = &x;//这时"*p"不能作为左值,但可以使用"x="来改变x的值,所以这个const仅仅是限定了使用"*p"的方式②常量指针
把const限定符放在*号的右边,使指针本身成为一个const指针,如下:
int x = 5; int * const p = &x;//这个指针本身就是常量,编译器要求给它一个初始值,这个值在整个指针的生存周期都不会改变,但可以使用"*p="来改变其值③指向常量的常量指针
例如:
int x = 2; const int * const p = &x;//这时告诉编译器*p和p都是常量,限制了"&"和"*"运算符6、泛型算法应用于普通数组
要输出数组的内容、对数组进行升幂排序、反转数组的内容、复制数组的内容等操作,需要包含头文件
reverse(a,a+length);//数组元素反转排列 copy(a,a+length,b);//将数组a的内容复制到数组b reverse_copy(a,a+length,b);将数组a的内容以逆向方式复制到数组b sort(a,a+length);//默认是升幂排序 copy(a,a+length,ostream_iterator(cout,"字符串"));//将数组内容按正向方式输送到屏幕 copy(a,a+length,ostream_iterator(cout," "));//在每个输出元素后面增加一个空格 copy(a,a+length,ostream_iterator(cout,"\n"));//在输出每个元素之后,换行要对数组进行降幂排序和检索,需要包含头文件
sort(b,b+length,greater());//数组降幂排序 find(a,a+length,value);//查找数组a内是否存在值为value的元素,它返回的是位置指针7、数据的简单输入输出格式
c++提供了两种格式控制方式:一种是使用iso_base类提供的接口;另一种是使用一种称为操控符的特殊函数,它的特点是可直接包含在输出和输入表达式中。不带形式参数的操控符定义在头文件
中,带形式参数的操控符定义在头文件 中。
名称 | 含义 | 作用 |
dec | 设置转换基数为十进制 | 输入/输出 |
oct | 设置转换基数为八进制 | 输入/输出 |
hex | 设置转换基数为十六进制 | 输入/输出 |
endl | 输出一个换行符并刷新流 | 输出 |
resetionsflags(long flag) | 清除flag指定的标志位 | 输出 |
setiosflags(long flag) | 设置flag指定的标志位 | 输出 |
setfill(char ch) | 设置ch为填充字符 | 输出 |
setprecision(int n) | 设置浮点数输出精度n | 输出 |
setw(int width) | 设置输出数据字段宽度width | 输出 |
resetiosflags和setiosflags的参数flag是引用c++的类ios_base里定义的枚举常量,所以要使用限定符"::"
常量名 | 含义 |
ios_base::left | 输出数据按输出域左边对齐输出 |
ios_base::right | 输出数据按输出域右边对齐输出 |
ios_base::showpoint | 浮点输出时必须带有一个小数点 |
ios_base::showpos | 在正数前面添加一个"+"号 |
ios_base::scientific | 使用科学计数法表示浮点数 |
ios_base::fixed | 使用定点形式表示浮点数 |
三、程序的编辑、编译和运行的基本概念
用c++语言写成的程序被称为源程序,源程序必须经过c++编译器程序翻译成机器语言才能执行,其大概过程如下:
①先使用编辑器编辑一个c++源程序my.cpp;
②然后使用c++编译器对这个源程序进行编译,产生my.obj文件;
③再使用连接程序,将my.obj变成my.exe可执行文件。
集成环境:就是将c++语言的编辑、编译、连接、运行程序都集中到一个综合环境中去。
;i++){> ;k++){>;t++){>