导航:首页 > 源码编译 > 并行c编译器

并行c编译器

发布时间:2023-06-12 19:13:06

A. Linux下C实现多进程同步并行

你去查一下OpenMP相关书籍,用OpenMP库函数实现吧,Linux的gcc编译器4.2版以后开始内置OpenMP并行支持,源程序里多写两句话就搞定的事情,不过OpenMP建立的是轻量级进程(在Windows下叫线程的东西)。

如果要用严格意义上的“进程”实现,还有一个多线程并行的工具是MPICH2,设计目的是多计算机分布式并行计算的,当然也能用在单一计算机上。

B. 如何评价CUDA,OpenCL,OpenMP,OpenACC等主流并行运算框架

PGI和Cray才是最早推动这项技术商业化的公司。PGI已经推出了一组非常类似的加速器指令,目前也成为了OpenACC标准的基础部分之一。Cray公司正在开发自己的OpenACC编译器,并且他的XK6客户如橡树岭国家实验室和瑞士国家超级计算机中心,预计将成为该技术的第一批超级计算机用户。
简而言之,OpenACC指令与OpenMP指令工作方式很类似,但前者特别适用于高度数据并行代码。它们可插入标准的C,C + +和Fortran程序直接指导编译器进行某些代码段的并行。编译器会特别注意数据在CPU和GPU(或其他)之间来回转移的逻辑关系,并将计算映射到适当的处理器上。
这样,开发人员就可以在现存的或者新的代码上做相对小的改动以标示出加速并行区域。由于指令设计适用于一个通用并行处理器,这样相同的代码可以运行在多核CPU、GPU或任何编译器支持的其他类型的并行硬件上。这种硬件的独立性对于HPC的用户来说特别重要,因为他们不愿意接受那种受供应商限制的,非便携式编程环境。

C. 学C语言现在最好用的编程软件

GNU编译器套装
开发 The GNU Project
最新版本 4.4.2 / 2009-10-15(2个月前)
操作系统 跨平台
类型 编译器
许可协议 GPL
网站 gcc.gnu.org

GCC(GNU Compiler Collection,GNU编译器套装),是一套由GNU开发的编程语言编译器。它是一套以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分,亦是自由的类Unix及苹果计算机Mac OS X 操作系统的标准编译器。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。

GCC原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理Fortran、Pascal、Objective-C、Java,以及Ada与其他语言。
目录
[隐藏]

* 1 概观
* 2 目前支持的语言
o 2.1 内嵌OpenMP支持
* 3 支持的处理器架构
* 4 结构
o 4.1 前端接口
o 4.2 中介接口
o 4.3 后端接口
* 5 替GCC程序除错
* 6 参考书目及注释
* 7 参阅
* 8 更多阅读
* 9 外部链接

[编辑] 概观

GCC是由理乍得·马修·斯托曼在1985年开始的。他首先扩增一个旧有的编译器,使它能编译C,这个编译器一开始是以Pastel语言所写的。Pastel是一个不可移植的Pascal语言特殊版,这个编译器也只能编译Pastel语言。为了让自由软件有一个编译器,后来此编译器由斯托曼和Len Tower在1987年[1]以C语言重写[2]并成为GNU项目的编译器。GCC的建立者由自由软件基金会直接管理[3]。

在1997年,一群不满GCC缓慢且封闭的创作环境者,组织了一个名为EGCS《Experimental/Enhanced GNU Compiler System》的项目,此项目汇整了数项实验性的分支进入某个GCC项目的分支中。EGCS比起GCC的建构环境更有活力,且EGCS最终也在1999年四月成为GCC的官方版本。

GCC目前由世界各地不同的数个程序设计师小组维护。它是移植到中央处理器架构以及操作系统最多的编译器。

由于GCC已成为GNU系统的官方编译器(包括GNU/Linux家族),它也成为编译与建立其他操作系统的主要编译器,包括BSD家族、Mac OS X、NeXTSTEP与BeOS。

GCC通常是跨平台软件的编译器首选。有别于一般局限于特定系统与运行环境的编译器,GCC在所有平台上都使用同一个前端处理程序,产生一样的中介码,因此此中介码在各个其他平台上使用GCC编译,有很大的机会可得到正确无误的输出程序。
[编辑] 目前支持的语言

以2006年5月24日释出的4.1.1版为准,本编译器版本可处理下列语言:

* Ada 《GNAT》
* C 《GCC》
* C++(G++)
* Fortran 《Fortran 77: G77,Fortran 90: GFORTRAN》

* Java 《编译器:GCJ;解释器:GIJ》
* Objective-C 《GOBJC》
* Objective-C++

