C语言基础

来源:互联网 发布:think in java 英文版 编辑:程序博客网 时间:2024/06/03 23:44
 第一部分 综述      

       C语言是一种计算机程序设计语言,它既具有高级语言的特点,又具有汇编语言的特点。它由美国贝尔研究所的D.M.Ritchie于1972年推出,1978年后,C语言已先后被移植到大、中、小及微型机上,它可以作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。它的应用范围广泛,具备很强的数据处理能力,不仅仅是在软件开发上,而且各类科研都需要用到C语言,适于编写系统软件,三维,二维图形和动画,具体应用比如单片机以及嵌入式系统开发

     随着C语言的发展,整个发展的历程中已经演变出很多版本,这使得各个C语言之间有很多不一致的地方,导致程序编译等一系列的不方便。为了改变这种情况,美国国家标准研究所(ANSI)为C语言制定了一套ANSI标准,成为现行的C语言标准,即我们常说的ANSI C。
     C语言是世界上流行、使用最广泛的高级程序设计语言之一。其实我个人觉得,C语言应该算是一种中级语言,在计算机的语言中,越是接近底层的语言,级别越低,但是编译和程序的运行效率会提高,级别越高,编译的难度会降级,但是运行和转换的时间增长,降低了程序运行的效率。
    C语言在设计程序时没有太严格的要求,灵活性高,这一方面很受程序员的喜爱,这也决定了C语言相对其他语言来说难度较大。
   C语言有以下优点
   1、简洁紧凑、灵活方便 
  C语言一共只有32个关键字,9种控制语句,程序书写形式自由,区分大小写。把高级语言的基本结构和语句与低级语言的实用性结合起来。C 语言可以像汇编语言一样对字节地址进行操作,而这三者是计算机最基本的工作单元。
注:32个关键字符是
   auto break case char const continue defaultdo double else enum extern float forgoto if int long register return shortsignedstatic sizof struct switch typedef unionunsigned void volatile while

  2、运算符丰富 
  C语言的运算符包含的范围很广泛,共有34种运算符。C语言把括号赋值强制类型转换等都作为运算符处理。从而使C语言的运算类型极其丰富,表达式类型多样化。灵活使用各种运算符可以实现在其它高级语言中难以实现的运算。
  3、数据类型丰富 
  C语言的数据类型有:整型、实型、字符型、数组类型、指针类型、结构体类型、共用体类型等。能用来实现各种复杂的数据结构的运算。并引入了指针概念,使程序效率更高。另外C语言具有强大的图形功能,支持多种显示器和驱动器。且计算功能、逻辑判断功能强大。
  4、表达方式灵活实用 
  C语言提供多种运算符和表达式值的方法,对问题的表达可通过多种途径获得,其程序设计更主动、灵活。它语法限制不太严格,程序设计自由度大,如对整型量与字符型数据及逻辑型数据可以通用等。
  5、允许直接访问物理地址,对硬件进行操作 
  由于C语言允许直接访问物理地址,可以直接对硬件进行操作,因此它既具有高级语言的功能,又具有低级语言的许多功能,能够像汇编语言一样对位、字节和地址进行操作,而这三者是计算机最基本的工作单元,可用来写系统软件
  6、生成目标代码质量高,程序执行效率高 
  C语言描述问题比汇编语言迅速,工作量小、可读性好,易于调试、修改和移植,而代码质量与汇编语言相当。
  7、可移植性好 
  C语言在不同机器上的C编译程序,86%的代码是公共的,所以C语言的编译程序便于移植。在一个环境上用C语言编写的程序,不改动或稍加改动,就可移植到另一个完全不同的环境中运行。
  8、表达力强 
  C语言有丰富的数据结构和运算符。包含了各种数据结构,如整型、数据类型、指针类型和联合类型等,用来实现各种数据结构的运算。C语言的运算符有34种,范围很宽,灵活使用各种运算符可以实现难度极大的运算。 
  C语言能直接访问硬件的物理地址,能进行位(bit)操作。兼有高级语言和低级语言的许多优点。 
  它既可用来编写系统软件,又可用来开发应用软件,已成为一种通用程序设计语言。
    C语言具有绘图能力强,可移植性,并具备很强的数据处理能力,因此适于编写系统软件,三维,二维图形和动画它是数值计算的高级语言。 
  常用的编译软件有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等。
      在本文中,使用的都是VisualC++6.0进行编译。

第二部分  编程从第一个程序“Hello World!”开始

   编程在有些人看来会觉得比较难,因为编程有一点抽象,并不是像那些实体一样能感受到,其实编程也不是很枯燥,那么我们就从第一个程序“Hello World!”开始

 [例1] Hello World 

