C++面向对象程序设计教程-陈维兴 第二章:C + + 概 述

这篇博客详细介绍了C++的非面向对象特性,包括源程序构成、输入输出流、const修饰符、内置函数、函数原型、缺省参数、函数重载等。同时,讲解了作用域运算符、无名联合、强制类型转换、new和delete操作以及引用的概念和用法。内容深入浅出,适合C++初学者巩固基础知识。
摘要由CSDN通过智能技术生成

目录

2 .2 C + + 源程序的构成

2 .2 .1 C + + 程序的一般格式

2 .3 C + + 在非面向对象方面的一些特性

2 .3 .2输入流和输出流的简单操作

2 .3 .5 const 修饰符

2 .3 .6 内置函数

2 .3 .7 函数原型

2 .3 .8 带有缺省参数的函数

2 .3 .9 函数重载

2 .3 .10 作用域运算符“∷”

2 .3 .11 无名联合

 2 .3 .12 强制类型转换

2 .3 .13 new 和 delete

 2 .3 .14 引用

 课后练习 

2 .7 分析下面程序的输出结果:

2 .8 建立一个被称为 sroot( )的函数,返回其参数的二次根。重载 sroot( )三次,让它分别返回整数、长整数与双精度数的二次根(为了实际计算二次根, 可以使用标准库函数sqrt( ))。

2 .9 编写一个程序, 用 C + + 风格的 I/ O 从键盘输入两个整数, 然后显示以第一个数为底,第二个数为指数的结果(例如,用户输入 2 与 4, 那么结果就是 16)。




本人代码用的是vs2017调试的,所以书上的很多错误问题,已经更正。

2 .2 C + + 源程序的构成

2 .2 .1 C + + 程序的一般格式

//例2.1  sum.cpp
# include <iostream>  //输入输出流cin和cout的头文件
using namespace std; //通用命名空间std
int add(int a, int b); // 函数原型的说明(声明)
//以上成为预处理命令
int main() // 主函数
{
    int x, y, sum; // 定义三个整型变量
    cout << "Enter two numbers : " << '\ n';// 界面: 提示用户输入两个数
    cin >> x;// 从键盘输入变量 x 的值
    cin >> y;// 从键盘输入变量 y 的值
    sum = add(x, y); // q 调用函数 add,将得到的值赋给变量 sum
    cout << "The sum is : " << sum < < '\ n'; // 输出两个数的和 sum 的值
    return 0;
}
int add(int a, int b) // 定义 add 函数, 函数值为整型
{
    int c; // 定义一个整型变量
    c = a + b; // 计算两个数的和
    return c; // q 将 c 的值返回, 通过 add 带回调用处
}

本程序用来计算两个整数的和。它由两个函数组成: 主函数 main( )和被调用函数add( )。函数 add( )的作用是计算 a 与 b 的和, 把其值赋给变量 c。return 语句把 c 的值返回给主函数 main( )。返回值通过函数名 add 带回到 main()函数的调用处。

2 .3 C + + 在非面向对象方面的一些特性

2 .3 .2输入流和输出流的简单操作

//例 2 .2 
#include<iostream>
using namespace std;
int main()
{
    char name[20];
    cout<< "Hello, your name : ";
    cin >> name;
    cout << name;
    return 0;
}

在 C + + 程序 中, 我们仍 然可以沿 用传统的 stdio 函 数库 中的 I/ O 函数, 如printf()函数、scanf( )函数或其它的 C 输入输出函数, 但只有使用“cin > > ”和“cout < < ”才能显示 C + + 的输入和输出风格  

使用“cin > > ”可以连续输入多个数据

实际上,我们也可以对输入和输出格式进行控制。例如我们可用不同进制的方式显示数据, 这时就要用设置转换基数的操纵符 dec、hex 和 oct。
其中 dec 把转换基数设置为十进制, hex 把转换基数设置为十六进制,oct 把转换基数设置为八进制, 缺省的转换基数是十进制。请看下面的例子。

//例 2 .3
# include < iostream >
using namespace std;
int main()
{
    int x = 25;
    cout << hex << x << ' ' << dec << x << ' ' << oct << x << ' \ n';
}

此例执行的结果为:
19 25 31
分别代表十六进制的 25、十进制的 25 及八进制的 25

 在 C 中, 常用′\ n′实现换行,C + + 中增加了换行控制符 endl, 其作用与′\ n′ 一样。

2 .3 .5 const 修饰符

C + + 提供了一种更灵活、更安全的方式来定义常量, 即使用 const 修饰符来定义常
量,例如: const int LIMIT = 100;
这个常量是类型化的,它有地址, 可以用指针指向这个值,但不能修改它。
const 也可以与指针一起使用,它们的组合情况较复杂, 可归纳为三种:

指向常量的指针、常指针和指向常量的常指针。

(1) 指向常量的指针是指一个指向常量的指针变量, 例如: const char * name = ”chen”; / / 声明指向常量的指针
这个语句的含义为: 声明一个名为 name 的指针变量, 它指向一个字符型常量, 初始化 name 为指向字符串”chen”。
由于使用了 const,不允许改变指针所指的常量, 因此以下语句是错误的: name[3] = ′a′;
但是,由于 name 是一个指向常量的普通指针变量, 不是常指针, 因此可以改变 name 的值。
例如下列语句是允许的: name =”zhang”;该语句赋给了指针另一个常量,即改变了 name 的值。