先前版本纳入的CHILL前端由于缺乏维护而被废弃。

Fortran前端在4.0版之前是G77,此前端仅支持Fortran 77。在本版本中,G77被废弃而采用更新的GFortran,因为此前端支持Fortran 95。

下列前端依然存在:

* Mola-2
* Mola-3
* Pascal
* PL/I

* D语言
* Mercury
* VHDL

[编辑] 内嵌OpenMP支持

OpenMP是一种跨语言的对称多处理器(SMP)多线程并行程序的编程工具,也非常适合当今越来越流行的单CPU多核硬件环境,因此从gcc4.2开始,OpenMP成为其内嵌支持的并行编程规范,可以直接编译内嵌 OpenMP语句的C/C++/Fortran95的源代码。gcc4.2之前如果想在C/C++/Fortran中嵌入OpenMP语句的话,需要额外安装库和预处理器才能识别和正确处理这些语句。

* gcc 4.2.0开始支持OpenMP v2.5
* gcc 4.4.0开始支持OpenMP v2.5及v3.0

参见GNU的GOMP计划
[编辑] 支持的处理器架构

GCC目前支持下列处理器架构(以4.1版为准):

* Alpha
* ARM
* Atmel AVR
* Blackfin
* H8/300
* IA-32(x86)与x86-64
* IA-64例如:Itanium

* MorphoSys家族
* Motorola 68000
* Motorola 88000
* MIPS
* PA-RISC
* PDP-11
* PowerPC

* System/370,System/390
* SuperH
* HC12
* SPARC
* VAX
* Renesas R8C/M16C/M32C家族

较不知名的处理器架构也在官方释出版本中支持:

* A29K
* ARC
* C4x
* CRIS
* D30V
* DSP16xx
* FR-30
* FR-V

* Intel i960
* IP2000
* M32R
* 68HC11
* MCORE
* MMIX

* MN10200
* MN10300
* NS32K
* ROMP
* Stormy16
* V850
* Xtensa

由FSF个别维护的GCC处理器架构:

* D10V
* MicroBlaze

* PDP-10
* MSP430

* Z8000

当GCC需要移植到一个新平台上,通常使用此平台固有的语言来撰写其初始阶段。
[编辑] 结构

GCC的外部接口长得像一个标准的Unix编译器。用户在命令行下键入gcc之程序名,以及一些命令参数,以便决定每个输入文件使用的个别语言编译器,并为输出代码使用适合此硬件平台的汇编语言编译器,并且选择性地运行连接器以制造可运行的程序。

每个语言编译器都是独立程序,此程序可处理输入的源代码,并输出汇编语言码。全部的语言编译器都拥有共通的中介架构:一个前端解析符合此语言的源代码,并产生一抽象语法树,以及一翻译此语法树成为GCC的寄存器转换语言《RTL》的后端。编译器优化与静态代码解析技术(例如FORTIFY_SOURCE[1],一个试图发现缓存溢出《buffer overflow》的编译器)在此阶段应用于代码上。最后,适用于此硬件架构的汇编语言代码以Jack Davidson与Chris Fraser发明的算法产出。

几乎全部的GCC都由C写成,除了Ada前端大部分以Ada写成。
[编辑] 前端接口

前端的功能在于产生一个可让后端处理之语法树。此语法解析器是手写之递回语法解析器。

直到最近,程序的语法树结构尚无法与欲产出的处理器架构脱钩。而语法树的规则有时在不同的语言前端也不一样,有些前端会提供它们特别的语法树规则。

在2005年,两种与语言脱钩的新型态语法树纳入GCC中。它们称为GENERIC与GIMPLE。语法解析变成产生与语言相关的暂时语法树,再将它们转成GENERIC。之后再使用"gimplifier"技术降低GENERIC的复杂结构,成为一较简单的静态唯一形式(Static Single Assignment form,SSA)基础的GIMPLE形式。此形式是一个与语言和处理器架构脱钩的全局优化通用语言,适用于大多数的现代编程语言。
[编辑] 中介接口

一般编译器作者会将语法树的优化放在前端,但其实此步骤并不看语言的种类而有不同,且不需要用到语法解析器。因此GCC作者们将此步骤归入通称为中介阶段的部分里。此类的优化包括消解死码、消解重复计算与全局数值重编码等。许多优化技巧也正在实现中。
[编辑] 后端接口

GCC后端的行为因不同的前处理器宏和特定架构的功能而不同,例如不同的字符尺寸、调用方式与大小尾序等。后端接口的前半部利用这些消息决定其RTL的生成形式,因此虽然GCC的RTL理论上不受处理器影响,但在此阶段其抽象指令已被转换成目标架构的格式。

