C编程标准:GNU C 、ANSI C、标准C、标准c++区别和联系

GNU C 、ANSI C、标准C、标准c++区别和联系

GNU计划,又称革奴计划,是由Richard Stallman在1983年9月27日公开发起的。它的目标是创建一套完全自由的操作系统。它在编写linux的时候自己制作了一个标准成为 GNU C标准。ANSI 美国国家标准协会,它对C做的标准ANSI C标准后来被国际标准协会接收成为 标准C 所以 ANSI C 和标准C是一个概念

总体来说现在linux也支持标准C,以后标准C可以跨平台,而GUN c 一般只在linux c下应用

18.1 ANSI C和标准C++的差别

这里的ANSI C指的是最新的标准-C99

1、ANSI C不支持引用

2、ANSI C不支持函数重载

3、ANSI C多了两个整型(long long、unsigned long long),不过最新的C++编译器已经支持这两种整型

4、ANSI C不支持C++中的一个变量初始化方式,例如:int a(8);

5、ANSI C声明结构时必须使用struct关键字,而标准C++不需要

6、ANSI C标准库中的一些头文件,在标准C++中有了新的名称,例如ctime、cstring、climits、cfloat、cctype,有些文件不仅是名称上的变化

7、ANSI C不支持名称空间

8、ANSI C不包含bool类型,以及true和false关键字

9、声明函数时,参数为空的含义不同。在ANSI C中表示接受任意个数的参数,而在标准C++中表示不接受参数

10、ANSI C不支持内联函数

11、ASNI C不支持默认参数

12、ANSI C不支持可用于全局变量的作用域解析操作符(::)

13、使用const定义的全局常量在ANSI C中具有外部链接性,在标准C++中具有内部链接性,所以在标准C++中声明外部链接性的全局常量必须使用extern,例如:extern const int a = 10;

 

18.02GNU C比ANSI C扩展的地方

1.允许零长度数组

GNU C允许零长度数组,在定义变长对象的头结构时,这个特性非常有用。

struct var_data

{

      int len;

      char data[0];

};

char data[0]仅仅意味着程序中通过var_data的结构体实例的data[index]成员可以访问len之后的第index个地址,并没有为data[0]分配内存。

假设struct var_data的数据域保存在struct var_data紧接着的内存区域,通过如下代码可以遍历这些数据:

struct var_data s;

...

for (i=0;i<s.len;i++)

{

    printf("%02x",s.data[i]);

}

2、case范围

GNU C 支持case x...y 这样的语法,区间[x,y]的数都会满足这个case的条件,记得数据结构试验时,有的同学为了做菜单使用了仅100个case,还好我做的是GUI的

switch(c)

{

      case '0'...'9': c-='0';

      break;

      case 'a'...'f': c-='a'-10;

      break;

      case 'A'...'F': c-='A'-10;

      break;

}

这个case的特点大家都看得出来,比标准C少敲了多少case啊

3、语句表达式

GNU C把包含在括号里的复合语句看做是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地方。我们可以在语句表达式中使用原本只能在复合语句中使用的循环变量、局部变量等,例如

#define min_t(type,x,y) /

({type __x=(x); type __y=(y);__x<__y?__x:__y})

int ia,ib,mini;

mini=min_t(int,ia,ib);

这样,因为重新定义了__x和__y这两个局部变量,所以上述方法定义的宏将不会有副作用。在标准C中,对应的宏通常会有副作用:

#define min(x,y) ((x)<(y)?(x):(y))

而代码min(++ia,++ib)将会被展开为

((++ia)<(++ib)?(++ia):(++ib)) 传入宏的参数会被增加两次。

这个在 嵌入式程序员应知道的0x10个基本问题 里有讲过。

4、typeof关键字

typeof(x)语句可以获得x的类型,因此,我们可以借助typeof重新定义第3条提到的min_t这个宏

#define min(x,y) /

