C++入门系列:第一章 认识C++的对象

C++入门系列:第一章 认识C++的对象

C++入门系列:第二章 从结构到类的演变

C++入门系列:第三章 函数和函数模板

C++入门系列:第四章 类和对象

C++入门系列:第五章 特殊函数和成员

C++入门系列:第六章 继承和派生

C++入门系列:第七章 类模板和向量

C++入门系列:第八章 多态性和虚函数

C++入门系列:第九章 流类库

#include <iostream>
using namespace std;

int result(int, int);	// 函数原型声明
const in k = 2;	
struct Point {			// 结构体
	int x, y;
};

int main() {
	int z(0), b(50);	// 初始化,相当于int z = 0; int b = 50;
	Point a;
	cout<< "输入两个整数(以空格区分):";	// 注意:在cout中的字符串不能加空格,否则会编译失败;<< 之间可以有空格
	cin>>a.x>>a.y;
	z = (a.x + a.y) * k;
	z = result(z, b);
	cout<<"result:"<<z;
	return 0;
}

int result(int x, int y) {
	return x + y;
}

1 混合型语言

C++程序以 .cpp 作为文件扩展名

2 使用输出和输入对象

当程序需要执行键盘输入时,可以使用提取操作符 ">>" 从cin输入流中提取字符;当程序需要在屏幕上显示输出时,可以使用插入操作符 "<<"向cout输出流中插入字符。

语句 cout<<endlcout<<"\n" 的功能都是换行。

3 使用命名空间

C语言一直使用扩展名 ".h" 标识头文件,新的C++标准引入新的标准类库的头文件载入方式,即省略".h"。不过,这时必须同时使用下述语句:

using namespace std;

如果仍然使用C库中的头文件,则需要使用扩展名".h"形式,例如 <math.h><stdio.h> 。如果使用C++提供的头文件,则不需要使用扩展名".h",例如 <string>

4 对象的定义及初始化

int z(0);	// 等同于int z = 0;
int b(50); 	// 等同于int b = 50;

5 函数原型及返回值

函数都需要有类型说明。C++程序使用变量的基本规则是:必须先声明,后使用,对函数调用也是如此

int result(int, int);	// 函数原型声明

int result(int a, int b) {	// 函数定义
	return a + b;
}

z = result(z, b); 	// 函数使用

6 const修饰符和预处理程序

在C++中,建议使用const代替宏定义。用关键字 const 修饰的标识符是一类特殊的常量,称为符号常量,或const变量。

因为被const修饰的变量的值在程序中不能被修改,所以在声明符号常量时,必须对符号常量进行初始化,除非这个变量是用extern修饰的外部变量:

const int i = 8;	// 不可变常量,必须初始化
const int d;		// 错误
extern const int d;	// 可以

引入头文件是使用双引号还是尖括号,其含义并不一样。

  • 采用尖括号引用系统提供的包含文件,C++编译系统将首先在C++语言系统设定的目录中寻找包含文件,如果没有找到,就到指定的目录中去寻找。

  • 采用双引号引用自己定义的包含文件(一般都放在自己指定的目录中),这将通知C++编译器在用户当前目录下或指定目录下寻找包含文件。

#include "e:\prog\myfile.h"	// 通知编译器在指定目录查找头文件

#includ <iostream>			// 通知编译器在系统设定目录先查找头文件
using namespace std;

7 使用函数重载

C++允许为同一个函数定义几个版本,从而使一个函数名具有多种功能,这成为函数重载。

#include <iostream>
using namespace std;
int max(int, int);		// 2个整型参数的函数原型
int max(int, int, int);	// 3个整型参数的函数原型

int main() {
	cout << max(35, 25) << "," << max(25, 39, 35) < endl;
}

int max(int m1, int m2) {
	return (m1 > m2) ? m1 : m2;
}

int max(int m1, int m2, int m3) {
	int t = max(m1, m2);
	return max(t, m3);
}

8 动态分配内存