GCC的优化技巧依其释出版本而有很大不同,但都包含了标准的优化算法,例如循环优化、线程跳跃、共通程序子句消减、指令调度等等。而RTL的优化由于可用的情形较少,且缺乏较高级的信息,因此比较起近来增加的GIMPLE语法树形式[2],便显得比较不重要。

后端经由一重读取步骤后,利用描述目标处理器的指令集时所取得的信息,将抽象寄存器替换成处理器的真实寄存器。此阶段非常复杂,因为它必须关照所有GCC可移植平台的处理器指令集的规格与技术细节。

后端的最后步骤相当公式化,仅仅将前一阶段得到的汇编语言码借由简单的副函数转换其寄存器与存储器位置成相对应的机器码。
[编辑] 替GCC程序除错

为GCC除错的首选工具当然是GNU除错器。其他特殊用途的除错工具是Valgrind,用以发现存储器泄漏 (Memory leak)。而GNU测量器(gprof)可以得知程序中某些函数花费多少时间,以及其调用频率;此功能需要用户在编译时选定测量《profiling》选项。
[编辑] 参考书目及注释

* Richard M. Stallman:Using and Porting the GNU Compiler Collection, Free Software Foundation,ISBN 0-595-10035-X
* Richard M. Stallman: Using Gcc: The Gnu Compiler Collection Reference, Free Software Foundation, ISBN 1-882114-39-6
* Brian J. Gough:An Introction to GCC, Network Theory Ltd., ISBN 0-9541617-9-3

1. ^ Tower, Leonard (1987) "GNU C编译器beta测试版释出" comp.lang.misc USENET新闻组;参阅http://gcc.gnu.org/releases.html#timeline
2. ^ Stallman, Richard M.(1986年2月1日).GNU状态.GNU的公告版,1(1).自由软件基金会.
3. ^ Stallman, Richard M. (2001) "GCC贡献者名单"于使用及移植GCC 2.95版(Cambridge, Mass.: Free Software Foundation)

[编辑] 参阅
[[File:|36x32px|自由软件主题]] 自由软件主题首页

GCC目前包含了Boehm GC,一个为C/C++ 所设计的垃圾回收器。

* distcc - 为分布式编译所设计的软件,以GCC为协同软件。
* LLVM - 低层虚拟机编译器架构。
* MinGW - 将GNU开发工具移植到Win32平台下的计划
* Cygwin - 在Windows上运行GNU程序的模拟软件。
* GCC Summit
* OpenWatcom - 另一个开放原码的C++/Fortran编译器。
* Code Sourcery - 一个GCC顾问公司。
* ggcc - 全球化GCC项目。

[编辑] 更多阅读

* Arthur Griffith, GCC: The Complete Reference. McGrawHill/Osborne. ISBN 0-07-222405-3.
* Kerner, Sean Michael.Open Source GCC 4.0: Older, Faster,internetnews.com,2005年4月22日.
* Kerner, Sean Michael.New GCC Heavy on Optimization,internetnews.com,2006年3月2日.

[编辑] 外部链接

* GCC官方网站
* GCC Forum - 由Nabble维持,整理所有gcc通信讨论串,并集成入一个可搜索接口中。

D. 求C语言的发展和现在应用

C语言
维 基
http://zh.w-i-k-i-p-e-d-i-a.org/zh/C%E8%AF%AD%E8%A8%80

编程范型
程序式
发行时间
1972年
设计者
丹尼斯·里奇(Dennis Ritchie)
实作者
丹尼斯·里奇(Dennis Ritchie)和肯·汤普逊(Ken Thompson)
最新发行时间 C99 (2000年3月)
启发语言
B语言、组合语言
影响语言
awk, BitC, csh, C++, C#, Concurrent C, D, Java, JavaScript, Objective-C, Perl, PHP
作业系统
跨平台
C语言,是一种通用的、程序式的程式语言,广泛用于系统与应用软件的开发。具有高效、灵活、功能丰富、表达力强和较高的移植性等特点,在程序员中备受青睐。
C语言是由UNIX的研制者丹尼斯·里奇(Dennis Ritchie)和肯·汤普逊(Ken Thompson)于1970年研制出的B语言的基础上发展和完善起来的。目前,C语言编译器普遍存在于各种不同的操作系统中,例如UNIX、MS-DOS、Microsoft Windows及Linux等。C语言的设计影响了许多后来的程式语言,例如C++、Objective-C、Java、C#等。
后来于1980年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局(American National Standard Institution)为C语言订定了一套完整的国际标准语法,称为ANSI C,作为C语言的标准。1980年代至今的有关程式开发工具,一般都支持符合ANSI C的语法。
目录 [隐藏]
1 设计哲学
2 特色
3 历史
3.1 早期发展
3.2 K&R C
3.3 ANSI C 和 ISO C
3.4 C99
4 语法
4.1 Hello World 程序
4.2 进一步了解
4.3 复合语句
4.4 条件语句
4.5 循环语句
4.6 跳转语句
4.7 在C99中的运算符号
4.8 数据类型
4.8.1 基础数据类型
4.8.2 阵列
4.8.3 指针
4.8.4 字串
4.9 文件输入/输出
4.9.1 标准输入/输出
5 内存管理
6 安全问题
7 库
8 保留关键字
8.1 C99新增关键字
9 C//
10 参考文献
11 外部连结
12 参见
[编辑]设计哲学