({ /

      const typeof(x) _x=(x);/

      const typeof(y) _y=(y);/

      (void) (&_x==&_y);/

       _x<_y ? _x: _y ; })

我们不需要像第三条时那样传一个type进去,因为通过typeof(x)可以得到type。

代码 (void) (&_x==&_y);的作用是检查_x和_y的类型是否一致。

5、可变参数的宏

标准C只支持可变参数的函数,意味着函数的参数可以是不固定的

例如printf()函数的原型是

int printf(const char *format [,argument]...)

而在GNU C中,宏也可以接受可变数目的参数,例如

#define pr_debug(fmt,arg...) printk(fmt,##arg)

这里arg表示其余的参数可以是零个或多个,这些参数以及参数之间的逗号构成arg的值,

在宏扩展时替换arg ,例如

pr_debug("%s:%d",filename,line);

被扩展为

printk("%s:%d",filename,line);

使用##的原因是为了处理arg不代表任何参数的情况,这时候,前面的逗号就变得多余了。

使用##之后,GNU C预处理器会丢弃前面的逗号,这样代码

pr_debug("success!/n") 会被正确扩展为 printk("success!/n")

而不是 printk("success!/n",);

6.标号元素

标准c要求数组或结构体的初始化值必须以固定的顺序出现,在GNU C中,通过指定索引或结构体成员名,允许初始化值得以任意顺序出现。

指定数组索引的方法是在初始化值前添加 [INDEX]= ,当然也可以用 [FIRST...LAST]= 的形式指定一个范围。例如下面的代码定义一个数组,并把其中的所有元素赋值为0:

unsigned char data[MAX] ={[0...MAX-1]=0 };

下面的代码借助结构体成员名初始化结构体:

struct file_operations DEMO_fops = {

    owner :    THIS_MODULE,

    llseek:      DEMO_llseek,

    read:       DEMO_read,

    write:       DEMO_write,

    ioctl:        DEMO_ioctl,

    open:        DEMO_open,

    release:   DEMO_release,

};

但是Linux 2.6还是推荐采用标准C的方式,如下

struct file_operations DEMO_fops = {

    .owner =    THIS_MODULE,

    .llseek =   DEMO_llseek,

    .read =     DEMO_read,

    .write =    DEMO_write,

    .ioctl =    DEMO_ioctl,

    .open =     DEMO_open,

    .release = DEMO_release,

};

7.当前函数名

GUN C预定义了两个标识符保存当前的函数名,__FUNCTION__保存函数在源码中的名字,

__PRETTY_FUNCTION__保存带语言特色的名字。在c函数中,这两个名字是相同的。

void example()

{

      printf("This is function: %s ",__FUNCTION__);

}

代码中的__FUNCTION__意味着字符串"example"

8、特殊属性声明

GNU C允许声明函数、变量和类型的特殊属性,以便进行手工的代码优化和定制代码检查的方法。指定一个声明的属性,只需要在申明后添加 __attribute__((ATTRIBUTE))

其中ATTRIBUTE为属性说明,如果存在多个属性,则以逗号分隔。GNU C支持noreturn format section aligned packed等十多个属性

noreturn属性作用于函数,表示该函数从不返回。这会让编译器优化代码,并消除不必要的的警告信息。例如

#define ATTRIB_NORET __attribute__ ((noreturn)) ....

asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;

format属性也可用于函数,表示该函数printf scanf 或strftime风格的参数,指定format属性可以让编译器根据格式串检查参数类型。例如:

asmlinkage int printk(const char * fmt,...)/

__attribute__((format(printf,1,2)));

详细的可以看http://blog.163.com/sunm_lin/blog/static/9192142200741533038695/

unused属性作用于函数和变量,表示该函数或变量可能不会被用到,避免编译器产生的警告信息。

aligned属性指定结构体、变量、联合体的对齐方式。packed属性作用于变量和类型,表示压缩结构体,使用最小的内存。

struct examprl_struct

{

      char a;

      int b;

