C语言精简概述
C语言语法
C语言的注释
- 多行注释:/…/
- 单行注释://
- 注释完全被编译器忽略掉,但多工具可以提取注释形成文档。
C语言的所属关系
- 大括号表达所属关系:{…}
- 函数、分支、循环等定义中使用。
- 表达式用分号;分隔,表示结束。
C语言的声明
- 变量及函数需要先声明再使用,声明要指定类型。
- 声明需要使用保留字或内置数据类型(char\int等)。
- 相关保留字:struct,union,enum。
C语言的程序控制结构
- 分支:if ,if-else,switch-case,default,goto。
- 循环:do-while,while,for,break,continue。
- 分支和循环都可以嵌套定义和使用。
C语言的字符集
- 字母和数字:a-z A-Z 0-9。
- 特殊字符:! " # % & ’ () * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~
- 隐式字符:空格、制表符TAB、换行等。
等…这里就不概述了,会C或C++的应该大概能读懂,没学过的可能需要十几周时间去学。
Python与C/C++交互的三种方式
- python扩展:在python程序中调用C/C++编写的库。
- python嵌入:在C/C++程序中调用python程序。
- python调用:python和C间以程序级别互相调用。
python与C/C++交互的价值
- 整合python高产与C/C++高效的优势。
- 利用C或python已有功能服务彼此的程序。
- python作为粘性脚本语言整合或被整合到各类独立程序。
Python扩展:在Python程序中调用C/C++编写的库
- 目的:提升关键代码性能、引入C语言成熟功能库。
- Cython、swig、ctypes、CFFI。
- 形式:Python为主程序,C通过.dll/.so形式使用。
Python嵌入:在C/C++程序中调用Python程序
- 目的:利用Python高产、引入Python成熟功能库。
- 方式:Python/C API。
- 形式:C/C++为主程序,Python通过源文件形式使用。
Python调用:Python和C间以程序级别互相调用。
- 目的:模块间功能互用,以功能使用为目标。
- 方式:子进程或线程方式,即subprocess。
- 形式:C/C++和Python都是独立程序。
Python扩展:十分重要,Python程序员必学必会。
Python嵌入:一般重要,Python程序员可以掌握。
Python调用:比较重要,Python程序员应该掌握。
Python扩展
Cython:实现Python扩展的一种语言,第三方库
- 思路:一种简单的语言来实现Python和C接口。
- 方式:采用了Pyrex语法形式。
- 结果:采用C数据类型的Python编程,实现混合编程。
SWIG:一个将C/C++与脚本语言相整合的编译器,独立工具。
- 思路:通过一个编译器来实现Python和C的接口。
- 方式:纯C/C++编程,通过编写接口变成Python模块。
- 结果:独立C和Python编程,重点在于编写接口(描述)。
ctypes:调用DLL或共享库的Python功能函数库,标准库API
- 思路:通过一个Python标准库实现Python扩展。
- 方式:C语言功能遍为.dll或.so库,加载库及调用函数,API。
- 结果:C语言独立编程,Python使用库调用接口函数。
CFFI:在Python中直接使用C函数的方式,第三方库
- 思路:类似ctypes,使用API扩展C程序,也可以直接混合编程。
- 方式:关注C函数的访问接口,而不是库函数,构建API。
- 结果:C语言独立编程,Python用CFFI扩展,最小学习代价。
Python嵌入:在C/C++程序中调用Python程序
- 目的:利用Python高产,引入Python成熟功能库。
- 方式:Python/C API
- 形式:C/C++为主程序,Python通过源文件形式使用。
Python/C API:Python嵌入的主要接口
- 嵌入Python语句:嵌入一个或多个Python语句。
- 嵌入Python脚本:嵌入一个或多个Python文件。
- Python/C API需要加载Python解释器及加载Python语句和脚本。
Python/C API:Python嵌入的主要接口
- Python/C API是一组能够在C语言下执行的类型定义和函数。
- 头文件:Python.h
- 函数:加载Python解释器、嵌入Python语句及脚本、数据类型转换等。
Python嵌入:最小实例
#include<Python.h> //导入头文件
int main()
{
Py_Initialize(); //初始化Python解释器
PyRun_SimpleString("print(eval('1+2'))"); //运行Python语句
Py_Finalize(); //退出Python解释器
return 0;
}
加载Python解释器
函数 | 描述 |
---|---|
Py_Initialize() | 初始化Python解释器,加载builtins、_ _ main _ _ 、sys等。 |
Py_Finalize() | 终结化Python解释器,释放解释器占用的内存。 |
PyRun_SimpleString(const char * cmd) | 在 _ _ main _ _ 模块中执行一条语句,如果 _ _ main _ _ 不存在则创建。 |
PyRun_SimpleFile(FILE *fp,const char * fname) | 在C中调用一个Python文件。 |
#include <Python.h>
int main()
{
char fname[]="mxmul.py";
FILE *fp=fopen(fname,"r"); //指定打开文件
if (fp==NULL)
{
printf("fopen error");
return 1;
}
Py_Initialize();
PyRun_SimpleFile(fp,fname); //调用并执行文件
Py_Finalize();
return 0;
}
Python调用:Python和C间以程序级别互相调用
- 目标:模块间功能互用,以功能使用为目标。
- 方式:子进程或线程方式,即subprocess。
- 形式:C/C++和Python都是独立程序。
在Python中调用C语言程序
- 使用Python的subprocess模块。
- 步骤1:准备好C语言编写的带调用程序。
- 步骤2:使用subprocess模块调用并执行程序。
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
int a;
a=atoi(argv[1])
printf("input x:%d\n",a);
printf("pow(x) :%d\n",a*a)
return 0;
}
import subprocess
subprocess.run(["c_app.exe","9"])
#命令执行后结果是:
#input x:9
#pow(x):81
函数 | 描述 |
---|---|
subprocess.run(args) | 执行args指定的一个程序,args可以是一个字符串或列表。字符串:一个程序的名字,如:a.exe。列表:程序名称和参数的列表,如[“c_app.exe”,“9”]。 |
在C中调用Python程序
- 使用C的system()函数。
- 步骤1:准备好Python编写的待调用程序。
- 步骤2:使用system()函数调用并执行程序。
import sys
print("input x:{}",sys.argv[1])
print("pow(x) :{}",pow(int(sys.argv[1]),2))
#py_app.py待调用Python程序
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("py_app.py 9");
return 0;
}
//C/C++下标准函数,C89定义,将指令和参数以字符指针作为参数传递执行。
Python扩展的CFFI方式
CFFI:C Foreign Function Interface for Python
- 思路:类似ctypes,使用API扩展C程序,也可以直接混合编程。
- 方式:关注C函数的访问接口,而不是库函数,构建API。
- 结果:C语言独立编程,Python用CFFI扩展,最小学习代价。
- 库扩展:对已经编译的C语言.dll或.so库调用并使用。
- 标准库:C语言标准库的调用及使用。
- 数据类型:C语言与Python数据类型的转换。
- 第三方库,需要安装:pip install cffi。
- 查阅文档:CFFI是一种流程或机制。
- 平台相关:Windows平台.dll、Linux平台.so、32位/64位等。
C语言数据类型相关的接口
函数 | 描述 |
---|---|
ffi.NULL | 相当于常量值 |
ffi.new(cdecl) | 数组或指针的生成,new(‘x*’)或new(‘x[n]’) |
ffi.cast(ctype,value) | C数据类型的声明,ctype是类型名,value是变量名cast(‘int’,x) |
ffi.string(cdata) | 从cdata类型中返回一个Python字符串 |
ffi.unpack(cdata,length) | 从cdata数组中获取特定长度,返回一个Python字符串或列表 |
ffi.typeof(ctype) | 返回ctype的长度 |
ffi.sizeof(object) | 返回object对象的长度 |
ffi.alignof(ctype) | 返回ctype或对象的长度 |
ffi.dlopen(libpath) | 打开动态链接库并建立一个句柄 |
ffi.dlclose(lib) | 关闭动态链接库并释放句柄 |
ffi.cdef(str) | str指明Python中需要使用的C类型、函数等声明 |
ffi.memmove(dst,src,n) | 从src向dst拷贝n直接内容,注意src和dst都是Python变量 |
Python计算生态:>15万个,每个都不一样
- 该怎么学呢?如何最有效呢?
- 阅读+理解+实践。
- 阅读官方文档+理解设计及应用理念+实践典型及拓展案例。
一起来学习CFFI库
- 阅读:https://cffi.readthedocs.io,文档不长。
- 理解:理解设计方法及应用理念。
- 实践:典型案例参考实例2,扩展案例请结合工作需要完成。
- 平台:操作系统平台很重要,Windows、Linux、建议后者。
- C基础:C语言基础很重要,理解C的内涵及内存操作与管理。
- Python:对Python引用及对象的理解很重要,理解C与Python内存交互。