(2) 常指针是指把指针本身, 而不是它指向的对象声明为常量,例如: char * const name = ”chen”; / / 常指针   
这个语句的含义为: 声明一个名为 name 的指针变量, 该指针是指向字符型数据的常指针,用”chen”的地址初始化该常指针。 创建一个常指针,就是创建一个不能移动的固定指针, 但是它所指的数据可以改变,
例如: name[3] = ′a′; / / 合法  name = ”zhang”; / / 出错
第一个语句改变了常指针所指的数据,这是允许的; 但第二个语句要改变指针本身, 这是 不允许的。

(3) 指向常量的常指针是指这个指针本身不能改变, 它所指向的值也不能改变。要声明一个指向常量的常指针,二者都要声明为 const, 例如: const char * const name = ”chen”; / / 指向常量的常指针
这个语句的含义是:声明了一个名为 name 的指针变量,它是一个指向字符型常量的常指针,用“chen”的地址初始化该指针。不难理解以下二个语句都是错误的:  name[3] =′a′; ) / / 出错, 不能改变指针所指的值 name = ”zhang”; / / 出错, 不能改变指针本身

说明:
(1) 如果用 const 定义的是一个整型常量, 关键字 int 可以省略。所以下面的两行定
义是等价的:
const int LIMIT = 100;
const LIMIT = 100;
(2) 常量一旦被建立, 在程序的任何地方都不能再更改。
(3) 与 # define 定义的常量有所不同, const 定义的常量可以有自己的数据类型,
这样C + + 的编译程序可以进行更加严格的类型检查, 具有良好的编译时的检测性。
(4) const 的作用与 # define 相似,但它消除了 # define 的不安全性, 因此建议用const取代 # define 定义常量

下例说明了使用 # define 的不安全性。

//例 2 .4
# include < iostream >
int main()
{
    int a = 1;
# define T1 a + a;
# define T2 T1 - T1;
    std::cout << "T2 is" << T2;
    return 0;
}

初看程序,似乎应打印出:
T2 is 0
但是这个答案是错误的,程序的实际输出结果是:
T2 is 2

其原因是 C + + 把第 7 行语句解释成: cout < < ”T2 is” < < a + a - a + a < < endl;
如果程序中用 const 取代了两个 # define, 将不会引起这个错误,请看下例。 

//例 2 .5
# include < iostream  >
int main()
{
    int a = 1;
    const int T1 = a + a;
    const int T2 = T1 - T1;
    std::cout<< "T2 is" << T2 <<std::endl;
    return 0;
}

输出:T2 is 0

函数参数也可以用 const 说明, 用于保证实参在该函数内部不被改动, 大多数C + + 编辑器能对具有 const 参数的函数进行更好的代码优化。  

虽然美国国家标准化协会(ANSI)制定的 C 标准(简称 ANSI C 标准)也采用了const,但两者略有差别, 如下面的程序段在 C + + 中是合法的, 但却不能被 ANSI C 所接受: const int size = 300; int a[size];
另外,在 ANSI C 标准中,const 定义的常量是全局常量, 而 C+ + 中 const 定义的常量根据其定义的位置来决定其是局部的还是全局的

2 .3 .6 内置函数

在函数说明前,冠以关键字“inline”, 该函数就被声明为内置函数。每当程序中出现对该函数的调用时,C + + 编译器使用函数体中的代码替代函数调用表达式, 这样能加快代码的执行,减少调用开销。下面的程序定义了一个内置函数

//例 2 .6
# include < iostream >
using namespace std;
inline float circle(float r){ //内置函数
    return 3.1416 * r * r; 
}
int main()
{
    for (int i = 1; i <= 3; i ++)
        cout << "r=" << i << "area =" << circle(i) << endl;
    return 0;
}

程序运行结果如下:
r = 1 area = 3 .1416
r = 2 area = 12 .5664
r = 3 area = 28 .274401

 内置函数在被调用之前必须进行完整的定义, 否则编译器将无法知道应该插入什么代码。内置函数通常写在主函数的前面。
C + + 的内置函数具有与 C 中的宏定义 # define 相同的作用和相似的机理,但消除了 # define 的不安全因素。请看下面的例子。

// 例 2 .7 使用带参宏定义完成乘 2 的功能。
# include < iostream >
using namespace std;
# define doub(x) x * 2
int main()
{
    for (int i = 1; i <= 3; i++)
        cout << i << "doubled is" << doub(i) << endl;
    cout << "1 + 2 doubled is " << doub(1 + 2) << endl;
    return 0;
}

程序运行结果为:
1 doubled 2
2 doubled 4
3 doubled 6
1 + 2 doubled 5

 分析运行结果, 可以看出前三个结果是正确的。但是第四个结果与期望的结果有所差别,期望的结果应该是 6, 因为 1 + 2 加倍后是 6, 实际运行的结果却是 5。出现问题的原因是宏定义的代码在程序中是被直接展开的。在上例中, 编译程序将第

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值