      long c;

}__attribute__((packed));

注意,这个__attribute__((packed))只能用在GNU C

关于在VC下的结构体对齐,参照http://hi.baidu.com/deep_pro/blog/item/421db081aeb604debd3e1e01.html

9、内建函数

GNU C 提供了大量的内建函数,其中很多是标准 C 库函数的内建版本,例如memcpy,它们与对应的 C 库函数功能相同,本文不讨论这类函数,其他内建函数的名字通常以 __builtin 开始。

* __builtin_return_address (LEVEL)

内建函数 __builtin_return_address 返回当前函数或其调用者的返回地址,参数LEVEL 指定在栈上搜索框架的个数,0 表示当前函数的返回地址,1 表示当前函数的调用者的返回地址,依此类推。例如:

++++ kernel/sched.c

437:                 printk(KERN_ERR “schedule_timeout: wrong timeout ”

438:                        “value %lx from %p/n”, timeout,

439:                        __builtin_return_address(0));

* __builtin_constant_p(EXP)

内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数,如果参数 EXP 的值是常数,函数返回 1,否则返回0。例如:

++++ include/asm-i386/bitops.h

249: #define test_bit(nr,addr) /

250: (__builtin_constant_p(nr) ? /

251: constant_test_bit((nr),(addr)) : /

252: variable_test_bit((nr),(addr)))

很多计算或操作在参数为常数时有更优化的实现,在 GNU C 中用上面的方法可以根据参数是否为常数,只编译常数版本或非常数版本,这样既不失通用性,又能在参数是常数时编译出最优化的代码。

* __builtin_expect(EXP, C)

内建函数 __builtin_expect 用于为编译器提供分支预测信息,其返回值是整数表达式 EXP 的值,C 的值必须是编译时常数。例如:

++++ include/linux/compiler.h

13: #define likely(x)       __builtin_expect((x),1)

14: #define unlikely(x)     __builtin_expect((x),0)

++++ kernel/sched.c

564:         if (unlikely(in_interrupt())) {

565:                 printk(”Scheduling in interrupt/n”);

566:                 BUG();

567:         }

这个内建函数的语义是 EXP 的预期值是 C,编译器可以根据这个信息适当地重排语句块的顺序,使程序在预期的情况下有更高的执行效率。上面的例子表示处于中断上下文是很少发生的,第 565-566 行的目标码可能会放在较远的位置,以保证经常执行的目标码更紧凑

 

总结:GNU c运用于linux上,ANSI c就是标准c库函数,GNU包含ANSI,ANSI可以跨平台。ANSI和C++库有交集,也有不同

 

ANSI/ISO_C POSIX GLIBC WIN32 种种C标准的概念区分

2015年05月09日 00:03:12 独自等待2016 阅读数:749

ansi/iso c

  • 我们常常称为的标准C(standard c )
  • 随着C的发展,C89,C99,C11标准在不断的推出,他们都是标准C,C的特性也在丰富,这也侧面反映出一个语言的生命力 
    这种标准是一个规范,不同平台的编译器都会去支持(vc ,gcc…) 
    新的标准发布后,编译器一般是立即可以支持(制定这些标准的组织和编译器公司在发布前,就已经沟通好) 
    推荐gcc @_@,特性支持快
  • 也就是因为各个平台都支持标准C,所以如果你的程序都是只用标准C的特性,包括头文件,那么你的程序在不同的平台下重新编译就能运行

POSIX

  • 首先,这也是个标准,运用于Linux,Unix,OS X,FreeBSD…
  • posix 包括了ansi标准,是后者的父集,除了ansi 定义的函数外,posix还定义了:
    • Network sockets
    • Creating new processes
    • Multithreaded programming
    • Memory-mapped IO,IPC
    • 随着 ansi 标准的变化,posix 也在变化
    • 官网,查看具体的特性