在使用指针时,如果不使用对象地址初始化指针,可以自己给它分配地址。申请方式如下:

new 类型名[size];	// 申请可以存储size个该数据类型的对象

不再使用时,"delete 指针名"即可释放已经申请的存储空间。

#include <iostream>
using namespace std;

int main() {
    double* p;
    p = new double[3]; // 分配内存

    for (int i = 0; i < 3; i++) {
        cin >> *(p + i);
    }

    for (int i = 0; i < 3; i++) {
        cout << *(p + i);
    }

    delete p; // 释放内存
    return 0;
}

Point结构指针分配内存:

指针名 = new 结构名;	// 分配内存
delete 指针名		// 释放内存

p = new Point; 	
delete p; 		

9 引用

C++语言支持引用。简单地讲,就是为现有的对象起个“别名”。别名的地址就是原来对象的地址,选定命名时使用“引用”运算符 "&",再选用数据类型与之匹配。

数据类型& 别名 = 对象名;
int& a = x; 	// 注意:对象x必须先初始化,声明中的符号"&"的位置无关紧要

#include <iostream>
using namespace std;

int main() {
    int x = 56;
    int& a = x; // 声明a是x的引用,a和x的地址相同
    int& r = a; // 声明r是a的引用,r和a的地址相同,即和x的地址也相同
    cout<< "x = " << x 
        << ", &x = " << &x 
        << ", a = " << a
        << ", &a = " << &a
        << ", r = " << r
        << ", &r = " << &r << endl;
    r = 25;
    cout<< "x = " << x
        << ", &x = " << &x
        << ", a = " << a
        << ", &a = " << &a
        << ", r = " << r
        << ", &r = " << &r << endl;
    
    return 0;
}

"int& a = x;" 是声明不是定义,不需要为a分配内存,别名和正名所代表的是同一个地址。既然引用作为正名的别名而使用,所以对别名的改动实际上就是对正名的改动,输出结果:

x = 56, &x = 006FFD60, a = 56, &a = 006FFD60, r = 56, &r = 006FFD60
x = 25, &x = 006FFD60, a = 25, &a = 006FFD60, r = 25, &r = 006FFD60

所谓“引用”就是将一个新标识符和一块已经存在的存储区相关联。

不能有空引用。在程序中必须要确保引用是和一块正确的存储区域关联。

引用通常用于函数的参数表中或者作为函数的返回值。

  • 引用只是作为一种标识对象的手段,不能直接声明对数组的引用,也不能声明引用的引用
int& &r = x;	// 错误

虽然不能直接定义对数组的引用,但可以间接地建立对数组的引用:

// 该例子使用array会编译出错
#include <iostream>
using namespaece std;
typedef double array[4];	// 定义了一个double数组类型array标识符,可以用它来定义数组的引用
int main() {
	array a = {12, 34, 56, 78};
	array& b = a;
	a[2] = 100;
	for (int i = 0; i < 4; i++) {
		cout << b[i] << " ";
	}
	return 0;
}
  • 引用的作用与指针有相似之处,它会对内存地址上存在的变量进行修改,但它不占用新的地址,从而节省开销。引用与指针除了使用形式上的不同外,在本质上也有所区别:指针是低级的直接操作内存地址的机制,指针功能强大但使用不慎极易产生错误。在C++语言中,引用则是较高级地封装了指针的特性,它不直接操作内存地址,不可以由强类型转换而得,因而具有较高的安全性,也不容易产生由于使用指针而常常产生的那些不易察觉的错误。

10 对指针使用const限定符

  • 指向常量的指针
// *p是常量,不能将*p的值更改
const int *p;
  • 常量指针
int x = 5;
int* const p = &x;	// 指针地址p不可变
  • 指向常量的常量指针
int x = 2;
const int* const p = &x;	// *P和p都不可变

11 泛型算法应用于普通数组

要输出数组的内容、对数组进行升幂排序、反转数组的内容、复制数组的内容等操作,需要包含头文件 <algorithm> 。要对数组进行降幂排序和检索,需要包含头文件 <functional>有用到ostream_iterator的函数,要添加头文件 <iterator>

