C语言

定义
  C语言是一种计算机程序设计语言。它既有高级语言的特点,又具有汇编语言的特点。它可以作为系统设计语言,编写工作系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。因此,它的应用范围广泛。
  C语言对操作系统和系统使用程序以及需要对硬件进行操作的场合,用C语言明显优于其它解释型高级语言,有一些大型应用软件也是用C语言编写的。
  C语言具有绘图能力强,可移植性,并具备很强的数据处理能力,因此适于编写系统软件,三维,二维图形和动画。它是数值计算的高级语言。
  常用的C语言IDE(集成开发环境)有Microsoft Visual C++,Borland C++,Watcom C++ ,Borland C++ ,Borland C++ Builder,Borland C++ 3.1 for DOS,Watcom C++ 11.0 for DOS,GNU DJGPP C++ ,Lccwin32 C Compiler 3.1,Microsoft C,High C,Turbo C等等......
C语言的发展历史
  C语言的原型ALGOL 60语言。(也称为A语言)
  1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言。
  1967年,剑桥大学的Matin Richards 对CPL语言进行了简化,于是产生了BCPL语言。
  1970年,美国贝尔实验室的Ken Thompson将BCPL进行了修改,并为它起了一个有趣的名字“B语言”。意思是将CPL语言煮干,提炼出它的精华。并且他用B语言写了第一个UNIX操作系统。
  而在1973年,B语言也给人“煮”了一下,美国贝尔实验室的D.M.RITCHIE在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。
  为了使UNIX操作系统推广,1977年Dennis M.Ritchie 发表了不依赖于具体机器系统的C语言编译文本《可移植的C语言编译程序》。即是著名的ANSI C。
  1978年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言。同时由 B.W.Kernighan和D.M.Ritchit合著了著名的“THE C PROGRAMMING LANGUAGE”一书。通常简称为《K&R》,也有人称之为《K&R》标准。但是,在《K&R》中并没有定义一个完整的标准C 语言,后来由美国国家标准协会(American National Standards Institute)在此基础上制定了一个C 语言标准,于一九八三年发表。通常称之为ANSI C。
  1988年,随着微型计算机的日益普及, C语言出现了许多版本。由于没有统一的标准,使得这些C语言之间出现了一些不一致的地方。为了改变这种情况,美国国家标准研究所(ANSI)为C语言制定了一套ANSI标准, 成为现行的C语言标准3.C语言的主要特点 。C语言发展迅速, 而且成为最受欢迎的语言之一, 主要因为它具有强大的功能。许多著名的系统软件, 如DBASE Ⅲ PLUS、DBASE Ⅳ 都是由C 语言编写的。用C语言加上一些汇编语言子程序, 就更能显示C语言的优势了,象PC- DOS 、WORDSTAR等就是用这种方法编写的。
C语言的优点
  1. 简洁紧凑、灵活方便
  C语言一共只有32个关键字,9种控制语句,程序书写自由,主要用小写字母表示。它把高级语言的基本结构和语句与低级语言的实用性结合起来。 C 语言可以象汇编语言一样对位、字节和地址进行操作, 而这三者是计算机最基本的工作单元。
  2. 运算符丰富
  C的运算符包含的范围很广泛,共有种34个运算符。C语言把括号、赋值、强制类型转换等都作为运算符处理。从而使C的运算类型极其丰富表达式类型多样化,灵活使用各种运算符可以实现在其它高级语言中难以实现的运算。
  3. 数据结构丰富
  C的数据类型有:整型、实型、字符型、数组类型、指针类型、结构体类型、共用体类型等。能用来实现各种复杂的数据类型的运算。并引入了指针概念,使程序效率更高。另外C语言具有强大的图形功能, 支持多种显示器和驱动器。且计算功能、逻辑判断功能强大。
  4. C是结构式语言
  结构式语言的显著特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立。这种结构化方式可使程序层次清晰, 便于使用、维护以及调试。C语言是以函数形式提供给用户的,这些函数可方便的调用,并具有多种循环、条件语句控制程序流向,从而使程序完全结构化。
  5. C语法限制不太严格,程序设计自由度大
  虽然C语言也是强类型语言,但它的语法比较灵活,允许程序编写者有较大的自由度。
  6. C语言允许直接访问物理地址,可以直接对硬件进行操作
  因此既具有高级语言的功能,又具有低级语言的许多功能,能够象汇编语言一样对位、字节和地址进行操作,而这三者是计算机最基本的工作单元,可以用来写系统软件。
  7. C语言程序生成代码质量高,程序执行效率高
  一般只比汇编程序生成的目标代码效率低10へ20%。
  8. C语言适用范围大,可移植性好
  C语言有一个突出的优点就是适合于多种操作系统, 如DOS、UNIX,也适用于多种机型。