Glibc —GUN C library

  • 基于标准C和posix拓展,在linux下,对函数和接口的实现,包口头文件和函数的实现代码
  • linux平台下的编译C代码,链接的库,都是用glibc编译后生成的库
  • glibc 本身还有自己的特性,不仅仅是ansi和posix定义的函数
  • 官网,下载代码,查看文档,

win32

  • 是win下,给C程序的api,包括例如图形接口api,还有
    • Network sockets
    • Creating new processes
    • Multithreaded programming
    • Memory-mapped IO 
      等等接口 api

没有函数实现的源代码,win不开源 
api的名称与posix定义的api的名称不一样,win按自己的标准

MFC

同样微软提供的库,方便开发win32程序 
基于面向对象的特征,对win32 复杂api 进行封装 
几近淘汰

 

ANSI C 和 POSIX介绍

2014年02月14日 15:15:35 optics_ts 阅读数:2827

标准 (ANSI C, POSIX, SVID, XPG, ...)

  • ANSI C:这一标准是 ANSI(美国国家标准局)于 1989 年制定的 C 语言标准。 后来被 ISO(国际标准化组织)接受为标准,因此也称为 ISO C。
    ANSI C 的目标是为各种操作系统上的 C 程序提供可移植性保证,而不仅仅限于 UNIX。 该标准不仅定义了 C 编程语言的语发和语义,而且还定义了一个标准库。这个库可以根据 头文件划分为 15 个部分,其中包括:字符类型 (<ctype.h>)、错误码 (<errno.h>)、 浮点常数 (<float.h>)、数学常数 (<math.h>)、标准定义 (<stddef.h>)、 标准 I/O (<stdio.h>)、工具函数 (<stdlib.h>)、字符串操作 (<string.h>)、 时间和日期 (<time.h>)、可变参数表 (<stdarg.h>)、信号 (<signal.h>)、 非局部跳转 (<setjmp.h>)、本地信息 (<local.h>)、程序断言 (<assert.h>) 等等。
  • POSIX:该标准最初由 IEEE 开发的标准族,部分已经被 ISO 接受为国际标准。该标准的具体内容 见 1.1.3。POSIX.1 和 POSIX.2 分别定义了 POSIX 兼容操作系统的 C 语言系统接口 以及 shell 和工具标准。这两个标准是通常提到的标准。POSIX 表示可移植操作系统接口(Portable Operating System Interface ,缩写为 POSIX 是为了读音更 像 UNIX)。电气和电子工程师协会(Institute of Electrical and Electronics Engineers,IEEE) 最初开发 POSIX 标准,是为了提高 UNIX 环境下应用程序的可移植性。然而,POSIX 并不局限于 UNIX。 许多其它的操作系统,例如 DEC OpenVMS 和 Microsoft Windows NT,都支持 POSIX 标准,尤其是 IEEE Std. 1003.1-1990(1995 年修订)或 POSIX.1,POSIX.1 提供了源代码级别的 C 语言应用编程 接口(API)给操作系统的服务程序,例如读写文件。POSIX.1 已经被国际标准化组织(International Standards Organization,ISO)所接受,被命名为 ISO/IEC 9945-1:1990 标准。
  •  
  • SVID:System V 的接口描述。System V 接口描述(SVID)是描述 AT&&;T Unix System V 操作 系统的文档,是对 POSIX 标准的扩展超集。
  • XPG:X/Open 可移植性指南。X/Open 可移植性指南(由 X/Open Company, Ltd.出版), 是比 POSIX 更为一般的标准。X/Open 拥有 Unix 的版权,而 XPG 则指定成为 Unix 操作系统必须满足的要求。

Glibc