C语言是一个程序语言,设计目标是提供一种能以简易的方式编译、处理低阶记忆体、产生少量的机械码以及不需要任何执行环境支援便能执行的程式语言。C语言也很适合搭配汇编语言来使用。尽管C语言提供了许多低阶处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程式可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(微控制器或称MCU)以及超级电脑等作业平台。
[编辑]特色

C语言是一个有结构化程式设计、具有变量作用域(variable scope)以及递回功能的程序式语言。
传递参数是以值传递(Pass-by-value),也可以透过指针来传递参数(Pass-by-address)。
不同的变数类型可以用结构体(struct)组合在一起。
只有32个保留字(reserved keywords),使变量、函数命名有更多弹性。
部份的变量类型可以转换,例如整型和字符型变量。
透过指针(pointer),C语言可以容易的对记忆体进行低阶控制。
编译预处理(preprocessor)让C语言的编译更具有弹性。
[编辑]历史

[编辑]早期发展
C语言的第一次发展在1969年到1973年之间。之所以被称为“C”是因为C语言的很多特性是由一种更早的被称为B语言的程式语言中发展而来。早期作业系统的核心大多由组合语言组成,随着C语言的发展,C语言已经可以用来编写作业系统的核心。1973年,Unix作业系统的核心正式用C语言改写,这是C语言第一次应用在作业系统的核心编写上。
[编辑]K&R C
1978年,丹尼斯·里奇(Dennis Ritchie)和Brian Kernighan合作出版了《C程序设计语言》的第一版。书中介绍的C语言标准也被C语言程式设计师称作“K&R C”,第二版的书中也包含了一些ANSI C的标准。K&R C主要介绍了以下特色:
结构(struct)类型
长整数(long int)类型
无号整数(unsigned int)类型
把运算符=+和=-改为+=和-=。因为=+和=-会使得编译器不知道使用者要处理i = +10还是i =- 10,使得处理上产生混淆。
即使在后来ANSI C标准被提出的许多年后,K&R C仍然是许多编译器的最低标准要求,许多老旧的编译仍然运行K&R C的标准。
[编辑]ANSI C 和 ISO C
主条目:ANSI C
1989年,C语言被 ANSI 标准化(ANSI X3.159-1989)。标准化的一个目的是扩展K&R C。这个标准包括了一些新特性。在K&R出版后,一些新特性被非官方地加到C语言中。
void 函数
函数返回 struct 或 union 类型
void * 数据类型
在ANSI标准化自己的过程中,一些新的特性被加了进去。ANSI也规定了一套标准函数库。ANSI ISO(国际标准化组织)成立 ISO/IEC JTC1/SC22/WG14 工作组,来规定国际标准的C语言。通过对ANSI标准的少量修改,最终通过了 ISO 9899:1990。随后,ISO标准被 ANSI 采纳。
传统C语言到ANSI/ISO标准C语言的改进包括:
增加了真正的标准库
新的预处理命令与特性
函数原型允许在函数申明中指定参数类型
一些新的关键字,包括 const、volatile 与 signed
宽字符、宽字符串与字节多字符
对约定规则、声明和类型检查的许多小改动与澄清
WG14工作小组之后又于1995年,对1985年颁布的标准做了两处技术修订(缺陷修复)和一个补充(扩展)。下面是 1995 年做出的所有修改:
3 个新的标准库头文件 iso646.h、wctype.h 和 wchar.h
几个新的记号与预定义宏,用于对国际化提供更好的支持
printf/sprintf 函数一系列新的格式代码
大量的函数和一些类型与常量,用于多字节字符和宽字节字符
[编辑]C99
在ANSI的标准确立后,C语言的规范在一段时间内没有大的变动,然而C++在自己的标准化建立过程中继续发展壮大。《标准修正案一》在1995年为C语言建立了一个新标准,但是只修正了一些C89标准中的细节和增加更多更广得国际字符集支持。不过,这个标准引出了1999年ISO 9899:1999的发表。它通常被称为C99。C99被ANSI于2000年3月采用。
在C99中包括的特性有:
对编译器限制增加了,比如源程序每行要求至少支持到 4095 字节,变量名函数名的要求支持到 63 字节(extern 要求支持到 31)
预处理增强了。例如:
巨集支持取可变参数 #define Macro(...) __VA_ARGS__
使用巨集的时候,参数如果不写,巨集里用 #,## 这样的东西会扩展成空串。(以前会出错的)
支持 // 行注释(这个特性实际上在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 里面有效。
当一个类似结构的东西需要临时构造的时候,可以用(type_name){xx,xx,xx} 这有点像 C++ 的构造函数
初始化结构的时候现在可以这样写:
struct {int a[3],b;} hehe[] = { [0].a = {1}, [1].a = 2 };
struct {int a, b, c, d;} hehe = { .a = 1, .c = 3, 4, .b = 5} // 3,4 是对 .c,.d 赋值的
字符串里面,\u 支持 unicode 的字符
支持 16 进制的浮点数的描述
所以 printf scanf 的格式化串多支持了 ll / LL(VC6 里用的 I64)对应新的 long long 类型。
浮点数的内部数据描述支持了新标准,这个可以用 #pragma 编译器指定
除了已经有的 __line__ __file__ 以外,又支持了一个 __func__ 可以得到当前的函数名
对于非常数的表达式,也允许编译器做化简
修改了对于/% 处理负数上的定义,比如老的标准里 -22 / 7 = -3, -22 % 7 = -1 而现在 -22 / 7 = -4, -22 % 7 = 6(根据本人的测试,使用c99标准时结果仍未-3和-1,本人使用的编译器是gcc4.4.3)
取消了不写函数返回类型默认就是 int 的规定
允许 struct 定义的最后一个数组写做 [] 不指定其长度描述
const const int i;将被当作 const int i;处理
增加和修改了一些标准头文件,比如定义 bool 的 <stdbool.h> 定义一些标准长度的 int 的 <inttypes.h> 定义复数的 <complex.h> 定义宽字符的 <wctype.h> 有点泛型味道的数学函数 <tgmath.h> 跟浮点数有关的 <fenv.h>。<stdarg.h> 里多了一个 va_ 可以复制 ... 的参数。<time.h> 里多了个 struct tmx 对 struct tm 做了扩展
输入输出对宽字符还有长整数等做了相应的支持
但是各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的时候,微软和Borland却似乎对此不感兴趣。
[编辑]语法