C语言的缺点
  1. C语言的缺点主要是表现在数据的封装性上,这一点使得C在数据的安全性上做的有很大缺陷,这也是C和C++的一大区别。
  2. C语言的语法限制不太严格,对变量的类型约束不严格,影响程序的安全性,对数组下标越界不作检查等。从应用的角度,C语言比其他高级语言较难掌握。
C语言指针
  指针就是C语言的一大特色,可以说C语言优于其它高级语言的一个重要原因就是因为它有指针操作可以直接进行靠近硬件的操作,但是C的指针操作也给它带来了很多不安全的因素。C++在这方面做了很好的改进,在保留了指针操作的同时又增强了安全性。Java取消了指针操作,提高了安全性。
C源程序的结构特点
  1.一个C语言源程序可以由一个或多个源文件组成。
  2.每个源文件可由一个或多个函数组成。
  3.一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。
  4.源程序中可以有预处理命令(include 命令仅为其中的一种),预处理命令通常应放在源文件或源程序的最前面。
  5.每一个说明,每一个语句都必须以分号结尾。但预处理命令,函数头和花括号“}”之后不能加分号。
  6.标识符,关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,也可不再加空格来间隔。
C源程序的关键字
  所谓关键字就是已被C语言本身使用, 不能作其它用途使用的字。例如关键字不能用作变量名、函数名等
  由ANSI标准定义的C语言关键字共32个 :
  auto double int struct break else long switch
  case enum register typedef char extern return union
  const float short unsigned continue for signed void
  default goto sizeof volatile do if while static
  根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类。
  1 数据类型关键字
  A基本数据类型(5个)
  void :声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
  char :字符型类型数据,属于整型数据的一种
  int :整型数据,通常为编译器指定的机器字长
  float :单精度浮点型数据,属于浮点数据的一种
  double :双精度浮点型数据,属于浮点数据的一种
  B 类型修饰关键字(4个)
  short :修饰int,短整型数据,可省略被修饰的int。
  long :修饰int,长整形数据,可省略被修饰的int。
  signed :修饰整型数据,有符号数据类型
  unsigned :修饰整型数据,无符号数据类型
  C 复杂类型关键字(5个)
  struct :结构体声明
  union :共用体声明
  enum :枚举声明
  typedef :声明类型别名
  sizeof :得到特定类型或特定类型变量的大小
  D 存储级别关键字(6个)
  auto :指定为自动变量,由编译器自动分配及释放。通常在栈上分配
  static :指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部
  register :指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数
  extern :指定对应变量为外部变量,即在另外的目标文件中定义,可以认为是约定由另外文件声明的韵蟮囊桓觥耙谩?
  const :与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
  volatile :与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值
  2 流程控制关键字
  A 跳转结构(4个)
  return :用在函数体中,返回特定值(或者是void值,即不返回值)
  continue :结束当前循环,开始下一轮循环
  break :跳出当前循环或switch结构
  goto :无条件跳转语句
  B 分支结构(5个)
  if :条件语句
  else :条件语句否定分支(与if连用)
  switch :开关语句(多重分支语句)
  case :开关语句中的分支标记
  default :开关语句中的“其他”分治,可选。
  C 循环结构(3个)
  for :for循环结构,for(1;2;3)4;的执行顺序为1->2->4->3->2...循环,其中2为循环条件
  do :do循环结构,do 1 while(2); 的执行顺序是 1->2->1...循环,2为循环条件
  while :while循环结构,while(1) 2; 的执行顺序是1->2->1...循环,1为循环条件
  以上循环语句,当循环条件表达式为真则继续循环,为假则跳出循环。