众所周知,C 语言并没有为常见的操作,例如输入/输出、内存管理,字符串操作等提供内置的支持。 相反,这些功能一般由标准的“函数库”来提供。GNU 的 C 函数库,即 glibc,是 Linux 上最重要的 函数库,它定义了 ISO C 标准指定的所有的库函数,以及由 POSIX 或其他 UNIX 操作系统 统变种指定的附加特色,还包括有与 GNU 系统相关的扩展。目前,流行的 Linux 系统使用 glibc 2.0 以上的版本。glibc 基于如下标准:

  • ISO C: C 编程语言的国际标准,即 ANSI C。
  • POSIX:GNU C 函数库实现了 ISO/IEC 9945-1:1996 (POSIX 系统应用程序编程接口, 即 POSIX.1)指定的所有函数。该标准是对 ISO C 的扩展,包括文件系统接口原 语、设备相关的终端控制函数以及进程控制函数。同时,GUN C 函数库还支持部分由 ISO/IEC 9945-2:1993(POSIX Shell 和 工具标准,即 POSIX.2)指定的函数, 其中包括用于处理正则表达式和模式匹配的函数。
  • Berkeley Unix:BSD 和 SunOS。GNU C 函数库定义了某些 UNIX 版本中尚未标准化的函数, 尤其是 4.2 BSD, 4.3 BSD, 4.4 BSD Unix 系统(即“Berkeley Unix”)以及“SunOS” (流行的 4.2 BSD 变种,其中包含有某些 Unix System V 的功能)。BSD 函数包括 符号链接、select 函数、BSD 信号处理函数以及套接字等等。
  • SVID:System V 的接口描述。GNU C 函数库定义了大多数由 SVID 指定而未被 ISO C 和 POSIX 标准指定的函数。来自 System V 的支持函数包括进程间通信和共享内存、 hsearch 和 drand48 函数族、fmtmsg 以及一些数学函数。
  • XPG:X/Open 可移植性指南。GNU C 函数库遵循 X/Open 可移植性指南(Issue 4.2) 以及所有的 XSI(X/Open 系统接口)兼容系统的扩展,同时也遵循所有的 X/Open Unix 扩展。

 

系统调用

系统调用是操作系统提供给外部程序的接口。在 C 语言中,操作系统的系统调用通常通过 函数调用的形式完成,这是因为这些函数封装了系统调用的细节,将系统调用的入口、参数以及 返回值用 C 语言的函数调用过程实现。在 Linux 系统中,系统调用函数定义在 glibc 中

谈到系统调用时,需要注意如下几点:

  • 系统调用函数通常在成功时返回 0 值,不成功时返回非零值。如果要检查失败原因,则 要判断 errno 这个全局变量的值,errno 中包含有错误代码。
  • 许多系统调用的返回数据通常通过引用参数传递。这时,需要在函数参数中传递一个 缓冲区地址,而返回的数据就保存在该缓冲区中。
  • 不能认为系统调用函数就要比其他函数的执行效率高。要注意,系统调用是一个非常耗时 的过程。

有关系统调用我们将在以后详细讲述。

在线文档 (man, info, HOW-TO, ...)

1. man

man,即 manunal,是 UNIX 系统手册的电子版本。根据习惯,UNIX 系统手册通常分为 不同的部分(或小节,即 section),每个小节阐述不同的系统内容。目前的小节划分如下:

  1. 命令:普通用户命令
  2. 系统调用:内核接口
  3. 函数库调用:普通函数库中的函数
  4. 特殊文件:/dev 目录中的特殊文件
  5. 文件格式和约定:/etc/passwd 等文件的格式
  6. 游戏。
  7. 杂项和约定:标准文件系统布局、手册页结构等杂项内容
  8. 系统管理命令。
  9. 内核例程:非标准的手册小节。便于 Linux 内核的开发而包含

其他手册小节:

  • l: PostgreSQL 数据库命令
  • n: TCL/TK 命令

手册页一般保存在 /usr/man 目录下,其中每个子目录(如 man1, man2, ..., manl, mann) 包含不同的手册小节。使用 man 命令查看手册页。

man 命令行:
man [-acdfFhkKtwW] [-m system] [-p string] [-C config_file] [-M path] [-P pager] [-S section_list] [section] name