[编辑]Hello World 程序
下面是一个在标准输出设备 (stdout) 上,印出 "Hello World" 字串的简单程序,这样子的程序,通常作为初学编程语言时的第一个程序:
#include <stdio.h>

int main(void)
{
printf("Hello, world!\n");
return 0;
}
[编辑]进一步了解
C语言由函数和变量组成。C的函数就像是Fortran中的子程序和函数。
在C语言中,程序从main开始执行。main函数通过调用和控制其他函数进行工作。例如上面的printf。程序员可以自己写函数,或从库中调用函数。在上面的return 0;使得main返回一个值给调用程序的外壳,表明程序已经成功运行。
一个C语言的函数由返回值、函数名、参数列表(或void表示没有返回值)和函数体组成。函数体的语法和其它的复合的语句部分是一样的。
[编辑]复合语句
C语言中的复合语句(或称语句块)的格式为:
{语句;语句;……}
复合语句可以使得几个语句从文法上变成一个语句。
[编辑]条件语句
C语言有三种条件语句形式。两种是if,另一种是switch。
两种if包括:
if(运算式)
语句;
以及
if(运算式)
语句;
else
语句;
运算式的值非零表示条件为真;如果条件为假,程式将跳过if处的语句,直接执行if后面的语句。但是如果if后面有else,则当条件为假时,程式跳到else处执行。if和else后面的语句可以是另个if语句,这种套叠式的结构,允许更复杂的逻辑控制流程得以实现。在一般情况下,else一定与最接近的if成对,必要时可用括号{}越过此限制。比较下面两种情况:
if(运算式)
if (运算式)
语句;
else
语句;
if(运算式){
if (运算式)
语句;
}
else
语句;
switch通常用于对几种有明确值的条件进行控制。它要求的条件值通常是整数或字符。与switch搭配的条件转移是case。使用case后面的标值,控制程式将跳到满足条件的case处一直往下执行,直到语句结束或遇到break。通常可以使用default把其他例外的情况包含进去。如果switch语句中的条件不成立,控制程式将跳到default处执行;如果省略default子句,则直接执行下一语句。switch是可以嵌套的。
switch (<运算式>) {
case <值1>:
<语句>
break;
case <值2>:
<语句>
default :
<语句>
}
[编辑]循环语句
C语言有三种形式的循环语句:
do
<语句>
while (<表达式>);

