《C++从入门到精通》教学视频,素材文件,结果文件

  • 更新时间:
  • 7204人关注
  • 点击下载

给大家带来的是《C++从入门到精通》教学视频,素材文件,结果文件,介绍了关于C++入门、C++精通、C++方面的内容,本书是由人民邮电出版社出版,已被447人关注,由热心网友胡馨欣 提供,目前本书在C++类综合评分为:9.6分

资源详情相关推荐
《《C++从入门到精通》教学视频,素材文件,结果文件》封面
  • 出版社:人民邮电出版社
  • 作者:谭玉波,吴勇,韩璐
  • 大小:1.1 GB
  • 类别:C++
  • 热度:854
  • C++入门经典(第5版)
  • Visual C++小波变换技术与工程实践
  • C++编程规范:101条规则、准则与最佳实践
  • 挑战C++程序语言
  • C++程序设计与实例
  • 编辑推荐

    *零基础、入门级的讲解n
    无论读者是否从事计算机相关行业、是否接触过C++、是否使用C++开发过项目,都能从本书中有所收获。n
    *超多、实用、专业的范例和项目n
    本书结合实际工作中的范例,逐一讲解C++的各种知识和技术。以实际开发项目来总结本书所讲内容,帮助读者在实战中掌握知识,轻松拥有项目经验。n
    *随时检测自己的学习成果n
    每章首页都给出了“本章要点”,以便读者明确学习方向。每章的“综合案例”根据所在章的知识点精心设计而成,读者可以随时自我检测,巩固所学知识。n
    *细致入微、贴心提示n
    本书在讲解过程中使用“提示”“注意”“技巧”等小栏目,帮助读者在学习过程中更清楚地理解基本概念、掌握相关操作以及轻松获取实战技巧。n
    *全程同步教学视频n
    涵盖本书所有知识点,详细讲解每个范例和项目的开发过程及关键点,帮助读者更轻松地掌握书中所有的C++程序设计知识。n
    *超多资源大放送n
    赠送大量资源,包括本书范例的素材文件和结果文件、库函数查询手册、C++ 常用查询手册(头文件、关键字和常用字符ASCII码查询)、10套完整源代码、C++常见面试题、C++常见错误及解决方案电子书、C++开发经验及技巧大汇总、C++程序员职业规划和C++程序员面试技巧。n
    *多平台学习方式n
    可实现手机端、电脑端同步学习

    内容简介

    本书主要面向零基础读者,用实例引导读者学习,深入浅出地介绍C++的相关知识和实战技能。n
    本书第Ⅰ篇“基础知识”主要讲解C++程序的基本组成、标识符和数据类型、运算符和表达式、程序控制结构和语句、算法与流程图、数组、函数、指针以及输入和输出等;第Ⅱ篇“核心技术”主要讲解类和对象、命名空间、继承与派生、多态与重载、文件操作、容器、模板、预处理、异常处理、网络编程技术、数据库编程技术、用户界面编程及游戏编程等;第Ⅲ篇“提高篇”主要介绍网络应用项目、DirectX基础与应用以及专业理财系统等。n
    本书提供的电子资源中包含与图书内容全程同步的教学视频。此外,还赠送了大量相关学习资料,以便读者扩展学习。n
    本书适合任何想学习C++的读者,无论读者是否从事计算机相关行业,是否接触过C++,均可通过学习本书快速掌握C++的开发方法和技巧。

    作者简介

    谭玉波,吴勇,韩璐,龙马高新教育团队的作者,龙马高新教育,专业的计算机研究、教育机构,拥有近20年的图书出版经历,与39所高校、8个行业协会、5家知名网站保持合作关系,屡获全国畅销书大奖,其推出的“从入门到精通”“完全自学手册”“编程宝典”“完全自学手册”“非常网络6+1”等均成为业界知名图书,受到百万读者的认可和推荐。

    目录

    第 Ⅰ 篇基础知识n
    第 1 章 开始C++编程之旅——C++概述n
    1.1 OOP面向对象编程 003n
    1.1.1 OOP的含义 003n
    1.1.2 面向对象编程 003n
    1.1.3 C++的特点 003n
    1.2 程序设计概述 004n
    1.2.1 结构化程序设计 004n
    1.2.2 面向对象程序设计 005n
    1.3 C、C++与Visual C++ 005n
    1.3.1 C与C++ 005n
    1.3.2 C++与Visual C++ 006n
    1.3.3 C++初学者建议  006n
    1.4 C++程序开发环境 006n
    1.4.1 基本概念 006n
    1.4.2 C++程序开发过程 007n
    1.4.3 C++开发环境介绍 008n
    1.4.4 Code::Blocks开发环境安装与部署 009n
    1.5 第 一个C++程序——“Hello,world!”输出 011n
    1.5.1 创建源程序 011n
    1.5.2 编译、连接和运行程序 012n
    1.5.3 常见错误 013n
    1.5.4 创建并运行多文件程序 014n
    1.5.5 打开已有文件 018n
    1.6 综合案例 019n
    1.7 疑难解答 020n
    第 2 章 C++程序的基本组成n
    2.1 C++程序 022n
    2.1.1 预处理命令 022n
    2.1.2 函数 023n
    2.1.3 注释 024n
    2.1.4 main函数 024n
    2.1.5 命名空间 024n
    2.1.6 cout进行标准输出 025n
    2.1.7 变量声明与赋值 025n
    2.1.8 cin进行标准输入 025n
    2.2 C++代码编写规范 025n
    2.2.1 代码写规范的必要性 025n
    2.2.2 将代码书写规范 025n
    2.3 算法是程序的核心 026n
    2.3.1 算法的概念 026n
    2.3.2 流程图表示算法 026n
    2.4 综合案例 027n
    2.5 疑难解答 028n
    第 3 章 标识符和数据类型n
    3.1 标识符  030n
    3.1.1 C++中的保留字 030n
    3.1.2 C++中的命名规则 031n
    3.2 数据类型  031n
    3.2.1 整型 032n
    3.2.2 浮点型 032n
    3.2.3 字符型 032n
    3.2.4 布尔型 033n
    3.3 常量 033n
    3.3.1 输出常量 033n
    3.3.2 宏定义的符号常量 035n
    3.3.3 const常量 037n
    3.4 变量 037n
    3.4.1 变量的定义 038n
    3.4.2 变量的赋值 038n
    3.4.3 变量的生存周期 042n
    3.5  数据类型转换 042n
    3.6 复合数据类型 046n
    3.6.1 数组 046n
    3.6.2 字符串 047n
    3.6.3 结构体 048n
    3.7 综合案例 050n
    3.8 疑难解答 051n
    第 4 章 C++运算符和表达式n
    4.1 C++中的运算符和表达式 054n
    4.1.1 运算符 054n
    4.1.2 表达式 054n
    4.2 算术运算符和表达式 055n
    4.2.1 基本算术运算符 055n
    4.2.2 算术运算符和算术表达式 055n
    4.2.3 自加和自减运算符 055n
    4.3 位移运算符和表达式 057n
    4.3.1 位移运算符 057n
    4.3.2 位移表达式 057n
    4.4 关系运算符和表达式 058n
    4.4.1 关系运算符 058n
    4.4.2 关系表达式 058n
    4.5 位运算符和表达式 059n
    4.5.1 位运算符 059n
    4.5.2 位表达式 059n
    4.6 逻辑运算符和表达式 060n
    4.6.1 逻辑运算符 060n
    4.6.2 逻辑表达式 060n
    4.7 条件运算符和表达式 061n
    4.8 赋值运算符和表达式 062n
    4.8.1 赋值运算符 062n
    4.8.2 赋值表达式 062n
    4.9 逗号运算符和表达式 063n
    4.10 运算符的优先级 064n
    4.11 综合案例 066n
    4.12 疑难解答 067n
    第 5 章 程序控制结构和语句n
    5.1 程序流程概述 070n
    5.2 顺序结构 070n
    5.3 选择结构与语句 071n
    5.3.1 选择结构 071n
    5.3.2 单分支选择结构——if语句 071n
    5.3.3 双分支选择结构——if...else语句 073n
    5.3.4 多分支选择结构——switch语句 074n
    5.4 循环结构与语句 076n
    5.4.1 循环结构 076n
    5.4.2 for语句 077n
    5.4.3 while语句 080n
    5.4.4 do...while语句 081n
    5.5 转向语句 082n
    5.5.1 break语句 083n
    5.5.2 continue语句 084n
    5.5.3 goto语句 085n
    5.6 简单文件输入输出 086n
    5.6.1 文本文件 087n
    5.6.2 文件读取 087n
    5.6.3 文件写入 087n
    5.7 常见错误 089n
    5.7.1 语法错误 089n
    5.7.2 逻辑错误 089n
    5.7.3 运行错误 090n
    5.8 程序调试 090n
    5.9 综合案例 093n
    5.10 疑难解答 095n
    第 6 章 程序设计的灵魂——算法与流程图n
    6.1 算法基础 098n
    6.1.1 算法的概念 098n
    6.1.2 算法的特性 098n
    6.1.3 算法举例1—排序 099n
    6.1.4 算法举例2—求和 100n
    6.2 流程图基础 101n
    6.2.1 流程图中的元素及含义 102n
    6.2.2 流程图的绘制 102n
    6.3 如何表示一个算法 103n
    6.3.1 用自然语言表示算法 103n
    6.3.2 用流程图表示算法 104n
    6.3.3 用N-S图表示算法 106n
    6.3.4 用伪代码表示算法 107n
    6.3.5 用PAD 图表示算法 108n
    6.4 结构化算法 109n
    6.5 综合案例 110n
    6.6 疑难解答 114n
    第 7 章 相同类型的数值表达——数组n
    7.1 数组是什么 116n
    7.1.1 一维数组 116n
    7.1.2 一维数组的声明和定义 116n
    7.1.3 一维数组的初始化 117n
    7.1.4 一维数组元素的引用 118n
    7.2 二维数组 119n
    7.2.1 二维数组的定义 120n
    7.2.2 二维数组的初始化 120n
    7.2.3 存取二维数组元素 122n
    7.2.4 二维数组元素的引用 123n
    7.3 多维数组 124n
    7.4 综合案例 124n
    7.5 疑难解答 126n
    第 8 章 函数n
    8.1 函数的作用与分类 128n
    8.1.1 函数的作用 128n
    8.1.2 函数的分类 129n
    8.2 函数的定义与声明 130n
    8.2.1 函数的定义 130n
    8.2.2 函数的声明 131n
    8.3 函数的参数和返回值 131n
    8.3.1 函数的参数 131n
    8.3.2 函数的返回值 132n
    8.4 函数的调用 133n
    8.4.1 函数调用的方式 133n
    8.4.2 参数传递方式 134n
    8.4.3 函数的嵌套调用 137n
    8.4.4 递归调用 138n
    8.4.5 函数的重载 140n
    8.4.6 带默认值的函数 141n
    8.5 局部变量和全局变量 142n
    8.5.1 局部变量 143n
    8.5.2 全局变量 143n
    8.6 变量的存储类别 144n
    8.7 内部函数和外部函数 145n
    8.8 内联函数 147n
    8.9 编译预处理 149n
    8.10 综合案例 153n
    8.11 疑难解答 156n
    第 9 章 内存的快捷方式——指针n
    9.1 指针概述 158n
    9.1.1 计算机内存地址 158n
    9.1.2 定义指针和取出指针指向地址中的数据 158n
    9.1.3 初始化指针和指针赋值 159n
    9.1.4 指针的运算 161n
    9.2 指针和数组 162n
    9.2.1 指针和一维数组 162n
    9.2.2 指针和二维数组 164n
    9.2.3 指针和字符数组 166n
    9.2.4 字符指针和字符数组对比 168n
    9.2.5 指向指针的指针 168n
    9.2.6 指针数组和数组指针 169n
    9.3 指针和函数 170n
    9.3.1 函数指针 170n
    9.3.2 返回指针的函数 171n
    9.3.3 指针与传递数组的函数 173n
    9.4 const 指针 174n
    9.5 特殊的指针 176n
    9.5.1 void指针类型 176n
    9.5.2 空指针 177n
    9.6 综合案例 178n
    9.7 疑难解答 180n
    第 10章 输入和输出n
    10.1 标准输入输出 182n
    10.1.1 输入操作符>> 182n
    10.1.2 输出操作符<< 183n
    10.2 标准格式输出流 185n
    10.2.1 常用的格式流 185n
    10.2.2 有参数的常用流 187n
    10.3 其他输入输出使用的函数 187n
    10.4 随机数发生器函数 188n
    10.5 字符串操作 189n
    10.6 综合案例 191n
    10.7 疑难解答 193n
    第 Ⅱ 篇核心技术n
    第 11章 面向对象编程基础——类和对象n
    11.1 类与对象概述 197n
    11.1.1 类的声明与定义 197n
    11.1.2 对象的定义和使用 200n
    11.2 构造函数 201n
    11.3 析构函数  204n
    11.4 静态成员 207n
    11.5 友元 208n
    11.5.1 友元成员 208n
    11.5.2 友元函数 210n
    11.5.3 友元类 212n
    11.6 this指针 214n
    11.7 综合案例 215n
    11.8 疑难解答 217n
    第 12章 C++中的空间应用——命名空间n
    12.1 命名空间的定义 220n
    12.1.1 命名空间的概念 220n
    12.1.2 命名空间的定义 220n
    12.2 命名空间成员的使用 222n
    12.2.1 using声明 222n
    12.2.2 using指令 222n
    12.3 类和命名空间的关系 224n
    12.4 自定义命名空间 225n
    12.5 作用域 227n
    12.6 综合案例 230n
    12.7 疑难解答 232n
    第 13章 继承与派生n
    13.1 继承概述 234n
    13.1.1 什么是继承 234n
    13.1.2 基类与派生类 234n
    13.2 单继承 235n
    13.3 多继承与多重继承 238n
    13.3.1 多继承的引用 239n
    13.3.2 二义性 239n
    13.4 虚继承和虚基类 241n
    13.4.1 虚继承的概念 241n
    13.4.2 虚继承的语法 241n
    13.5 派生 243n
    13.5.1 派生类的生成过程 243n
    13.5.2 基类的使用 244n
    13.5.3 派生类的使用 244n
    13.6 综合案例 245n
    13.7 疑难解答 246n
    第 14章 多态与重载n
    14.1 多态概述 248n
    14.2 虚函数 250n
    14.3 构造函数多态 252n
    14.4 抽象类 257n
    14.5 重载概述 259n
    14.5.1 运算符重载 259n
    14.5.2 函数重载 262n
    14.6 综合案例 267n
    14.7 疑难解答 269n
    第 15章 文件操作n
    15.1 什么是文件 272n
    15.1.1 文件的分类 272n
    15.1.2 C++如何使用文件 272n
    15.2 文件的打开和关闭 273n
    15.2.1 打开文件 273n
    15.2.2 关闭文件 274n
    15.3 文件的读写 275n
    15.3.1 文本文件的读写 275n
    15.3.2 二进制文件的读写 276n
    15.4 文件中实现定位到每个数据 277n
    15.5 文件中的数据随机访问 278n
    15.6 综合案例 279n
    15.7 疑难解答 286n
    第 16章 容器n
    16.1 容器的概念 288n
    16.2 迭代器 288n
    16.3 顺序容器 289n
    16.4 向量的使用 289n
    16.5 列表 294n
    16.6 关联容器 296n
    16.7 映射 296n
    16.8 适配器 299n
    16.8.1 容器适配器 299n
    16.8.2 stack容器 299n
    16.9 综合案例 301n
    16.10 疑难解答 302n
    第 17章 模板n
    17.1 模板的概念 304n
    17.1.1 模板的定义 304n
    17.1.2 模板的作用 304n
    17.1.3 模板的语法 304n
    17.2 模板的编译模型 308n
    17.2.1 包含编译模型 308n
    17.2.2 分离编译模型 310n
    17.3 模板的特化 310n
    17.3.1 函数模板的特化 311n
    17.3.2 类模板的特化 311n
    17.3.3 类模板的偏特化 312n
    17.4 综合案例 314n
    17.5 疑难解答 316n
    第 18章 预处理n
    18.1 预处理概述 318n
    18.2 函数对象 318n
    18.2.1 函数对象的应用 318n
    18.2.2 自定义函数对象 318n
    18.3 常见的预处理 319n
    18.3.1 文件包含 319n
    18.3.2 条件编译 320n
    18.3.3 布局控制 321n
    18.3.4 宏替代 322n
    18.3.5 其他预编译命令 324n
    18.4 综合案例 324n
    18.5 疑难解答 326n
    第 19章 异常处理n
    19.1 异常的类型 328n
    19.1.1 常见异常 328n
    19.1.2 异常的分类 328n
    19.2 异常处理的基本思想 329n
    19.3 异常处理语句 329n
    19.3.1 异常处理语句块 329n
    19.3.2 使用 try…catch 处理异常 330n
    19.4 多种异常的捕获 333n
    19.5 异常的重新抛出 335n
    19.6 构造函数异常的处理 337n
    19.7 综合案例 339n
    19.7.1 强制类型转换异常处理 339n
    19.7.2 读写文件异常处理 341n
    19.8 疑难解答 342n
    第 20章 网络编程技术n
    20.1 网络编程基础 344n
    20.1.1 TCP/IP 协议 344n
    20.1.2 WinSock 套接字 345n
    20.2 TCP 可靠连接 349n
    20.2.1 服务器端 349n
    20.2.2 客户端 350n
    20.3 UDP 消息传输 352n
    20.3.1 服务器端 352n
    20.3.2 客户端 353n
    20.4 综合案例 354n
    20.5 疑难解答 358n
    第 21章 数据库编程技术n
    21.1 数据库基础知识 360n
    21.1.1 数据库系统概述 360n
    21.1.2 数据库管理系统 360n
    21.1.3 数据库安装及使用 361n
    21.2 SQL 366n
    21.2.1 SQL 的特点 366n
    21.2.2 SQL 语句 367n
    21.2.3 SQL 中的常用函数 369n
    21.3 C++ 与数据库交互 371n
    21.3.1 IDE 配置 371n
    21.3.2 数据库连接 372n
    21.3.3 基本操作 374n
    21.4 数据库访问接口 376n
    21.4.1 ADO 访问技术 377n
    21.4.2 ODBC 访问技术 378n
    21.5 综合案例 379n
    21.6 疑难解答 385n
    第 22章 用户界面编程及游戏编程n
    22.1 Windows 编程基础 388n
    22.1.1 API 与SDK 388n
    22.1.2 窗体与句柄 388n
    22.1.3 Windows 应用程序组成 388n
    22.2 GDI 基础 390n
    22.2.1 GDI 概述 390n
    22.2.2 设备描述表 391n
    22.2.3 绘图对象 391n
    22.2.4 GDI 绘图 391n
    22.3 位图 395n
    22.4 图标与菜单 397n
    22.5 控件的使用 400n
    22.5.1 控件的创建与响应 400n
    22.5.2 对话框的使用 402n
    22.6 常用的游戏算法 404n
    22.6.1 递归算法 404n
    22.6.2 枚举算法 406n
    22.6.3 动态规划 406n
    22.6.4 贪心算法 409n
    22.6.5 回溯算法 411n
    22.7 综合案例 413n
    22.8 疑难解答 426n
    第 Ⅲ 篇提高篇n
    第 23章 网络应用项目n
    23.1 项目需求分析 429n
    23.1.1 C/S模式 429n
    23.1.2 C/S模式的运作流程 429n
    23.2 实现原理 430n
    23.3 具体实现 430n
    23.3.1 服务器端 430n
    23.3.2 客户端 435n
    23.4 疑难解答 440n
    第 24章 DirectX基础与应用n
    24.1 DirectX基础 442n
    24.2 概述 442n
    24.3 基本结构与组成 442n
    24.3.1 基于COM的DirectX  442n
    24.3.2 DirectX的组成 443n
    24.4 Direct3D应用 443n
    24.4.1 框架 443n
    24.4.2 顶点及索引缓存 445n
    24.5 表面与位图 450n
    24.6 DirectShow与DirectSound 460n
    24.7 综合案例 461n
    24.8 疑难解答 465n
    第 25章 专业理财系统n
    25.1 开发背景 468n
    25.2 需求及功能分析 468n
    25.2.1 需求分析 468n
    25.2.2 总体功能分析 469n
    25.2.3 各功能模块设计 470n
    25.3 系统功能的实现 473n
    25.3.1 系统整体功能的实现 473n
    25.3.2 系统界面功能的实现 474n
    25.3.3 登录功能的实现 474n
    25.3.4 创建表格模块的实现 475n
    25.3.5 增添信息模块的实现 476n
    25.3.6 删除信息模块的实现 477n
    25.3.7 查询信息模块的实现 477n
    25.3.8 修改信息模块的实现 478n
    25.3.9 统计信息模块的实现 480n
    25.3.10  数据管理模块的实现 481n
    25.4 系统运行 481n
    25.5 疑难解答 486

    展开阅读
    精选笔记1:Python与C/C++的相互调用案例

    21小时34分钟前回答

    一、问题

    Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结。

    二、Python调用C/C++

    1、Python调用C动态链接库

    Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。

    (1)C语言文件:pycall.c

    /***gcc -o libpycall.so -shared -fPIC pycall.c*/
    #include <stdio.h>
    #include <stdlib.h>
    int foo(int a, int b)
    {
     printf("you input %d and %d\n", a, b);
     return a+b;
    }

    (2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern "C"来进行编译。

    (3)Python调用动态库的文件:pycall.py

    import ctypes
    ll = ctypes.cdll.LoadLibrary 
    lib = ll("./libpycall.so") 
    lib.foo(1, 3)
    print '***finish***'

    (4)运行结果:

    2、Python调用C++(类)动态链接库

    需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern "C",构建后的动态链接库没有这些函数的符号表。

    (1)C++类文件:pycallclass.cpp

    #include <iostream>
    using namespace std;
     
    class TestLib
    {
     public:
      void display();
      void display(int a);
    };
    void TestLib::display() {
     cout<<"First display"<<endl;
    }
    void TestLib::display(int a) {
     cout<<"Second display:"<<a<<endl;
    }
    extern "C" {
     TestLib obj;
     void display() {
      obj.display(); 
      }
     void display_int() {
      obj.display(2); 
      }
    }

    (2)g++编译生成动态库libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。

    (3)Python调用动态库的文件:pycallclass.py

    import ctypes
    so = ctypes.cdll.LoadLibrary 
    lib = so("./libpycallclass.so") 
    print 'display()'
    lib.display()
    print 'display(100)'
    lib.display_int(100)

    (4)运行结果:

    3、Python调用C/C++可执行程序

    (1)C/C++程序:main.cpp

    #include <iostream>
    using namespace std;
    int test()
    {
     int a = 10, b = 5;
     return a+b;
    }
    int main()
    {
     cout<<"---begin---"<<endl;
     int num = test();
     cout<<"num="<<num<<endl;
     cout<<"---end---"<<endl;
    }

    (2)编译成二进制可执行文件:g++ -o testmain main.cpp。

    (3) Python调用程序:main.py

    import commands
    import os
    main = "./testmain"
    if os.path.exists(main):
     rc, out = commands.getstatusoutput(main)
     print 'rc = %d, \nout = %s' % (rc, out)
     
    print '*'*10
    f = os.popen(main) 
    data = f.readlines() 
    f.close() 
    print data
     
    print '*'*10
    os.system(main)

    (4)运行结果:

    4、扩展Python(C++为Python编写扩展模块)

    所有能被整合或导入到其它python脚本的代码,都可以被称为扩展。可以用Python来写扩展,也可以用C和C++之类的编译型的语言来写扩展。Python在设计之初就考虑到要让模块的导入机制足够抽象。抽象到让使用模块的代码无法了解到模块的具体实现细节。Python的可扩展性具有的优点:方便为语言增加新功能、具有可定制性、代码可以实现复用等。

    为 Python 创建扩展需要三个主要的步骤:创建应用程序代码、利用样板来包装代码和编译与测试。

    (1)创建应用程序代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int fac(int n)
    {
     if (n < 2) return(1); /* 0! == 1! == 1 */
     return (n)*fac(n-1); /* n! == n*(n-1)! */
    }
    char *reverse(char *s)
    {
     register char t,     /* tmp */
       *p = s,      /* fwd */
       *q = (s + (strlen(s) - 1)); /* bwd */
     while (p < q)    /* if p < q */
     {
      t = *p;   /* swap & move ptrs */
      *p++ = *q;
      *q-- = t;
     }
     return(s);
    }
    int main()
    {
     char s[BUFSIZ];
     printf("4! == %d\n", fac(4));
     printf("8! == %d\n", fac(8));
     printf("12! == %d\n", fac(12));
     strcpy(s, "abcdef");
     printf("reversing 'abcdef', we get '%s'\n", \
      reverse(s));
     strcpy(s, "madam");
     printf("reversing 'madam', we get '%s'\n", \
      reverse(s));
     return 0;
    }

    上述代码中有两个函数,一个是递归求阶乘的函数fac();另一个reverse()函数实现了一个简单的字符串反转算法,其主要目的是修改传入的字符串,使其内容完全反转,但不需要申请内存后反着复制的方法。

    (2)用样板来包装代码

    接口的代码被称为“样板”代码,它是 应用程序代码与Python解释器之间进行交互所必不可少的一部分。样板主要分为4步:a、包含Python的头文件;b、为每个模块的每一个函数增加一个型如PyObject* Module_func()的包装函数;c、为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组;d、增加模块初始化函数void initModule()。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int fac(int n)
    {
     if (n < 2) return(1);
     return (n)*fac(n-1);
    }
    char *reverse(char *s)
    {
     register char t,
       *p = s,
       *q = (s + (strlen(s) - 1));
     while (s && (p < q))
     {
      t = *p;
      *p++ = *q;
      *q-- = t;
     }
     return(s);
    }
    int test()
    {
     char s[BUFSIZ];
     printf("4! == %d\n", fac(4));
     printf("8! == %d\n", fac(8));
     printf("12! == %d\n", fac(12));
     strcpy(s, "abcdef");
     printf("reversing 'abcdef', we get '%s'\n", \
      reverse(s));
     strcpy(s, "madam");
     printf("reversing 'madam', we get '%s'\n", \
      reverse(s));
     return 0;
    }
    #include "Python.h"
    static PyObject *
    Extest_fac(PyObject *self, PyObject *args)
    {
     int num;
     if (!PyArg_ParseTuple(args, "i", &num))
      return NULL;
     return (PyObject*)Py_BuildValue("i", fac(num));
    }
    static PyObject *
    Extest_doppel(PyObject *self, PyObject *args)
    {
     char *orig_str;
     char *dupe_str;
     PyObject* retval;
     if (!PyArg_ParseTuple(args, "s", &orig_str))
      return NULL;
     retval = (PyObject*)Py_BuildValue("ss", orig_str,
      dupe_str=reverse(strdup(orig_str)));
     free(dupe_str);    #防止内存泄漏
     return retval;
    }
    static PyObject *
    Extest_test(PyObject *self, PyObject *args)
    {
     test();
     return (PyObject*)Py_BuildValue("");
    }
    static PyMethodDef
    ExtestMethods[] =
    {
     { "fac", Extest_fac, METH_VARARGS },
     { "doppel", Extest_doppel, METH_VARARGS },
     { "test", Extest_test, METH_VARARGS },
     { NULL, NULL },
    };
    void initExtest()
    {
     Py_InitModule("Extest", ExtestMethods);
    }

    Python.h头文件在大多数类Unix系统中会在/usr/local/include/python2.x或/usr/include/python2.x目录中,系统一般都会知道文件安装的路径。

    增加包装函数,所在模块名为Extest,那么创建一个包装函数叫Extest_fac(),在Python脚本中使用是先import Extest,然后调用Extest.fac(),当 Extest.fac()被调用时,包装函数 Extest_fac()会被调用,包装函数接受一个 Python的整数参数,把它转为C的整数,然后调用C的fac()函数,得到一个整型的返回值,最后把这个返回值转为Python的整型数做为整个函数调用的结果返回回去。其他两个包装函数Extest_doppel()和Extest_test()类似。

    从Python到C的转换用PyArg_Parse*系列函数, int PyArg_ParseTuple():把Python传过来的参数转为C;int PyArg_ParseTupleAndKeywords()与PyArg_ParseTuple()作用相同,但是同时解析关键字参数;它们 的用法跟C的sscanf函数很像,都接受一个字符串流,并根据一个指定的格式字符串进行解析,把结果放入到相应的指针所指的变量中去,它们的返回值为1表示解析成功,返回值为0表示失败。 从C到Python的转换函数是PyObject* Py_BuildValue():把C的数据转为Python的一个对象或一组对象,然后返回之;Py_BuildValue的用法跟sprintf很像,把所有的参数按格式字符串所指定的格式转换成一个Python的对象。

    C与Python之间数据转换的转换代码:

    为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组,以便于Python解释器能够导入并调用它们,每一个数组都包含了函数在Python中的名字,相应的包装函数的名字以及一个METH_VARARGS常量,METH_VARARGS表示参数以tuple形式传入。 若需要使用 PyArg_ParseTupleAndKeywords()函数来分析命名参数的话,还需要让这个标志常量与METH_KEYWORDS常量进行逻辑与运算常量 。数组最后用两个NULL来表示函数信息列表的结束。

    所有工作的最后一部分就是模块的初始化函数,调用Py_InitModule()函数,并把模块名和ModuleMethods[]数组的名字传递进去,以便于解释器能正确的调用模块中的函数。

    (3)编译

    为了让新Python的扩展能被创建,需要把它们与Python库放在一起编译,distutils包被用来编译、安装和分发这些模块、扩展和包。

    创建一个setup.py 文件,编译最主要的工作由setup()函数来完成:

    #!/usr/bin/env python 
    from distutils.core import setup, Extension 
    MOD = 'Extest'
    setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest2.c'])])

    Extension()第一个参数是(完整的)扩展的名字,如果模块是包的一部分的话,还要加上用'.'分隔的完整的包的名字。上述的扩展是独立的,所以名字只要写"Extest"就行;sources参数是所有源代码的文件列表,只有一个文件Extest2.c。setup需要两个参数:一个名字参数表示要编译哪个内容;另一个列表参数列出要编译的对象,上述要编译的是一个扩展,故把ext_modules参数的值设为扩展模块的列表。

    运行setup.py build命令就可以开始编译我们的扩展了,提示部分信息:

    creating build/lib.linux-x86_64-2.6
    gcc -pthread -shared build/temp.linux-x86_64-2.6/Extest2.o -L/usr/lib64 -lpython2.6 -o build/lib.linux-x86_64-2.6/Extest.so
    

    (4)导入和测试

    你的扩展会被创建在运行setup.py脚本所在目录下的build/lib.*目录中,可以切换到那个目录中来测试模块,或者也可以用命令把它安装到Python中:python setup.py install,会提示相应信息。

    测试模块:

    (5)引用计数和线程安全

    Python对象引用计数的宏:Py_INCREF(obj)增加对象obj的引用计数,Py_DECREF(obj)减少对象obj的引用计数。Py_INCREF()和Py_DECREF()两个函数也有一个先检查对象是否为空的版本,分别为Py_XINCREF()和Py_XDECREF()。

    编译扩展的程序员必须要注意,代码有可能会被运行在一个多线程的Python环境中。这些线程使用了两个C宏Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS, 通过将代码和线程隔离,保证了运行和非运行时的安全性,由这些宏包裹的代码将会允许其他线程的运行。

    三、C/C++调用Python

    C++可以调用Python脚本,那么就可以写一些Python的脚本接口供C++调用了,至少可以把Python当成文本形式的动态链接库,

    需要的时候还可以改一改,只要不改变接口。缺点是C++的程序一旦编译好了,再改就没那么方便了。

    (1)Python脚本:pytest.py

    #test function
    def add(a,b):
     print "in python function add"
     print "a = " + str(a)
     print "b = " + str(b)
     print "ret = " + str(a+b)
     return
     
    def foo(a):
     
     print "in python function foo"
     print "a = " + str(a)
     print "ret = " + str(a * a)
     return 
     
    class guestlist:
     def __init__(self):
      print "aaaa"
     def p():
     print "bbbbb"
     def __getitem__(self, id):
     return "ccccc"
    def update():
     guest = guestlist()
     print guest['aa']
     
    #update()

    (2)C++代码:

    /**g++ -o callpy callpy.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config -lpython2.6**/
    #include <Python.h>
    int main(int argc, char** argv)
    {
     // 初始化Python
     //在使用Python系统前,必须使用Py_Initialize对其
     //进行初始化。它会载入Python的内建模块并添加系统路
     //径到模块搜索路径中。这个函数没有返回值,检查系统
     //是否初始化成功需要使用Py_IsInitialized。
     Py_Initialize();
     
     // 检查初始化是否成功
     if ( !Py_IsInitialized() ) {
      return -1;
     }
     // 添加当前路径
     //把输入的字符串作为Python代码直接运行,返回0
     //表示成功,-1表示有错。大多时候错误都是因为字符串
     //中有语法错误。
     PyRun_SimpleString("import sys");
     PyRun_SimpleString("print '---import sys---'"); 
     PyRun_SimpleString("sys.path.append('./')");
     PyObject *pName,*pModule,*pDict,*pFunc,*pArgs;
     
     // 载入名为pytest的脚本
     pName = PyString_FromString("pytest");
     pModule = PyImport_Import(pName);
     if ( !pModule ) {
      printf("can't find pytest.py");
      getchar();
      return -1;
     }
     pDict = PyModule_GetDict(pModule);
     if ( !pDict ) {
      return -1;
     }
     
     // 找出函数名为add的函数
     printf("----------------------\n");
     pFunc = PyDict_GetItemString(pDict, "add");
     if ( !pFunc || !PyCallable_Check(pFunc) ) {
      printf("can't find function [add]");
      getchar();
      return -1;
      }
     
     // 参数进栈
     PyObject *pArgs;
     pArgs = PyTuple_New(2);
     
     // PyObject* Py_BuildValue(char *format, ...)
     // 把C++的变量转换成一个Python对象。当需要从
     // C++传递变量到Python时,就会使用这个函数。此函数
     // 有点类似C的printf,但格式不同。常用的格式有
     // s 表示字符串,
     // i 表示整型变量,
     // f 表示浮点数,
     // O 表示一个Python对象。
     
     PyTuple_SetItem(pArgs, 0, Py_BuildValue("l",3));
     PyTuple_SetItem(pArgs, 1, Py_BuildValue("l",4));
     
     // 调用Python函数
     PyObject_CallObject(pFunc, pArgs);
     
     //下面这段是查找函数foo 并执行foo
     printf("----------------------\n");
     pFunc = PyDict_GetItemString(pDict, "foo");
     if ( !pFunc || !PyCallable_Check(pFunc) ) {
      printf("can't find function [foo]");
      getchar();
      return -1;
      }
     
     pArgs = PyTuple_New(1);
     PyTuple_SetItem(pArgs, 0, Py_BuildValue("l",2)); 
     
     PyObject_CallObject(pFunc, pArgs);
      
     printf("----------------------\n");
     pFunc = PyDict_GetItemString(pDict, "update");
     if ( !pFunc || !PyCallable_Check(pFunc) ) {
      printf("can't find function [update]");
      getchar();
      return -1;
      }
     pArgs = PyTuple_New(0);
     PyTuple_SetItem(pArgs, 0, Py_BuildValue(""));
     PyObject_CallObject(pFunc, pArgs);  
     
     Py_DECREF(pName);
     Py_DECREF(pArgs);
     Py_DECREF(pModule);
     
     // 关闭Python
     Py_Finalize();
     return 0;
    } 

    (3)C++编译成二进制可执行文件:g++ -o callpy callpy.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config -lpython2.6,编译选项需要手动指定Python的include路径和链接接路径(Python版本号根据具体情况而定)。

    (4)运行结果:

    四、总结

    (1)Python和C/C++的相互调用仅是测试代码,具体的项目开发还得参考Python的API文档。

    (2)两者交互,C++可为Python编写扩展模块,Python也可为C++提供脚本接口,更加方便于实际应用。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持码农之家。如有错误或未考虑完全的地方,望不吝赐教。

    展开阅读

    C++相关资源

    • C++ Primer Plus(第6版)中文版习题解答

      C++ Primer Plus(第6版)中文版习题解答

      《C Primer Plus(第6版)中文版习题解答》是超级畅销书《C Primer Plus(第6版)中文版》的配套习题答案,针对书中的复习题和编程练习,给出了解题思路和答案。 《C Primer Plus(第6版)中文版习题解答》共分为18章,每一章的主题与《C Primer Plus(第6版)中文版》完全一致。每章开篇采用思维导图的方式列出本章的知识点,然后对每章的重点内容进行了梳理总结,*后则对每章中的复习题和编程练习进行了分析并给出了解答思路,确保读者在彻底夯实理论知

      大小:103 MBC++

      立即下载
    • Visual C++打印编程技术与工程实践

      Visual C++打印编程技术与工程实践

      VisualC++打印编程技术与工程实践 作者:求是科技李鲲程 出版时间:2003/9/1 本书介绍利用VisualC++编制常用打印程序的技术,全书分为9章。第1章主要介绍打印编程所需要的基础知识,第2章介绍了打印控制技术,第3章“打印预览”分析了VisualC++框架中的打印预览机制,并介绍了其实现方法,第4章介绍了打印条形码的方法和技巧,第5章介绍了打印信封的方法,第6章介绍了打印商业专用发票的编程方法,第7章介绍了图片打印的编程方法,第8章介绍了简历的编

      大小:30.68 MBC++

      立即下载
    • C++语言程序设计(第3版)

      C++语言程序设计(第3版)

      本书将C++语言作为大学生学习程序设计的人门语言,不仅详细介绍了语言本身,而且介绍了常用的数据结构和算法。全书以面向对象的程序设计方法贯穿始终,每一章都首先阐述面向对象的程序设计思想和方法,然后引出必要的语法知识,在讲解语法时着重从程序设计方法学的角度讲述其意义和 用途,力求使读者在掌握C++语言的同时,能够对现实世界中较简单的问题及其解决方法用计算机语言进行描述。针对初学者和自学读者的特点,书中以结合实例讲解基本概

      大小:4.74 MBC++语言

      立即下载
    • Visual C++实践与提高:图形图像编程篇

      Visual C++实践与提高:图形图像编程篇

      VisualC++实践与提高—图形图像编程篇 作者:李于剑 丛书名:计算机编程实践与提高系列 中国铁道 出版日期:2001年7月 本书将向读者讲述如何用VisualC++进行图形图像编程。本书共分为图形篇、图像篇、综合提高篇。图形篇以计算机绘图的基础知识为铺垫,介绍了各种图形元素的绘制方法,并结合实际代码实现了一个小型的绘图系统;图像篇通过实例向读者介绍了不同格式图像的处理方法,并给出了一些特效处理的技巧;综合提高篇综合应用了图形图像

      大小:16.32 MBC++

      立即下载
    • C++ GUI Qt4编程

      C++ GUI Qt4编程

      本书详细讲述了使用更新的Qt版本进行图形用户界面应用程序开发的各个方面。全书分为四个部分,共24章及4个附录:*部分介绍Qt的基础知识和编写图形用户界面应用程序时所需的基本概念

      大小:152.3 MBQt

      立即下载
    • C++面向对象程序设计教程(第3版)

      C++面向对象程序设计教程(第3版)

      学过程序设计的人,都有一个体会,看别人编写的程序,好像挺明白的,但是一旦要自己编写一个程序,就感觉无从下手。这是因为程序设计是一门对实践环节要求很高的课程,初学者要想真正学会C++面向对象程序设计,最重要的是抓住两个关键环节: 一个是多做习题多编程; 另一个就是多上机,写在纸上的程序是否正确,最好的办法就是上机验证。为此,我们编写了这本习题解答与上机指导书,以期帮助读者尽快地掌握C++语言程序设计的基本规则与编程

      大小:280 KBC++

      立即下载

    学习笔记

    20小时57分钟前回答

    详解python如何调用C/C++底层库与互相传值

    前言 开发环境: Centos 7 + Python 3.5.1 + Qt Creator(只是使用Qt Creator编译而已,并没有使用QT的任何库) Python调用C/C++库,我现在能做到的有两种方式 1.extern “C” 导出 (互相传值比较麻烦,不建议使用这种方式): 将C/C++库做成和平常一样的DLL和或者.so,比如: //.h文件#include Python.h//.cpp文件//C/C++ my.so 或者my.dllenter "C" void printHello(){ std::cout"Hello World"std::endl;} #Pythonimport ctypes from ctypes import *loadso = ctypes.cdll.LoadLibrary mylib = loadso("./my.so")mylib.printHello()Hello world 代码解释: my.so 有一个C导出函数 printHello() import ctypes : 导入官方的一个库,顾名思义和C有关 loadso = ctypes.cdll.LoadLibrary : loadso 表示加载库用的函数 mylib ……

    23小时19分钟前回答

    PHP中调用C/C++制作的动态链接库的教程

    一般而言,php速度已经比较快,但是,对于一些较高级开发者而言,如果想要追求更快的速度,那毫无疑问可以通过自己写c代码,并编译为动态链接库(常为.so文件),然后php通过创建一个新的扩展(extension),并在扩展里调用该.so文件,同时对外暴露出php函数接口。 在实际使用中,只要调用该函数接口,即可使用底层更快速的c函数服务。 一、动态链接库(shared) 动态链接库的文件名后缀通常是 ".so"。在Windows系统中,其文件名后缀是".dll"。 程序如果是和动态连接库进行链接(link),程序运行时需要能够找到相应的动态链接库文件。 使用动态链接库存编译的程序在运行时要求用户的机器上必需也安装了相应……