常用命令行:
$ man open
$ man 7 man
$ man ./myman.3

2. info

Linux 中的大多数软件开发工具都是来自自由软件基金会的 GNU 项目,这些工具软件 件的在线文档都以 info 文件的形式存在。info 程序是 GNU 的超文本帮助系统。

info 文档一般保存在 /usr/info 目录下,使用 info 命令查看 info 文档。

要运行 info,可以在 shell 提示符后输入 info,也可以在 GNU 的 emacs 中键入 Esc-x 后跟 info。

info 帮助系统的初始屏幕显示了一个主题目录,你可以将光标移动到带有 * 的主题菜单上面,然后按回车键

进入该主题,也可以键入 m,后跟主题菜单的名称而进入该主题。例如,你可以键入 m,然后再键入 gcc 而进

进入 gcc 主题中。

如果你要在主题之间跳转,则必须记住如下的几个命令键:

* n:跳转到该节点的下一个节点;

* p:跳转到该节点的上一个节点;

* m: 指定菜单名而选择另外一个节点;

* f:进入交叉引用主题;

* l:进入该窗口中的最后一个节点;

* TAB:跳转到该窗口的下一个超文本链接;

* RET:进入光标处的超文本链接;

* u:转到上一级主题;

* d:回到 info 的初始节点目录;

* h:调出 info 教程;

* q:退出 info。

#DEMO#

3. HOW-TO

可供用户参考的联机文档的另一种形式是 HOWTO 文件,这些文件位于系统的 /usr/doc/HOWTO 目录下。 HOWTO 文件的文件名都有一个 -HOWTO 后缀,并且都是文本文件。

每一个 HOWTO 文件包含 Linux 某一方面的信息,例如它支持的硬件或如何建立一个引导盘。

要想查看这些文件,进入 /usr/doc/HOWTO 目录,使用 more 命令,具体形式如下:
$ cd /usr/doc/HOWTO; more topic-name-HOWTO

另外,HOWTO 文档还有其他格式的文件,例如 HTML 和 PS 等,保存在 /usr/doc/HOWTO/other-formats 下。

4. 其他

Linux 的内核文档一般包含在内核源代码中,目录如下:/usr/src/linux-2.x.x/Documentation

/usr/doc 目录下包含有大量与特定软件或函数库相关的说明性文档。 

库和头文件的保存位置

1. 函数库

  • /lib:系统必备共享库
  • /usr/lib:标准共享库和静态库
  • /usr/i486-linux-libc5/lib:libc5 兼容性函数库
  • /usr/X11R6/lib:X11R6 的函数库
  • /usr/local/lib:本地函数库

2. 头文件

  • /usr/include:系统头文件
  • /usr/local/include:本地头文件

POSIX 现在已经发展成为一个非常庞大的标准族,某些部分正处在开发过程中。表 1-1 给出了 POSIX 标准的几个 重要组成部分。POSIX 与 IEEE 1003 和 2003 家族的标准是可互换的。除 1003.1 之外,1003 和 2003 家族也包括在表中。 

1-1 POSIX 标准的重要组成部分

1003.0

管理 POSIX 开放式系统环境(OSE)。IEEE 在 1995 年通过了这项标准。 ISO 的版本是 ISO/IEC 14252:1996。

1003.1

被广泛接受、用于源代码级别的可移植性标准。1003.1 提供一个操作系统的 C 语言应 用编程接口(API)。IEEE 和 ISO 已经在 1990 年通过了这个标准,IEEE 在 1995 年 重新修订了该标准。

1003.1b

一个用于实时编程的标准(以前的 P1003.4 或 POSIX.4)。这个标准在 1993 年 被 IEEE 通过,被合并进 ISO/IEC 9945-1。

1003.1c

一个用于线程(在一个程序中当前被执行的代码段)的标准。以前是 P1993.4 或 POSIX.4 的一部分,这个标准已经在 1995 年被 IEEE 通过,归入 ISO/IEC 9945-1:1996。