while (<表达式>)
<语句>;

for (<表达式1> ; <表达式2> ; <表达式3>)
<语句>;
在while和do中,语句将执行到表达式的值为零时结束。在do...while语句中,循环体将至少被执行一次。这三种循环结构可以互相转化:
for (<表达式1>; <表达式2>; <表达式3>)
<语句>;
如果<语句>中不使用continue语句的话,相当于
<表达式1>;
while (<表达式2>) {
<语句>;
<表达式3>;
}
当循环条件一直为真时,将产生死循环。
[编辑]跳转语句
跳转语句包括四种:goto,continue,break和return。
goto语句是无条件转移语句:
goto 标记;
标记必须在当前函数中定义,使用“标记:”的格式定义。程式将跳到标记处继续执行。由于goto容易产生阅读上的困难,所以应该尽量少用。
continue语句用在回圈语句中,作用是结束当前一轮的回圈,马上开始下一轮回圈。
break语句用在回圈语句或switch中,作用是结束当前回圈,跳到循环体外继续执行。但是使用break只能跳出一层回圈。在要跳出多重回圈时,可以使用goto使得程式更为简洁。
当一个函数执行结束后要返回一个值时,使用return。return可以跟一个运算式或变数。如果return后面没有值,将执行不返回值。
[编辑]在C99中的运算符号
()、 []、 -> 、 .、 !、 ++、 -- 、(cast) 括号、指标、成员、逻辑非、自加、自减、强制转换
++ 、 -- 、 * 、 & 、 ~ 、 ! 、 + 、 - 、 sizeof 单目运算符
* 、 / 、 % 算术运算符
+ 、 - 算术运算符
<< 、 >> 位运算符
< 、 <= 、 > 、 >= 关系运算符
== 、 != 关系运算符号
& 位与
^ 位异或
| 位或
&& 逻辑与
|| 逻辑或
? 、 : 条件运算符
= 、 += 、 -= 、 *= 、 /= 、 %= 、 < 、 <= 、 > 、 >= 、 &= 、 |= 、 ^= 赋值运算符
, 顺序运算符
比较特别的是,位元右移(>>)运算子可以是算术(左端补最高有效位)或是逻辑(左端补 0)位移。例如,将 11100011 右移 3 位元,算术右移后成为 11111100,逻辑右移则为 00011100。因算术位元右移较适于处理带负号整数,所以几乎所有的编译器都是算术位元右移。(经测试,gcc4.4.3使用c99依然是00011100,即逻辑移位)
[编辑]数据类型
[编辑]基础数据类型
注意:以下是典型的数据位长和范围。但是编译器可能使用不同的数据位长和范围。这取决于使用的编译器。请参考具体的参考手册。
在头文件<limits.h>和<float.h>中说明了基础数据的长度。float,double和long double的范围就是在IEEE 754标准中提及的典型数据。
关键字 位长 范围 printf chars
char 1 -128..127(或0..255,与体系结构相关) %c
unsigned char 1 0..255
signed char 1 -128..127
int 2 or
4 -32768..32767 or
-2147483648..2147483647 %i, %d
unsigned int 2 or
4 0..65535 or
0..4294967295 %u
signed int 2 or
4 -32768..32767 or
-2147483648..2147483647 %i, %d
short int 2 -32768..32767 %hi
unsigned short 2 0..65535 %hu
signed short 2 -32768..32767
long int 4 -2147483648..2147483647 %li, %ld
unsigned long 4 0..4294967295 %lu
signed long 4 -2147483648..2147483647
long long 8 -9223372036854775808..9223372036854775807 %lli
unsigned long long 8 0..18446744073709551615 %llu
float 4 3.4x10-38..3.4x10+38 (7 sf) %f, %e, %g
double 8 1.7x10-308..1.7x10+308 (15 sf) %f, %e, %g
long double 8 或以上 编译器相关 %Lf, %Le, %Lg
[编辑]阵列
如果一个变数名后面跟着一个有数字的中括号,这个声明就是阵列声明。字串也是一种阵列。它们以ASCII的NUL作为阵列的结束。要特别注意的是,方括内的索引值是从0算起的。
例如:
int myvector [100];/* 从myvector[0]至myvector[99]止共100个元素 */
char mystring [80];
float mymatrix [3] [2] = {2.0 , 10.0, 20.0, 123.0, 1.0, 1.0};
int notfull [3][3] = {{1},{1,2,3},{4,5}}; (*)
char lexicon [10000] [300];/* 共一万个最大长度为300的字符阵列。*/
int a[3][4];
上面最后一个例子创建了一个阵列,但也可以把它看成是一个多维阵列。注意阵列的下标从0开始。这个阵列的结构如下:
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
例子(*)创建了一个3*3的二维阵列,初始化时有些元素并未赋值。如下:
1 0 0
1 2 3
4 5 0
为0的位置的数值是随机的。
[编辑]指针
如果一个变量声明时在前面使用 * 号,表明这是个指针型变量。换句话说,该变量存储一个地址,而 * 则是取内容操作符,意思是取这个内存地址里存储的内容。指针是 C 语言区别于其他同时代高级语言的主要特征之一。
指针是一把双刃剑,许多操作可以通过指针自然的表达,但是不正确的或者过分的使用指针又会给程序带来大量潜在的错误。
例如:
int *pi; /* 指向整型数据的指针变量 */
int *api[3];/* 由指向整型数据的指针构成的数组,长度为 3 */
char **argv; /* 指向一个字符指针的指针 */
储存在指针中的地址所指向的数值在程序中可以由 * 读取。例如,在第一个例子中, *pi 是一个整型数据。这叫做引用一个指针。
另一个运算符 &,叫做取地址运算符,它将返回一个变量、数组或函数的存储地址。因此,下面的例子:
int i, *pi; /* int and pointer to int */
pi = &i;
i 和 *pi 在程序中可以相互交替使用,直到 pi 被改变成指向另一个变量的地址。
[编辑]字串
C语言的字符串其实就是char型数组,所以使用字串并不需要引用库。但是C标准库确实包含了一些用于对字串进行操作的函数,使得它们看起来就像字串而不是阵列。使用这些函数需要引用标头档<string.h>。