#include<stdio.h>  这是C语言设计中的头文件名,因为我们下面要调用 printf() 这个函数,所以要在代码的最前面声明。
viod main()          这是C语言设计中的主函数名,注意 一个C语言的程序代码中只能有一个主函数。
{
     printf("Hello World!\n" )  printf()表示将括号内的字符串打印到电脑显示器上 引号中的反斜杠\n是转义字符 表示光标换行
}

通过上面这个最简单的C语言程序,也许大家会觉得,编程并不是想象的那么难。
下面我们来看另一个例子。

[例2] 一个简单的数学运算
  #include<math.h> 这个也是头文件名 但是是math.h 原因是我们下面用了一个 sin()的数学函数,为了正常使用,所以声明调用
  #include<stdio.h> 这是C语言设计中的头文件名,因为我们下面要调用 printf()和scanf()这个函数,所以要在代码的最前面声明。
  main()                     这是C语言设计中的主函数名,注意 一个C语言的程序代码中只能有一个主函数。
{ 
   double x,s;            定义两个变量为双精度浮点型,供以后使用(关于数据类型的在以后的文章中会详细讲到)
    printf("input number:\n");   在运行程序的时候显示input number \n是转义字符 表示光标回车 在下一行输入。
    scanf("%lf",&x);        把输入的数字赋值给变量x (关于%和&符号的连接问题,在以后的文章中会讲到)
    s=sin(x);                    把sin(x)的运算结果赋值给变量s
    printf("sine of %lf is %lf\n",x,s);  输出结果

}

   值得注意的是,在这里的printf() scanf() sin() 这些函数都是系统已经为你编写好运算过程的,可以直接调用的函数,如果自己定义函数,还得记得在程序中生命函数的运算法则,这样编译环境才能够识别并正确运行。
例如:
  int add(int x,int y)  定义add()这个函数,中间定义了函数中使用的变量 x和y
{
return x+y;                声明add()这个函数的运算法则,是把变量都相加。
}

  特别注意,定义函数不能当作一个独立的程序进行运行,只能在一个程序中起声明函数作用。

第三部分 C语言数据类型
     数据是我们日常生活中经常见到的东西,那么在C语言中也不例外。
          C语言的数据类型分为:基本数据类型,指针数据类型,构造数据类型和空类型。
          在基本数据类型中,又分为:整型,字符型,实型(浮点型)和枚举类型。
          在实型中,分为单精度型和双精度型。
          在构造数据类型中又分为:数组,结构和共同体。
   指针数据类型是C语言设计中比较难的一个数据类型,在上篇文章中我们知道,C语言可以直接访问内存等硬件,这就为控制硬件有了极大的方便,指针类型就是指出这个数据在内存中所占的位置。(在稍后的篇幅中会说到)
   本文重点讲解基本数据类型。
 
第四部分 基本数据类型及其常量和变量
  什么是基本数据类型?我们来看一下比较规范的解释。基本数据类型的值不可以再分解为其它类型。也就是说,基本数据类型是自我说明的。说白了,基本数据类型就是我们身体中的细胞,他能构成很多很多的组织和器官。
   那么构造数据类型是什么呢,我们再来看一下比较规范的解释:是根据已定义的一个或多个数据类型用构造的方法来定义的。也就是说,一个构造类型的值可以分解成若干个“成员”或“元素”。每个“成员”都是一个基本数据类型或又是一个构造类型。在C语言中,构造类型有以下几种:
数组类型
结构类型
联合(共用体)类型
  那么我刚才所说到的指针数据类型又是什么呢?指针数据类型是一种特殊的,同时又起重要作用的数据类型。其值用来表示某个变量在内存存储器中的地址。虽然指针变量的取值类似整数型,但是这两个完全不一样,所以不能混淆。
  空类型又是什么呢?在调用函数的时候,通常会向调用函数的人返回一个数值,这个数值应该是有数据类型的,应该在函数的定义和函数的说明中给予说明。例如int min(int x,int y),由于有了int,这个函数表明返回的函数值应该是整型的。但是还有一类函数,在调用函数后不需要向调用者返回函数值,这种函数可以定义为空类型,其类型说明符为void。
       这篇文章重点讲基本数据类型中的整型,浮点型和字符型。
 