1003.1g

一个关于协议独立接口的标准,该接口可以使一个应用程序通过网络与另一个应用程序 通讯。 1996 年,IEEE 通过了这个标准。

1003.2

一个应用于 shell 和 工具软件的标准,它们分别是操作系统所必须提供的命令处理器 和工具程序。 1992 年 IEEE 通过了这个标准。ISO 也已经通过了这个标准(ISO/IEC 9945-2:1993)。

1003.2d

改进的 1003.2 标准。

1003.5

一个相当于 1003.1 的 Ada 语言的 API。在 1992 年,IEEE 通过了这个标准。 并在 1997 年对其进行了修订。ISO 也通过了该标准。

1003.5b

一个相当于 1003.1b(实时扩展)的 Ada 语言的 API。IEEE 和 ISO 都已经通过了 这个标准。ISO 的标准是 ISO/IEC 14519:1999。

1003.5c

一个相当于 1003.1q(协议独立接口)的 Ada 语言的 API。在 1998 年, IEEE 通过了这个标准。ISO 也通过了这个标准。

1003.9

一个相当于 1003.1 的 FORTRAN 语言的 API。在 1992 年,IEEE 通过了这个标准, 并于 1997 年对其再次确认。ISO 也已经通过了这个标准。

1003.10

一个应用于超级计算应用环境框架(Application Environment Profile,AEP)的标准。 在 1995 年,IEEE 通过了这个标准。

1003.13

一个关于应用环境框架的标准,主要针对使用 POSIX 接口的实时应用程序。 在 1998 年,IEEE 通过了这个标准。

1003.22

一个针对 POSIX 的关于安全性框架的指南。

1003.23

一个针对用户组织的指南,主要是为了指导用户开发和使用支持操作需求的 开放式系统环境(OSE)框架

2003

针对指定和使用是否符合 POSIX 标准的测试方法,有关其定义、一般需求和指导方针的 一个标准。在 1997 年,IEEE 通过了这个标准。

2003.1

这个标准规定了针对 1003.1 的 POSIX 测试方法的提供商要提供的一些条件。 在 1992 年,IEEE 通过了这个标准。

2003.2

一个定义了被用来检查与 IEEE 1003.2(shell 和 工具 API)是否符合的测试方法的 标准。在 1996 年,IEEE 通过了这个标准。

除了 1003 和 2003 家族以外,还有几个其它的 IEEE 标准,例如 1224 和 1228,它们 也提供开发可移植应用程序的 API。要想得到关于 IEEE 标准的最新信息,可以访问 IEEE 标准的主页,网址是 http://standard.ieee.org/。 有关 POSIX 标准的概述信息,请访问 Web 站点http://standards.ieee.org/reading/ieee/stad_public/description/posix/。 

C语言原来是没有统一的标准的,第一个标准是90左右确定的,内容较以前有些改进:

   1、增加了真正的标准库;

   2、新的预处理命令与特性;

   3、函数原型允许在函数申明中;

   4、指定参数类型一些新的关键字,包括 constvolatile  signed

   5、宽字符、宽字符串与多字节字符;

   6、对约定规则、声明和类型检查的许多小改动与澄清;