[编辑]文件输入/输出
在C语言中,输入和输出是经由标准函式库中的一组函数来实现的。在ANSI/ISO C中,这些函数被定义在标头档<stdio.h>中。
[编辑]标准输入/输出
有三个标准输入/输出是标准I/O库预先定义的:
stdin 标准输入
stdout 标准输出
stderr 输入输出错误

下面的这个例子显示了一个过滤程式(filter program)是怎样构成的。
#include <stdio.h>

int main(void)
{
int c;
while (1)
{
c = getchar();
if (c==EOF)
{
perror("getchar()");
return -1;
}
putchar(c);
}

return 0;
}
[编辑]内存管理

C语言的特色之一是:程序员必须亲自处理内存的分配细节。
C语言使用栈(Stack)来保存函数返回地址/栈祯基址、完成函数的参数传递和函数局部变量的存储。 如果程序需要在运行的过程中动态分配内存,可以利用堆(Heap)来实现。
基本上C程序的元素存储在内存的时候有3种分配策略:
静态分配
如果一个变量声明为全局变量或者是函数的静态变量,这个变量的存储将使用静态分配方式。静态分配的内存一般会被编译器放在数据段或代码段来存储,具体取决于实现。这样做的前提是,在编译时就必须确定变量的大小。 以 IA32 的 x86 平台及 gcc 编译器为例,全局及静态变量放在数据段的低端;全局及静态常量放在代码段的高端。
自动分配
函数的自动局部变量应该随着函数的返回会自动释放(失效),这个要求在一般的体系中都是利用栈(Stack)来满足的。相比于静态分配,这时候,就不必绝对要求这个变量在编译时就必须确定变量的大小,运行时才决定也不迟,但是C89仍然要求在编译时就要确定,而C99放松了这个限制。但无论是C89还是C99,都不允许一个已经分配的自动变量运行时改变大小。
所以说C函数永远不应该返回一个局部变量的地址。
要指出的是,自动分配也属于动态分配,甚至可以用alloca(3)函数来像分配堆(Heap)一样进行分配,而且释放是自动的。
动态分配
还有一种更加特殊的情况,变量的大小在运行时有可能改变,或者虽然单个变量大小不变,变量的数目却有很大弹性,不能静态分配或者自动分配,这时候可以使用堆(Heap)来满足要求。ANSI C 定义的堆操作函数是malloc(3)、calloc(3)、realloc(3)和free(3)。
使用堆(Heap)内存将带来额外的开销和风险。
[编辑]安全问题