第五部分 变量和常量
 
   在基本数据类型中,我们又可以按照数据的取值是否可以发生改变分为变量和常量。
  在程序的执行过程中,其值不变的是常量,而数值发生改变的是变量。
  可以和数据类型结合起来分类 如整形变量,整形常量……等。
  符号常量指的是用一个符号代表一个常量,在C语言中,可以这样来节约修改程序的时间。
  在使用符号常量之前,需要先定义,格式如下:
  #define 标识符 常量
  下面我们来看一个例子:
  [例1]define
 
  #define PRICE 30  我们定义PRICE这个符号常量的值为30
  void main()
  {
      int num,total;    定义整形常量num,total
      num=10;          赋值
      total=num* PRICE;
      printf(“total=%d”,total)输出
   }
    也许有些没有看明白,我来解释一下。这里面我们把30给了PRICE 这个符号常量,那么在以后的程序语句中出现PRICE,编译环境会把他转换为30,然后进行计算。
    符号常量有什么好处呢?加入我们把PRICE变成30,那么我们想修改这个数值的时候,还得一个一个的修改,如果使用了符号常量,我们只需在程序的开头进行修改,那么下面的程序语言中的所有都会修改,大大的提高了程序编译的效率。
    下面我们再来说说变量:
   其值可以改变的量称为变量,一个变量应该有一个名字,在内存中占据一定的存储单元,定义变量一定只能在使用变量之前,一般放在函数体的开头部分。
例如:
 
int k = 3;
 
int            k             =           3;                        0x0010ff
         变量的名称                变量的值            在内存中的地址
 
第六部分  整型常量的表示方法 
 
在C语言,使用的整型常量有 八进制 十六进制和十进制三种。
1.十进制整数。如356,-120,0。
2.八进制整数。八进制形式的常量都以0开头,如0123,也就是十进制的83;-011,也就是十进制的-9。
3.十六进制整数。十六进制的常量都是以0x开头,如0x123,就是十进制的291。
C语言中,程序是根据前缀来区分数的,一定要记住八进制形式的常量都以0开头,十六进制的常量都是以0x开头。
整型常数的后缀:这是在TC编译环境上的问题,VC++不存在这样的问题。有兴趣的可以去查一下。
 
在这里补充一个常识:一个字节(BYTE)=8位(bit)
在宽带的带宽中,那个M是,Mbps,是BIT这个B,而不是BYTE的B    
数值是以补码的形式存在,
正数的补码和原码相同,
负数的补码是将该数的绝对值的二进制形式按位取反后加1.
例如,求-10的补码
10的二进制原码是:00001010
取反                       11110101
再加1                     11110110
 
第七部分 整型变量的分类
 
基本型:类型说明符为int 在内存中占四个字符(可以用size of自己在自己的编译环境下查看)
短整型:类型说明符是short int 或者 short
长整型:类型说明符是long int 或者 long
无符号型:类型说明符是unsigned
 
整型变量的定义 一般格式为:
 
类型说明符  变量名标识符  变量名称符
 
例如:
int a,b,c;
long x,y;
注意,每个语句后面必须以分号结尾,否则在编译的时候会出现问题,在C语言中,你可以这样理解,分号就是句号。
 
第八部分 整型变量的溢出
 
  最后我们来说一个比较好玩的东西——数据溢出
  因为C语言的程序会很自由,如果编程不谨慎的话,会出现数据溢出。
  我们来看一个例子:
  [例2] 数据溢出
 
 #include<stdio.h>
 main()
   short a,b;
   a=32767
   b=a+1
   printf("%d,%d\n"a,b)
}
 
  大家可以在自己的程序编译环境中试一下这个代码,按正常来说,32767+1应该就是32768,但是这个程序出来的结果却是-32768,为什么呢?
  程序中我定义了short int ,用size of 可知short int 占两个字符,两个字符就是2*8=16位,所以数字的取值范围就应该是2的16次方正负对半,就是32768,由于包括0,所以最大只能在32767. 超出了32767,就会发生数据溢出。
 32767的十六位表示方式:0111111111111111
 如果再加上一,会变成什么呢?
  1000000000000000
那么这个是不是就是-32768?嗯 是的
提示 用上文所说的补码求出来验证。
   这就是数据的溢出,这就需要程序员在编写和定义常量和变量的同时,记住这些定义的数值取值范围!
上一章节我们说到,C语言的几种数据类型,这一章就告诉大家C语言的运算符和基本的表达式。
   第九部分、算术运算符和算术表达式
       首先我们来说一下运算符的优先级,在C语言中,运算符一共分为15级,1级是最高级别,15级是最低级别,在表达式中,优先级高的较于优先级低的进行运算,而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。
       然后我们再说一下运算符的结合性,在C语言中,运算符的结合性分为两种,即左结合性(自左向右)和右结合性(自右向左)。如表达式X+Y-Z,这样进行运算的时候,应该是先Y和X进行加法运算,然后在和Z进行减法运算。这种自左向右的运算方式就是左结合性。最为典型的右结合运算是赋值运算符。例如表达式X=Y=Z,按照右结合性运算规则应该先进行y=z运算,然后再进行x=(y=z)的运算。在C语言中有很多运算符都是右结合性运算符,到时候要注意区分,以免造成误解。
    基本算术运算符
    加法运算符"+":加法运算符是双目运算符,即有两个元素参加运算,如“A+B”"4+8" 具有右结合性。
    减法运算符“-”:减法运算符为双目运算符,但是在作为负值运算符的时候,可以做单目运算,如“-8”"-x",具有左结合性。
    乘法运算符“*”,双目运算符,具有左结合性。
   除法运算符“/”,双目运算符,具有左结合性。参与运算量均为整型时,结果也为整型,舍去小数。如果运算量中有一个是实型,则运算结果为双精度实型。