后来到了99年就有了新的修正:

   1、增加了对编译器的限制,比如源程序每行要求至少支持到 4095 字节,变量名函数名的要求支持到 63 字节(extern 要求支持到 31)

   2、增强了预处理功能。例如:支持取可变参数 #define Macro(...) __VA_ARGS__;

                                                         使用的时候,允许省略参数,被省略的参数会被扩展成空串;

                                                         支持 // 开头的单行注释(这个特性实际上在C89的很多编译器上已经被支持了);

    3、增加了新关键字 restrict, inline, _Complex, _Imaginary, _Bool;支持 long long, long double _Complex, float _Complex 等类型;

    4、支持不定长的数组,即数组长度可以在运行时决定,比如利用变量作为数组长度。声明时使用 int a[var]的形式。不过考虑到效率和实现,不定长数组不能用在全局,或struct union 里。
    5、变量声名不必放在语句块的开头,,for 语句提倡写成 for(int i=0;i<100;++i) 的形式,即i 只在for 语句块内部有效。

    6、允许采用(type_name){xx,xx,xx} 类似于 C++ 的构造函数的形式构造匿名的结构体。

    7、初始化结构的时候允许对特定的元素赋值,形式为:

                      struct test{int a[3],b;} foo[] = { [0].a = {1}, [1].a = 2 }

                     struct test{int a, b, c, d;} foo=  { .a=1, .c=3,4, .b=5 };  // 3,4 是对 .c,.d 赋值的

     8、格式化字符串中,利用 \u 支持 unicode 的字符。

     9、支持 16 进制的浮点数的描述;printf scanf 的格式化串增加了对 long long int 类型的支持;浮点数的内部数据描述支持了新标准,可以使用 #pragma 编译器指令指定。

     10、除了已有的 __line__ __file__ 以外,增加了 __func__ 得到当前的函数名。

     11、允许编译器化简非常数的表达式;取消了函数返回类型默认为 int 的规定

     12、修改了 / % 处理负数时的定义,这样可以给出明确的结果,例如在C89中-22 / 7 = -3, -22 % 7 = -1,也可以-22 / 7= 4, -22 % 7 = 6。 而C99中明确为-22 / 7 = -3, -22 % 7 = -1,只有一种结果。

     13、允许 struct 定义的最后一个数组不指定其长度,写做 [](flexible array member)。

  14、const const int i 将被当作const int i 处理;输入输出对宽字符以及长整数等做了相应的支持。

     15、增加和修改了一些标准头文件,比如定义 bool 的 <stdbool.h> ,定义一些标准长度的 int 的 <inttypes.h> ,定义复数的 <complex.h> ,定义宽字符的 <wctype.h> ,类似于泛型的数学函数 <tgmath.h>, 浮点数相关的 <fenv.h>。 在<stdarg.h> 增加了 va_copy 用于复制 ... 的参数。 里增加了 struct tmx ,对 struct tm 做了扩展。


在11年的时候ISO正式发布了新的C语言的新标准C11:

     1、对齐处理(Alignment)的标准化(包括_Alignas标志符,alignof运算符, aligned_alloc函数以及<stdalign.h>头文件

     2、_Noreturn 函数标记,类似于 gcc 的 __attribute__((noreturn))。

     3、_Generic 关键字。

     4、多线程(Multithreading)支持,包括:

                  _Thread_local存储类型标识符,<threads.h>头文件,里面包含了线程的创建和管理函数。

                 _Atomic类型修饰符和<stdatomic.h>头文件。

      5、增强的Unicode的支持。基于C Unicode技术报告ISO/IEC TR 19769:2004,增强了对Unicode的支持。包括为UTF-16/UTF-32编码增加了char16_t和char32_t数据类型,提供了包含unicode字符串转换函数的头文件<uchar.h>.

      6、删除了 gets() 函数,使用一个新的更安全的函数gets_s()替代。

      7、增加了边界检查函数接口,定义了新的安全的函数,例如 fopen_s(),strcat_s()

      8、匿名结构体/联合体支持。这个在gcc早已存在,C11将其引入标准。

      9、静态断言(Static assertions),_Static_assert(),在解释 #if 和 #error 之后被处理。

      10、新的 fopen() 模式,(“…x”)。类似 POSIX 中的 O_CREAT|O_EXCL,在文件锁中比较常用。

      11、新增 quick_exit() 函数作为第三种终止程序的方式。当 exit()失败时可以做最少的清理工作。

C90和C99容易弄混,这也是现在用的最多的两个版本,至于C11的话基本没见人用,反正有了也总结一下 。

 

 

猜你喜欢

转载自blog.csdn.net/qq_38971487/article/details/90760218