动态库DLL
这里以VS2017为例子,讲解一下动态链接库(.dll)的生成与使用。
一、动态链接库(.dll)的生成
1、打开:“文件”-“新建”-“项目”
2、打开:“已安装”-“模板”-“Visual C++” -“windows桌面”+“动态链接库dll”把文件“名称”加上,为自己的工程名称;把“位置”加上,为自己的工程所在位置;
3、默认生成以下文件
4、在“phc.cpp”中添加程序如下
int Moline (int i, int(call_back)(int a, int b))
{
int aa;
aa = ii;
call_back(i, aa);
return 0;
}
5、在头文件“phc.h”中添加如下代码
__declspec(dllexport) int Moline (int i, int(*call_back)(int a, int b));
6、点击“生成”-“重新生成解决方案”
7、如图,成功。
8、Debug文件夹中生成了.dll和.lib的文件
二、使用.dll文件
1、新建项目
2、打开:“已安装”-“模板”-“Visual C++” -“windows桌面”+“控制台应用“名称”加上,为自己的工程名称;把“位置”加上,为自己的工程所在位置;
3、把上一步中的“.dll”和“.lib”放到如图的文件夹里面
4、把“pch.h、framework.h”放到如图的文件夹里面
5、在Moline_dll_use.cpp文件夹里面添加如下代码
#include <stdio.h>
#include “pch.h”
int Moline_call_back(int a, int b)
{
int c;
c = a + b;
printf(“输出:%d\n”, c);
return 11;
}
void main()
{
int p = 10;
int Moline1;
Moline1 = Moline(p, Moline_call_back);
printf(“输出2:%d\n”, Moline1);
}
6、添加头文件“pch.h、framework.h”
7、添加资源文件
8、点击“重新生成解决方案”,成功。
9、执行
C的标准库
C89
1989年,美国国家标准协会(ANSI)通过了C语言标准,被称为ANSI X3.159-1989 “Programming Language C”。因为这个标准是1989年通过的,所以一般简称C89标准。有些人也简称ANSI C,因为这个标准是美国国家标准协会(ANSI)发布的。
1990年,国际标准化组织(ISO)和国际电工委员会(IEC)把C89标准定为C语言的国际标准,命名为ISO/IEC 9899:1990 - Programming languages – C。因为此标准是在1990年发布的,所以有些人把简称作C90标准。不过大多数人依然称之为C89标准,因为此标准与ANSI C89标准完全等同。
C99
C99标准是 ISO/IEC 9899:1999 - Programming languages – C 的简称,是C语言的官方标准第二版。1999年12月1日,国际标准化组织(ISO)和国际电工委员会(IEC)旗下的C语言标准委员会(ISO/IEC JTC1/SC22/WG14)正式发布了这个标准文件。
新特性
在ANSI标准化发布了C89标准以后,C语言的标准在一段相当的时间内都保持不变,尽管C++继续在改进。(实际上,Normative Amendment1在1995年已经开发了一个新的C语言版本(即C95)。但是这个版本很少为人所知。)标准在90年代才经历了改进,这就是ISO/IEC 9899:1999(1999年出版)。这个版本就是通常提及的C99。
在C99中包括的特性有:
对编译器限制增加了,比如源程序每行要求至少支持到 4095字节,变量名与函数名的要求支持到 63 字节 (extern 要求支持到 31)。
预编译处理增强了。例如:
支持了可变参数的宏(Variadic Macro): #define Macro(…) VA_ARGS
使用宏的时候,参数如果不写,宏里用 #,## 这样的东西会扩展成空串。(C89标准中会出错的)
可变参数宏的示例代码:
支持 // 行注释(这个特性实际上在C89的很多编译器上已经被支持了)
增加了新关键字restrict,inline,_Complex,_Imaginary,_Bool
支持 long long,long double _Complex,float _Complex 这样的类型
支持 <: :> <% %> %: %:%: ,等等奇怪的符号替代,D&E 里提过这个
支持了不定长的数组。数组的长度就可以用变量了。声明类型的时候呢,就用 int a[*] 这样的写法。不过考虑到效率和实现,这玩意并不是一个新类型。所以就不能用在全局里,或者 struct union 里面,如果你用了这样的东西,goto语句就受限制了。
变量声明不必放在语句块的开头,for 语句提倡这么写 for(int i=0;i<100;++i) 就是说,int i 的声明放在里面,i 只在 for 里面有效。(VC6.0没有遵守这条标准,i 在 for 外也有效;但vc2005里已经默认是i在外面不可见了,但有编译选项可以设置。)
复合字面量:当一个类似结构的东西需要临时构造的时候,可以用 (type_name){xx,xx,xx} 这有点像 C++ 的构造函数
相较于C89标准,C99标准新增了一种结构体/数组的初始化方式,名叫designated initializers,即:
struct { int a[3], b; } w[] ={ [0].a = {1}, [1].a[0] = 2 };
字符串里面,\u 支持unicode的字符
支持 16 进制的浮点数的描述
所以printf和scanf的格式化串增加了支持 “%lld"和”%llu",对应long long int类型和unsigned long long int类型(可以分别简写为long long和unsigned long long)。
浮点数的内部数据描述支持了新标准,这个可以用 #pragma编译器指定
增加了一个内置的局部静态字符数组变量 func ,可以用于得到当前函数的函数名。
对于非常量的表达式,也允许编译器做化简
修改了 /% 处理负数时的定义,这样可以给出明确的结果,例如在C89中-22 / 7 = -3, -22% 7 = -1,也可 以-22 / 7= -4, -22% 7 = 6。 而C99中明确为 -22 / 7 = -3, -22% 7 = -1,只有一种结果。
取消了不写函数返回类型默认就是 int 的规定
允许 struct 定义的最后一个数组写做 [] 不指定其长度描述
const const int i; 将被当作 const int i; 处理
增加和修改了一些标准头文件。比如定义 bool 的 ,定义一些标准长度的 int 的 ,定义复数的 定义宽字符的 有点泛型味道的数学函数 跟浮点数有关的 。 里多了一个 va_copy 可以复制 … 的参数。 里多了个 struct tmx 对 struct tm 做了扩展
输入输出对宽字符还有长整数等做了相应的支持
long double_Complex;long double_Imaginary。
<complex.h>头文件中定义了complex和imaginary宏,并将它们扩展为_Complex和_Imaginary,因此在编写新的应用程序时,应该使用<stdbool.h>头文件中的complex和imaginary宏。下面是关于C99所支持的复数语法特性的使用示例代码:
long long int
C99标准中引进了long long int(-263至263- 1)和unsigned long long int(0到264- 1)。long long int能够支持的整数长度为64位。
后续标准
C99标准之后,新的C语言标准是国际标准化组织(ISO)和国际电工委员会(IEC)在2011年12月8日正式发布的C11标准,官方正式名为ISO/IEC 9899:2011。
C11
C11标准是 ISO/IEC 9899:2011 - Information technology – Programming languages – C 的简称,曾用名为C1X。
C11标准是C语言标准的第三版,前一个标准版本是C99标准。2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC) 旗下的C语言标准委员会(ISO/IEC JTC1/SC22/WG14)正式发布了C11标准。
C11标准的最终定稿的草案是免费开放的,为N1570,但是正式标准文件需要198瑞士法郎。
当前,支持此标准的主流C++语言编译器有:GCC、Clang、Intel C++ Compiler等。
相比C99的变化
- 对齐处理操作符 alignof,函数 aligned_alloc(),以及 头文件 。
- _Noreturn 函数标记,类似于gcc的 attribute((noreturn))。例子:
_Noreturn void thrd_exit(int res); - _Generic 关键词,有点儿类似于 gcc 的 typeof。
- 静态断言( static assertions),_Static_assert(),在解释 #if 和 #error 之后被处理。例子:_Static_assert(FOO > 0, “FOO has a wrong value”);
- 删除了 gets() 函数,C99中已经将此函数被标记为过时,推荐新的替代函数 gets_s()。
- 新的 fopen() 模式,(“…x”)。类似 POSIX 中的 O_CREAT|O_EXCL,在文件锁中比较常用。
- 匿名结构体/联合体,这个早已经在 gcc 中了,我们并不陌生。
- 多线程支持,包括:_Thread_local,头文件 ,里面包含线程的创建和管理函数(比如 thrd_create(),thrd_exit()),mutex (比如 mtx_lock(),mtx_unlock())等等。
- _Atomic类型修饰符和 头文件 <stdatomic.h>。
- 带边界检查(Bounds-checking)的函数接口,定义了新的安全的函数,例如 fopen_s(),strcat_s() 等等。更多参考 Annex K。
- 改进的Unicode支持,新的头文件 <uchar.h> 等。
- 新增 quick_exit() 函数,作为第三种终止程序的方式,当 exit() 失败时可以做最少的清理工作(deinitializition)。
- 创建复数的宏, CMPLX()。
- 更多浮点数处理的宏 (More macros for querying the characteristics of floating point types, concerning subnormal floating point numbers and the number of decimal digits the type is able to store)。
- struct timespec 成为 time.h 的一部分,以及宏 TIME_UTC,函数 timespec_get()。
C11还缺少什么
1、对IEEE754标准-2008的半精度浮点数的支持。尽管遵循GNU C标准规范的编译器(GCC以及Clang等)使用了C扩展关键字__fp16,但是只能对半精度浮点数进行引用,而不能做任何算术操作。因此,这个特性应当在下一个C语言标准中立马加入进去的,建议使用_Half作为半精度浮点数类型的关键字。
2、匿名函数:匿名函数,也叫lambda表达式,是现代计算机编程语言的一个典范特性,在Clang编译器中已经通过blocks语法进行了支持,该语法也被发表到了下一代C标准的提案。Lambda表达式非常适用于多核多线程并行计算,而不仅仅只是用于语法糖。
3、增加对UTF-16字符编码字符串格式符的支持。在标准C语言中,直到C11还只能支持UTF-8编码字符串的格式,采用%s。而对于UTF-16编码字符串的各类操作都比较欠缺,而只有UTF-16转UTF-8的库函数c16rtomb以及UTF-8转UTF-16的标准库函数mbrtoc16可使用,因此在实际项目工程上,用起来十分繁琐。这里建议后续标准C语言采用%S表示UTF-16的字符串格式符,%s作为UTF-8字符串格式符,%C表示UTF-16字符,%c表示UTF-8字符。
标准C语言头文件
83年 ANSI 年制定ANSI C
87年 ANSI 年公布新标准87 ANSI C 15个头文件
90年 ISO 接受ANSI C为 ISO C 15个头文件
95年 ISO 增加3个头文件 18个头文件
99年 ISO 增加6个头文件 24个头文件
11年 ISO 增加5个头文件 29个头文件
C89 15个
The standard headers are
<assert.h> <locale.h> <stddef.h>
<ctype.h> <math.h> <stdio.h>
<errno.h> <setjmp.h> <stdlib.h>
<float.h> <signal.h> <string.h>
<limits.h> <stdarg.h> <time.h>
C99的话,是24个
Diagnostics <assert.h>
Complex <complex.h>
Character handling <ctype.h>
Errors <errno.h>
Floating-point environment <fenv.h>
Characteristics of floating types <float.h>
Format conversion of integer types <inttypes.h>
Alternative spellings <iso646.h>
Sizes of integer types <limits.h>
Localization <locale.h>
Mathematics <math.h>
Nonlocal jumps <setjmp.h>
Signal handling <signal.h>
Variable arguments <stdarg.h>
Boolean type and values <stdbool.h>
Common definitions <stddef.h>
Integer types <stdint.h>
Input/output <stdio.h>
General utilities <stdlib.h>
String handling <string.h>
Type-generic math <tgmath.h>
Date and time <time.h>
Extended multibyte/wide character utilities <wchar.h>
Wide character classification and mapping utilities <wctype.h>C11标准中又新增了5个头文件(stdalign.h, stdatomic.h, stdnoreturn.h, threads.h, and uchar.h)。至此,C标准函数库共29个头文件:
<assert.h>
<complex.h>
<ctype.h>
<errno.h>
<fenv.h>
<float.h>
<inttypes.h>
<iso646.h>
<limits.h>
<locale.h>
<math.h>
<setjmp.h>
<signal.h>
<stdalign.h>
<stdarg.h>
<stdatomic.h>
<stdbool.h>
<stddef.h>
<stdint.h>
<stdio.h>
<stdlib.h>
<stdnoreturn.h>
<string.h>
<tgmath.h>
<threads.h>
<time.h>
<uchar.h>
<wchar.h>
<wctype.h>