- 面向过程
- 函数声明
- 头文件
- cstdlib
- limits
- 调用函数
- Vector
- 基本操作
- 传值(Pass by value)
- 传址(Pass by reference)
- 作用域
- 动态内存管理
- cerr
- inline function
- 重载函数
- 函数模板
- 函数指针
- 设定头文件
面向过程 函数声明
函数必须先被声明,之后才能被引用/调用,声明不必提供函数体,但必须指明返回类型、函数名、参数列表。
int fibon_elem(int pos); // bool fibon_elem(int pos, int &elem); // bool fibon_elem(int, int &); //目的只是让编译器知道这个函数的存在头文件 cstdlib
终止整个程序的时候,可以使用exit()这个函数。而在cstdlib这个头文件当中,就包含了这个函数。
limits想知道某个类型中的最大最小值时,可以查询limits class。
#include调用函数 Vectorint max_int = numeric_limits ::max(); double min_db1 = numeric_limits ::min();
Vector是一种数组,既然是一种数组,那么肯定有普通数组的一系列特性,比如可以通过下标对数组当中的元素进行引用。Vector也是一种可以存放任意动态类型的数组。综上,称之为容器。
基本操作- 使用时候要加入头文件#include
- 声明vector:vector vec;
- vector数组的初始化
vector传值(Pass by value)vec(1,2,3); // vector vec(a); //a这个向量给vector初始化 int ia[8] = {1,2,3,4,5,6,7,8}; vector vec(ia, ia+8); //以上这两行操作是把ia当中的元素来给vector进行初始化 vector vec(&m[0], &m[10]); //将m[0]~m[10]范围内的元素给vector进行初始化 //vector的基本操作 vec.push_back(i) ; //在尾部插入i vec.insert(vec.begin(),i); //在第一个元素之前插入i vec.assign(5,1); //插入5个1 vec.pop_back(); //相当于pop出栈 vec.erase(vec.begin()); //删除第一个元素的数值 vec.clear(); // vec.empty(); // //遍历vec vector vec; for(int i=0;i cout << vec[i]; } //利用迭代器进行访问 vector ::iterator iter; for(iter=vec.begin();iter!=vec.end();iter++){ cout << *iter; } //建立二维数组 cin >> n >> m vector >vec(n); for(int i=0;i vec[i].resize(m); }
例如有一个swap函数
void swap(int val1, int val2)
{
int temp = val1;
val1 = val2;
val2 = temp;
}
在主函数当中,swap被调用之后,其实从vector当中传给swap()函数的对象被复制了一份(vector中的对象传入函数当中是会被默认复制一份的,成为参数的局部性定义),原对象与副本之间是没有任何关联的。
传址(Pass by reference)令swap()的参数和传入的实际对象产生关联,这就是所谓的传址,把真正的地址给传进去,就能把真实值给改变。
void swap(int &val1, int &val2)
{
int temp = val1;
val1 = val2;
val2 = temp;
}
所以,要真正改变vector当中对象的数值时,要使用传址而不是传值。
作用域对象在程序内的存活区域成为对象的scope(作用域)。
对象如果在函数以外声明,具有所谓的file scope,相当于全局变量。
local scope之内的,相当于局部变量,需指定参数,否则不会被初始化。
local scope与file scope,都是系统自动分配空间的。
分配:new
释放:delete
int *pi; pi = new int; // delete pi;
局部对象的地址返回会出现错误,但是有一个例外(指的是static)。
局部静态对象所处的内存空间,即使在不同的函数调用过程当中,依然持续存在。
全局对象 std::cerr 和 std::wcerr 控制到实现定义类型(分别导出自 std::streambuf 和 std::wstreambuf )的流缓冲,与标准 C 错误输出流 stderr 关联。
inline function将之前分散开来的各个独立的函数,整合进一个函数内,但任然保持n个独立的运算单元,这就是inline function,只需在头文件处加上inline即可。
重载函数C++特性,参数列表不想同的两个或者多个函数,可以拥有相同的函数名称,这就是函数的重载。需要注意的是不能通过返回的类型来区分两个不同函数的语境。
int sum(int x, int y)
{
cout << "sum(int, int) is called" << endl;
return x + y;
}
float sum(float x, float y)
{
cout << "sum(float, float) is called" << endl;
return x + y;
}
double sum(double x, double y)
{
cout << "sum(double, double) is called" << endl;
return x + y;
}
函数模板
templatevoid display_message(const string &msg, const vector &vec) { ....... }
此处的关键字typename以及elemtype只是占位符。当指定了vector的数据类型时,elemType才会绑定相应的类型。
这个模板既可以是函数模板也可以是参数模板。template本身也可以做类型,相当于套娃。
函数模板的 其中的elemType要与之后的elemType开头相同。
templateT sum(T x, T y) { cout << "The input type is " << typeid(T).name() << endl; return x + y; }
编译器看到这个函数时,编译器不知道怎么做,因为不知道类型。要调用函数模板的话,就得进行实例化。
template double sum(double, double); //一种更简化的类型就是下面 template int sum(int, int);
templateT sum(T x, T y) { cout << "The input type is " << typeid(T).name() << endl; return x + y; } // Explicitly instantiate template double sum (double, double); int main() { auto val = sum(4.1, 5.2); //auto就是返回值是什么类型,这个val就是什么类型 cout << val << endl; return 0; }
在实例化当中进行类型的赋值就行,实例化之后直接在main函数当中调用这个函数就行。
注意,模板的调用分显式的实例化还有隐式的实例化,就是不一定非要把实例化写出来。
templateT sum(T x, T y) { cout << "The input type is " << typeid(T).name() << endl; return x + y; } int main() { // Implicitly instantiates product (int, int) cout << "sum = " << sum (2.2f, 3.0f) << endl; // Implicitly instantiates product (float, float) cout << "sum = " << sum(2.2f, 3.0f) << endl; return 0; }
结构体也可以是一个类型,不过其实例化是一个特例化,要加上一个尖括号<>。
普通的实例化如下
template double sum函数指针(double, double); //特例化如下 template<> Point sum (Point pt1, Point pt2); //Point代表结构体类型
必须指明所指函数的返回类型以及参数列表,以及赋予一个名称。
const vector* (*seq_ptr)(int);
在这,参数列表内容为int,返回类型为const vector*。
若要显示循环,在每次迭代过程中将seq_ptr设置为各个不同的数列函数,可以利用数组索引的技巧。
const vector设定头文件* (*seq_array[])(int) = { fibon_seq, lucas_seq......... };
尖括号就是从编译器指定的include路径去找头文件,双引号就是从不光从编译器指定的路径找,而且还从当前这个cpp文件的当前目录去找。