新标准
  在ANSI标准化后,C语言的标准在一段相当的时间内都保持不变,尽管C++继续在改进。(实际上,Normative Amendment1在1995年已经开发了一个新的C语言版本。但是这个版本很少为人所知。)标准在90年代才经历了改进,这就是 ISO9899:1999(1999年出版)。这个版本就是通常提及的C99。它被ANSI于2000年三月采用。
  在C99中包括的特性有:
  对编译器限制增加了,比如源程序每行要求至少支持到 4095 字节,变量名函数名的要求支持到 63 字节 (extern 要求支持到 31)
  预处理增强了。例如:
  宏支持取参数 #define Macro(...) __VA_ARGS__
  使用宏的时候,参数如果不写,宏里用 #,## 这样的东西会扩展成空串。(以前会出错的)
  支持 // 行注释(这个特性实际上在C89的很多编译器上已经被支持了)
  增加了新关键字 restrict, inline, _Complex, _Imaginary, _Bool
  支持 long long, long double _Complex, float _Complex 这样的类型
  支持 <: :> <% %> %: %:%: ,等等奇怪的符号替代
  支持了不定长的数组。数组的长度就可以用变量了。声明类型的时候呢,就用 int a[*] 这样的写法。不过考虑到效率和实现,这玩意并不是一个新类型。所以就不能用在全局里,或者 struct union 里面,如果你用了这样的东西,goto 语句就受限制了。
  变量声明不必放在语句块的开头,for 语句提倡这么写 for(int i=0;i<100;++i) 就是说,int i 的声明放在里面,i 只在 for 里面有效。(VC没有遵守这条标准,i 在 for 外也有效)
  当一个类似结构的东西需要临时构造的时候,可以用 (type_name){xx,xx,xx} 这有点像 C++ 的构造函数
  初始化结构的时候现在可以这样写:
  struct {int a[3], b;} hehe[] = { [0].a = , [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
  取消了不写函数返回类型默认就是 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_copy 可以复制 ... 的参数。<time.h> 里多了个 struct tmx 对 struct tm 做了扩展
  输入输出对宽字符还有长整数等做了相应的支持
  相对于c89的变化还有
  1、增加restrict指针
  C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。restrict数据类型不改变程序的语义。
  如果某个函数定义了两个restrict指针变元,编译程序就假定它们指向两个不同的对象,memcpy()函数就是restrict指针的一个典型应用示例。C89中memcpy()函数原型如下:
  代码: void *memcpy (void *s1, const void *s2, size_t size);
  如果s1和s2所指向的对象重叠,其操作就是未定义的。memcpy()函数只能用于不重叠的对象。C99中memcpy()函数原型如下:代码: void *memcpy(void *restrict s1, const void *restrict s2,size_t size);
  通过使用restrict修饰s1和s2 变元,可确保它们在该原型中指向不同的对象。
  2、inline(内联)关键字
  内联函数除了保持结构化和函数式的定义方式外,还能使程序员写出高效率的代码.函数的每次调用与返回都会消耗相当大的系统资源,尤其是当函数调用发生在重复次数很多的循环语句中时.一般情况下,当发生一次函数调用时,变元需要进栈,各种寄存器内存需要保存.当函数返回时,寄存器的内容需要恢复。如果该函数在代码内进行联机扩展,当代码执行时,这些保存和恢复操作旅游活动会再发生,而且函数调用的执行速度也会大大加快。函数的联机扩展会产生较长的代码,所以只应该内联对应用程序性能有显著影响的函数以及长度较短的函数
  3、新增数据类型
  _Bool
  值是0或1。C99中增加了用来定义bool、true以及false宏的头文件夹<stdbool.h>,以便程序员能够编写同时兼容于C与C++的应用程序。在编写新的应用程序时,应该使用
  <stdbool.h>头文件中的bool宏。
  _Complex and _Imaginary
  C99标准中定义的复数类型如下:float_Complex; float_Imaginary; double_Complex; double_Imaginary; long double_Complex; long double_Imaginary.
  <complex.h>头文件中定义了complex和imaginary宏,并将它们扩展为_Complex和_Imaginary,因此在编写新的应用程序时,应该使用<stdbool.h>头文件中的complex 和imaginary宏。
  long long int
  C99标准中引进了long long int(-(2e63 - 1)至2e63 - 1)和unsigned long long int(0 - 2e64 - 1)。long long int能够支持的整数长度为64位。
  4、对数组的增强
  可变长数组
  C99中,程序员声明数组时,数组的维数可以由任一有效的整型表达式确定,包括只在运行时才能确定其值的表达式,这类数组就叫做可变长数组,但是只有局部数组才可以是变长的.
  可变长数组的维数在数组生存期内是不变的,也就是说,可变长数组不是动态的.可以变化的只是数组的大小.可以使用*来定义不确定长的可变长数组。
  数组声明中的类型修饰符
  在C99中,如果需要使用数组作为函数变元,可以在数组声明的方括号内使用static关键字,这相当于告诉编译程序,变元所指向的数组将至少包含指定的元素个数。也可以在数组声明的方括号内使用restrict,volatile,const 关键字,但只用于函数变元。如果使用restrict,指针是初始访问该对象的惟一途径。如果使用const,指针始终指向同一个数组。使用 volatile没有任何意义。
  5、单行注释
  引入了单行注释标记 "//" , 可以象C++一样使用这种注释了。
  6、分散代码与声明
  7、预处理程序的修改
  a、变元列表
  宏可以带变元,在宏定义中用省略号(...)表示。内部预处理标识符__VA_ARGS__决定变元将在何处得到替换。例:#define MySum(...) sum(__VA_ARGS__) 语句MySum(k,m,n);
  将被转换成:sum(k, m, n); 变元还可以包含变元。例: #define compare(compf, ...) compf(__VA_ARGS__) 其中的compare(strcmp,"small", "large"); 将替换成:strcmp("small","large");
  b、_Pragma运算符
  C99引入了在程序中定义编译指令的另外一种方法:_Pragma运算符。格式如下:
  _Pragma("directive")
  其中directive是要满打满算的编译指令。_Pragma运算符允许编译指令参与宏替换。
  c、内部编译指令
  STDCFP_CONTRACT ON/OFF/DEFAULT 若为ON,浮点表达式被当做基于硬件方式处理的独立单元。默认值是定义的工具。
  STDCFEVN_ACCESS ON/OFF/DEFAULT 告诉编译程序可以访问浮点环境。默认值是定义的工具。
  STDC CX_LIMITED_RANGE ON/OFF/DEFAULT 若值为ON,相当于告诉编译程序某程序某些含有复数的公式是可靠的。默认是OFF。
  d、新增的内部宏
  __STDC_HOSTED__ 若操作系统存在,则为1
  __STDC_VERSION__ 199991L或更高。代表C的版本
  __STDC_IEC_599__ 若支持IEC 60559浮点运算,则为1
  __STDC_IEC_599_COMPLEX__ 若支持IEC 60599复数运算,则为1
  __STDC_ISO_10646__ 由编译程序支持,用于说明ISO/IEC 10646标准的年和月格式:yyymmmL
  9、复合赋值
  C99中,复合赋值中,可以指定对象类型的数组、结构或联合表达式。当使用复合赋值时,应在括弧内指定类型,后跟由花括号围起来的初始化列表;若类型为数组,则不能指定数组的大小。建成的对象是未命名的。
  例: double *fp = (double[]) {1.1, 2.2, 3.3};
  该语句用于建立一个指向double的指针fp,且该指针指向这个3元素数组的第一个元素。 在文件域内建立的复合赋值只在程序的整个生存期内有效。在模块内建立的复合赋值是局部对象,在退出模块后不再存在。
  10、柔性数组结构成员
  C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结构中的柔性数组成员前面必须至少一个其他成员。柔性数组成员允许结构中包含一个大小可变的数组。sizeof返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
  11、指定的初始化符
  C99中,该特性对经常使用稀疏数组的程序员十分有用。指定的初始化符通常有两种用法:用于数组,以及用于结构和联合。用于数组的格式:[index] = vol; 其中,index表示数组的下标,vol表示本数组元素的初始化值。
  例如: int x[10] = {[0] = 10, [5] = 30}; 其中只有x[0]和x[5]得到了初始化.用于结构或联合的格式如下:
  member-name(成员名称)
  对结构进行指定的初始化时,允许采用简单的方法对结构中的指定成员进行初始化。
  例如: struct example{ int k, m, n; } object = {m = 10,n = 200};
  其中,没有初始化k。对结构成员进行初始化的顺序没有限制。
  12、printf()和scanf()函数系列的增强
  C99中printf()和scanf()函数系列引进了处理long long int和unsigned long long int数据类型的特性。long long int 类型的格式修饰符是ll。在printf()和scanf()函数中,ll适用于d, i, o, u 和x格式说明符。另外,C99还引进了hh修饰符。当使用d, i, o, u和x格式说明符时,hh用于指定char型变元。ll和hh修饰符均可以用于n说明符。
  格式修饰符a和A用在printf()函数中时,结果将会输出十六进制的浮点数。格式如下: [-]0xh, hhhhp + d 使用A格式修饰符时,x和p必须是大写。A和a格式修饰符也可以用在scanf()函数中,用于读取浮点数。调用printf()函数时,允许在%f说明符前加上l修饰符,即%lf,但不起作用。
  13、C99新增的库
  C89中标准的头文件
  <assert.h> 定义宏assert()
  <ctype.h> 字符处理
  <errno.h> 错误报告
  <float.h> 定义与实现相关的浮点值勤
  <limits.h> 定义与实现相关的各种极限值
  <locale.h> 支持函数setlocale()
  <math.h> 数学函数库使用的各种定义
  <setjmp.h> 支持非局部跳转
  <signal.h> 定义信号值
  <stdarg.h> 支持可变长度的变元列表
  <stddef.h> 定义常用常数
  <stdio.h> 支持文件输入和输出
  <stdlib.h> 其他各种声明
  <string.h> 支持串函数
  <time.h> 支持系统时间函数
  C99新增的头文件和库
  <complex.h> 支持复数算法
  <fenv.h> 给出对浮点状态标记和浮点环境的其他方面的访问
  <inttypes.h> 定义标准的、可移植的整型类型集合。也支持处理最大宽度整数的函数
  <iso646.h> 首先在此1995年第一次修订时引进,用于定义对应各种运算符的宏
  <stdbool.h> 支持布尔数据类型类型。定义宏bool,以便兼容于C++
  <stdint.h> 定义标准的、可移植的整型类型集合。该文件包含在<inttypes.h>中
  <tgmath.h> 定义一般类型的浮点宏
  <wchar.h> 首先在1995年第一次修订时引进,用于支持多字节和宽字节函数
  <wctype.h> 首先在1995年第一次修订时引进,用于支持多字节和宽字节分类函数
  14、__func__预定义标识符
  用于指出__func__所存放的函数名,类似于字符串赋值。
  15、其它特性的改动
  放宽的转换限制
  限制 C89标准 C99标准
  数据块的嵌套层数 15 127
  条件语句的嵌套层数 8 63
  内部标识符中的有效字符个数 31 63
  外部标识符中的有效字符个数 6 31
  结构或联合中的成员个数 127 1023
  函数调用中的参数个数 31 127
  不再支持隐含式的int规则
  删除了隐含式函数声明
  对返回值的约束
  C99中,非空类型函数必须使用带返回值的return语句.
  扩展的整数类型
  扩展类型 含义
  int16_t 整数长度为精确16位
  int_least16_t 整数长度为至少16位
  int_fast32_t 最稳固的整数类型,其长度为至少32位
  intmax_t 最大整数类型
  uintmax_t 最大无符号整数类型
  对整数类型提升规则的改进
  C89中,表达式中类型为char,short int或int的值可以提升为int或unsigned int类型.
  C99中,每种整数类型都有一个级别.例如:long long int 的级别高于int, int的级别高于char等.在表达式中,其级别低于int或unsigned int的任何整数类型均可被替换成int或unsigned int类型.
  有必要说明的是,c99的main()函数要求必须返回一个int值给程序的激活者(通常是操作系统)0表示正常推出,非0表示异常。
  但是各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的时候,微软和Borland却似乎对此不感兴趣。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值