强制类型转换运算符
其一般形式为:
  类型说明符 表达式
作用为把表达式的运算符强制转换为类型说明符所表示的类型。

例如:
(float)a  把a转换为实型。

自增自减运算符(使用广泛,重要)
自增1,自减1运算符。自增用“++” 表示,其功能是使变量的值自增1,自减运算符为“-”其功能是使变量的值自减1
均为单目运算符,具有右结合性。
自增自减运算符有以下四种的表现形式
++i     i的值增加1后再参与其他的运算
-i        i减少1以后再参与其他的运算
i++    i先参与运算,然后他的值再增加1
i-       i先参加运算,然后他的值再减1

   以上四种运算符的表现形式一定要记得清楚,准确,自增自减运算符使程序得到了很大的简化,但是容易出错,尤其对于新程序员来说一定要注意。
我们来看一下下面这个例子
#include <stdio.h>
 void main()
{ 
  int i=8;  
   printf("%dn",++i);  在这一步的运算 得出的数值为9
  printf("%dn",--i); 在这一步运算 得到的数据为8 
  printf("%dn",i++); 
  printf("%dn",i--);
  printf("%dn",-i++);
 printf("%dn",-i--);
}
其他的请各位读者自行计算。
第十部分、赋值运算符与赋值表达式

 赋值运算符

简单的赋值运算符表达式:简单的赋值运算符记为“=”,特别注意,这里面的所谓的等号不是真正意义上的等号,在C语言中,等号是“==”这个运算符号,赋值运算符的一般形式为:
变量 = 表达式
例如:
W=a+b
Y=sinx+cosx
赋值运算符具有右结合性。

类型转换

如果赋值运算符两边的数据类型不相同,系统将自行进行转换,把赋值号右边的类型转化为赋值号左边的类型。具体规则如下:
1.实型赋予整型,舍去小数部分。
2.整型赋予实型,数值不变,但将以浮点形式存放,即增加小数部分(小数部分的值为0)
3.字符型赋予整型。由于字符型占一个字节,而整型为两个字节(对于TC编译环境),故将字符的ASCII码值放到整型量的低八位中,高八位为0.整型赋予字符型,只把低八位赋予字符量。
我们来看一个例子:


#include <stdio.h> 
void main()
{ 
  int a,b=322;  
  float x,y=8.88;  
  char c1='k',c2; 
   a=y; 
   x=b;
   a=c1; 
   c2=b; 
   printf("%d,%f,%d,%c",a,x,a,c2);
}
 
请各位读者用自己的VC++进行验证,看看会出现什么情况。

复合的赋值运算符
 
在赋值符号 = 之前加入其它的二目运算符号,构成一个新的运算符号。例如 += ^= *=等等。
例如:
a+=5 等价于a=a+5
x*=y+7 等价于 x=x*(y+7)

这种复合运算符对于初学的编程员不是太习惯,但是对于编译却有很大优点。提高了编译效率,也有利于写出高质量代码。

逗号运算符与逗号表达式

在C语言中,逗号也是一种运算符,称为逗号运算符。其功能是把两个表达式连接起来组成一个表达式。
其一般形式为:
表达式1,表达式2
其求值过程是,分别求出两个表达式的值,然后以表达式2的值作为整个逗号表达式的值。
我们来看一个例子:

#include <stdio.h> 
void main()
{ 
  int a=2,b=4,c=6,x,y;  
  y=(x=a+b),(b+c); 
  printf("y=%d,x=%d",y,x);
}
这个例子的运算结果应该是10

对于逗号运算符再做出一下几点说明:
1.逗号表达式中的表达式1,表达式2,也可以是逗号运算符。
例如:
表达式1,(表达式2,表达式3)形成嵌套结构。
我们也可以对逗号表达式进行推广,
表达式1,表达式2,……表达式n

2、程序中使用逗号表达式,分别是求逗号表达式内各个表达式的值,并不一定要求整个逗号表达式的值。
并不是在所有出现逗号表达式的地方都叫做逗号表达式,如在变量说明中,函数参数表中的逗号只是作为各个变量之间的间隔符。


1 0