11.1 数组内容反转

reverse(a, a + Len);	// 数组元素反转排列

11.2 复制数组的内容

copy(a, a + Len, b); 			// 将数组a的内容原样复制到数组b
reverse_copy(a, a + Len, b);	// 将数组a的内容以逆向方式复制到数组b

11.3 数组升幂排序

sort(a, a + Len);	// 默认排序方式是升幂排序

11.4 数组降幂排序

sort(b, b + Len, greater<Type>());	// 数组降幂排序

11.5 查找数组内容

find(a, a + Len, value);	// 查找数组a内是否存在值为value的元素,这个函数返回的是位置指针

Type* x = find(a, a + Len, value);
if (x == a + Len) {
	cout << "没有value";
} else {
	cout << "有值为value的数组元素";
}

11.6 输出数组的内容

// 可将ostream_iterator简单的理解为输出流操作符,<Type>表示数组元素的数据类型,例如int或char等。
// 本语句将数组内容按正向方式送往屏幕,输出方式是将每个元素与“字符串”的内容组合在一起输出
copy(a, a + Len, ostream_iterator<Type>(cout, "字符串"));

// 逆向输出
reverse_copy(a, a + Len, ostream_iterator<Type>(cout, "字符串"));

algorithm例子

#include <iostream>
// 输出数组内容、对数组进行升幂排序、反转数组的内容、复制数组的内容等操作
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
    double a[] = {1.1, 4.4, 3.3, 2.2}, b[4];
    // 正向输出数组
    copy(a, a + 4, ostream_iterator<double>(cout, " "));
    cout << endl;
    
    // 反向输出数组
    reverse_copy(a, a + 4, ostream_iterator<double>(cout, " "));
    cout << endl;
    
    // 将数组a复制到数组b
    copy(a, a + 4, b);
    copy(b, b + 4, ostream_iterator<double>(cout, " "));
    cout << endl;
    
    // 升幂排序
    sort(a, a + 4);
    copy(a, a + 4, ostream_iterator<double>(cout, " "));
    cout << endl;
    
    reverse_copy(a, a + 4, b);
    copy(b, b + 4, ostream_iterator<double>(cout, " "));
    cout << endl;
    
    return 0;
}

functional例子

#include <iostream>
#include <algorithm>
// 数组升降幂排序和检索
#include <functional>
#include <iterator>
using namespace std;

int main() {
    double a[] = {1.1, 4.4, 3.3, 2.2};

    // 升幂排序后输出
    sort(a, a + 4);
    copy(a, a + 4, ostream_iterator<double>(cout, " "));
    cout << endl;

    // 降幂排序后输出
    sort(a, a + 4, greater<double>());
    copy(a, a + 4, ostream_iterator<double>(cout, " "));
    cout << endl;

    double* x = find(a, a + 4, 4.4);
    if (x == a + 4) {
        cout << "not found 4.4";
    } else {
        cout << "found it";
    }
    cout << endl;

    x = find(a, a + 4, 4.8);
    if (x == a + 4) {
        cout << "not found 4.8";
    } else {
        cout << "found it";
    }

    return 0;
}

注意:在操作字符串数组时要注意尾部还有一个结束符"\0",正向复制copy()不需要复制结束符,但逆向复制reverse_copy()不能将这个结束符逆向复制,否则字符串的第一位变成结束标志,使其称为空字符串。

12 输出数组的内容

C++提供了两种格式控制方式:一种是使用 iso_base 类提供的接口;另一种是使用一种称为操控符的特殊函数,它的特点是可直接包含在输出和输入表达式中,因此更为方便。不带形式参数的操控符定义在头文件 <iostream> 中,带形式参数的操控符定义在头文件 <iomanip> 中。使用它们时,一是要正确包含它们,二是只有与符号"<<“或”>>"连接时才起作用,三是无参数的操控符函数不能带有 "()" 号。

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值