C++ 语言是对 C 语言的扩展,两者常被视为一个整体,集成于同一编译环境之中——你只须将一个 C 程序的文件后缀由 .c 改为 .cpp,它就成了 C++ 程序。C++ 在 C 语法之上增加了许多高级特性,运行效率相近而更加灵活多变,因此其应用领域也更为广阔。
下面来看一个 C++ 程序示例 myclass.cpp——这段源码首先包含了 C++ 标准库的“输入输出流”头文件,能够更方便地读入数据并打印结果(可以对照之前 C 代码的输入输出方式);随后定义了一个“圆”类,用一个私有成员变量表示半径,并用两个公有成员函数分别计算面积和周长(可以对照 Python 中定义类及创建实例的语法):
#include <iostream>
const double PI = 3.14159;
class Circle
{
private:
double r;
public:
Circle(double r_)
{
r = r_;
}
double area()
{
return PI * r * r;
}
double perimiter()
{
return 2 * PI * r;
}
};
int main()
{
double r;
std::cout << "请输入圆的半径:";
std::cin >> r;
Circle c = Circle(r);
std::cout << "圆的面积为:" << c.area() << std::endl;
std::cout << "圆的周长为:" << c.perimiter() << std::endl;
}
你已经知道 Python 能够使用 C/C++ 共享库,实际上 C/C++ 还可以编写 Python 专用共享库也就是扩展模块——让我们来尝试一下,首先新建文件 mymath.cpp:
/* C/C++编写Python扩展模块示例
需要包含Python提供的头文件,例如VSCode应添加以下配置
"C_Cpp.default.includePath": ["~/miniconda3/include/python3.7m"],
*/
#include <Python.h>
/* 计算斐波纳契数列的项 */
int cFib(int n)
{
if (n < 2)
return n;
return cFib(n - 1) + cFib(n - 2);
}
/* Python函数 */
static PyObject *fib(PyObject *self, PyObject *args)
{
int n;
if (!PyArg_ParseTuple(args, "i", &n))
return NULL;
return Py_BuildValue("i", cFib(n));
}
/* Python方法列表 */
static PyMethodDef module_methods[] = {
{"fib", fib, METH_VARARGS, "calculates the fibonachi number"},
{NULL, NULL, 0, NULL}};
/* Python模块 */
static struct PyModuleDef mymath =
{
PyModuleDef_HEAD_INIT,
"mymath", /* 模块名 */
"mymath module", /* 模块文档字符串 */
-1, /* 保持全局状态 */
module_methods};
/* Python模块初始化 */
PyMODINIT_FUNC PyInit_mymath()
{
return PyModule_Create(&mymath);
}
以上源码其实只用了 C 语法。第一行指令是包含官方 Python/C API 的头文件;第一个函数 cFib 实现具体功能——递归地计算斐波那契数列的项:第一项为 0,第二项为 1,之后每一项都是其前面两项的和;其余函数都是按照规范来定义模块的信息。接下来新建文件 setup.py:
from distutils.core import setup, Extension
mymath = Extension('mymath', sources=['mymath.cpp'])
setup(ext_modules=[mymath])
输入以下命令即可调用编译器在当前目录下生成扩展模块文件,注意:在 Windows 下需要 Visual C++ Build Tools http://go.microsoft.com/fwlink/?LinkId=691126
python setup.py build_ext --inplace # 执行时会提示实际调用的编译命令
最后在交互模式下测试:
In [1]: import mymath
In [2]: mymath.fib?
Docstring: calculates the fibonachi number
Type: builtin_function_or_method
In [3]: [mymath.fib(i) for i in range(10)]
Out[3]: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
说起交互模式,其实 C/C++ 也可以有交互模式,而且还支持我们刚接触过的 Jupyter,如果需要就请安装 Cling https://github.com/root-project/cling