C语言的特色之一是:语言不负责内存边界检查。
[编辑]库

C语言的标准文档要求了一个平台移植C语言的时候至少要实现的一些功能和封装的集合,称为“标准库”,标准库的声明头部通过预处理器命令#include进行引用。
在C89标准中:
文件 简介说明
<assert.h> 断言相关
<ctype.h> 字符类型判断
<errno.h> 标准报错机制
<float.h> 浮点运算
<limits.h> 各种体系结构限制
<locale.h> 本地化接口
<math.h> 数学函数
<setjmp.h> 跨函数跳转
<signal.h> 信号(类似UNIX的信号定义,但是差很远)
<stdarg.h> 可变参处理
<stddef.h> 一些标准宏定义
<stdio.h> 标准I/O库
<stdlib.h> 标准工具库函数
<string.h> ASCIIZ字符串及任意内存处理函数
<time.h> 时间相关
在95年的修正版中
<iso646.h>
<wchar.h>
<wctype.h>
在C99中增加了六个函式库
<complex.h>
<fenv.h>
<inttypes.h>
<stdbool.h>
<stdint.h>
<tgmath.h>
以上是C语言的标准,而各个平台各自又对C库函数进行的各种扩充,就浩如烟海了。如POSIX C、GNU C等。
[编辑]保留关键字

char short int unsigned
long float double struct
union void enum signed
const volatile typedef auto
register static extern break
case continue default do
else for goto if
return switch while sizeof
[编辑]C99新增关键字
_Bool _Complex _Imaginary inline restrict
[编辑]C//

C//是一种结构化的并行语言,读作C parallel。它基于标准C语言但扩展了为数不多的构造用来表示并行性和进程交互。C//的核心是称为一致区域的构造,它方便了结构化的、确定的、终止的和复合的并行程序的开发。
[编辑]参考文献

E. c语言编译器是用汇编语言写的吗

这个是肯定的。算法优化,首先是逻辑描述的精炼化。至于C,只是计算逻辑到计算机模式的一种映射,而汇编仅是利用特殊计算机指令的一个更深的藕荷。
不过有一点,C语言由于是计算逻辑到计算机模式的映射,所以不单单考虑算法本身,还肩负数据组织的实现。数据流动方式,数据组织方式,对计算性能的影响也很大。这要看是否和计算机组成原理相贴近。其实这块也是侧重逻辑的设计,而不是具体机器指令的实现,因此汇编是无能为力的。
不过在DSP等特殊CPU架构,C语言和编译器无法很好的将上述逻辑转换为机器指令,或者C本身的逻辑无法很好的贴近CPU的特性,那么还是得汇编。一个典型的例子就是如何使用DSP的并行指令(通常的矢量计算)和并发指令集,几个不同的指令(隶属不同处理单元)的同时执行。使用C语言无法描述清楚这些逻辑方式,而编译器又太水,则还是不得不用汇编。此时C语言仅能沦落到大的计算机组织特性的贴近,和整体框架,模块的设计上。细节方面无能为力了。

F. C代码实现并行执行

我是这么想的,你监测链表节点是否增加,可以通过增加一个计数器来实现。
因为链表节点的增加工作是你自己的程序实现的,那么你修改一下,让程序变成每增加一个节点,计数器就增加1,每减少一个节点,计数器就减少1.

每次截取指令时,都保存一下计数器的值。下一次截取指令时,先取得当前计数器值,再与上次保存的计数器值比较,看是否增加了。

第二个思路,你可以加一个锁(可以是一个全局标志位),当有节点加入时,锁置位,截取命令时先检查锁的状态。

阅读全文

与并行c编译器相关的资料

热点内容
dvd光盘存储汉子算法 浏览:758
苹果邮件无法连接服务器地址 浏览:963
phpffmpeg转码 浏览:672
长沙好玩的解压项目 浏览:145
专属学情分析报告是什么app 浏览:564
php工程部署 浏览:833
android全屏透明 浏览:737
阿里云服务器已开通怎么办 浏览:803
光遇为什么登录时服务器已满 浏览:302
PDF分析 浏览:486
h3c光纤全工半全工设置命令 浏览:143
公司法pdf下载 浏览:383
linuxmarkdown 浏览:350
华为手机怎么多选文件夹 浏览:683
如何取消命令方块指令 浏览:350
风翼app为什么进不去了 浏览:779
im4java压缩图片 浏览:362
数据查询网站源码 浏览:151
伊克塞尔文档怎么进行加密 浏览:893
app转账是什么 浏览:163