你的位置:首页 > 操作系统

[操作系统]01_C语言基础


内容提要:

1. C语言概述
2. 数据类型、运算符与表达式
3. C语言程序结构

4. VC6.0使用练习

知识详解01:C语言的历史

1. C语言与其它语言比较

汇编语言:

(1).可直接对硬件进行操作,执行效率较高;依赖于计算机硬件,可读性和可移植性较差。

(2).对硬件进行操作,执行效率高,用一串数字代码表示指令,更接近计算机使用的详细操作步骤。依赖于计算机硬件(比如写了一段汇编程序控制51单片机的IO,但是这段程序在AVR上可能起不了啥作用),对于汇编的查看也挺困难

一般高级语言:C++、java、C#等

(1).是在C语言的语法和基本结构上,扩展开发出来的;

(2).硬件操作支持性较差;运行效率不高

2. C语言是贝尔实验室于70年代初发明的.80年代初,美国国家标准化协会(ANSI)制定了ANSI C标准.
3. 后来各个领域都有各自的扩展:如windows下的vc,Linux下的GNU C等

 注意:C语言是基于平台的,如果只有C语言,那什么也干不了

 

知识详解02:C语言的特点

1.概括的说,C语言同时具有汇编语言和高级语言的双重特性;

双重性是指:效率高,可读性较好

2. 具体地说,C语言的主要特点如下:

(1).语言简洁、紧凑,使用方便、灵活,32个关键字、9种控制语句(控制程序的流向),程序形式自由(一件事情可以用多种方式来实现(如:循环)).
(2).运算符丰富(方便程序的设计),34种运算符.
(3).数据类型丰富,数据类型有:整形、实型、字符型、数组、指针、结构体、共用体等.
(4).具有结构化的控制语句,如(if..else、while、switch等)是完全模块化和结构化的语言
(5).模块化:将处理复杂的系统分解成更好理解的可管理的模块的方式
(6).结构化:将一个复杂的求解过程分阶进行,使得每一块更容易理解
(7).允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作.
(8).生成的目标代码质量高,执行效率高,只比汇编程序生成的目标代码效率低10%-20%.
(9).可移植性好、基本上不做修改就能用于各种型号的计算机和各种操作系统.

(10).与linux的结合性好(Ios, windows, UNIX的核心用C语言实现)Linux、UNIX本身就是用C语言来编写的.在Linux上用C语言开发的运行效率非常高,尤其在嵌入式领域 C语言更是开发的首选

知识详解02:关键字

1. C的关键字共有32个

数据类型关键字(12个)

char, short, int, long, float, double, unsigned, signed, struct, union, void, enum

unsigned, signed:是修饰符,int a=125;默认是 signed

void:不可用来定义变量,但可以用它来修饰各种变量

控制语句关键字(12个)

if,else,for,do,while,break,case,continue,default,goto(尽量别使用),return,switch

存储类关键字(4个)(重点介绍,因为上面的几个知识点会在后面介绍)

auto, extern, register, static
extern:可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,可以外部使用

register:修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度。

register变量必须是能被CPU所接受的类型。这通常意味着register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。不过,有些机器的寄存器也能存放浮点数。
因为register变量可能不存放在内存中,所以不能用“&”来获取register变量的地址

static:

静态变量都在全局数据区分配内存

静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的;

其他关键字(4个)

const,sizeof,typedef,volatile

volatile:

  确保本条指令不会因编译器的优化而省略,且要求每次直接读值.简单地说就是防止编译器对代码进行优化.比如如下程序:

  num=0x55;

  num =0x56;

  num =0x57;

  num =0x58;

    对外部硬件而言,上述四条语句分别表示不同的操作,会产生四种不同的动作,但是编译器就不能像对待纯粹的程序那样对上述四条语句进行优化,只认为 num=0x58(即忽略前三条语句,只产生一条机器代码)。如果键入volatile,则编译器会逐一的进行编译并产生相应的机器代码(四条)

 

 

知识详解03:语句

1.  C语言利用函数体中的可执行语句,向计算机系统发出操作指令;按照语句功能或构成的不同,可将C语言的语句分为5类:

2. 控制语句(9条,可以细分为三种)

选择结构控制语句

if()~else~,switch()~

循环结构控制语句  

for()~,while()~, do~while(),break, continue

其他控制语句

return, goto

goto 

return功能:

 终止执行函数,赋值(可选)

将控制权返回给调用函数的下一条语句

那函数的返回值是存在哪儿的?

对于四字节的返回值,一般编译器把它放入eax寄存器里,而大于4字节的返回值,一般是放在会在栈中返回地址前的位置。可以肯定的是,应该不是在堆里。

例如:

3. 函数调用语句

函数调用语句由一次函数调用加一个分号构成.

例如:

printf(“hello world!”);

scanf(“%d”,&i);

4. 表达式语句

表达式语句是由表达式后加一个分号构成,

例如:

“num = 5”是表达式,

“num = 5;”是赋值语;

5. 空语句 

空语句由一个分号构成;空语句什么操作也不执行.

6. 复合语句

复合语句由大括号括起来的一组语句构成.

main( )

{

{  }  //复合语句,注意大括号后不需要分;

 }

复合语句一般与其它语句配合使用:

如for( ; ; )  {  }

 

知识详解04:总体结构

 

1. 在C语言中,除实现顺序、选择和循环三种基本结构等9条控制语句外,输入输出操作都由标准库函数(不是C语言的组成部分)来实现.
2. 一个完整的C语言程序,是由一个、且只能有一个main()函数(又称主函数)和若干个其他函数结合而成,或仅由一个main()函数构成.
3. 所有函数既可以放置在同一个源文件里,也可以放置在不同的源文件里

知识详解05:C文件结构

 

1. 一个基于C的软件系统一般由以下文件构成:

 

 

若干个C文件:每个C文件中包含若干个函数.

若干个头文件:每个头文件中包含一些数据结构的定义以及C函数、变量的原型声明.

若干个库文件:库文件是编译后的二进制文件,一般由若干C文件编译后组成,其中包含了若干个函数的可执行代码;这些库文件中的函数可执行代码在连接的时候合并到最终的可执行文件中.

若干个make文件:make文件描述了多个文件中的依赖关系以及生成最终可执行文件或库文件所需要的信息

 

 

知识详解06:数据类型

1. 数据类型

 

 

 

2. 常量与变量

 

常量:在程序运行过程中,其值不能被改变的量(注意:不能反过来说)

 

整型    100,125,-100, 

实型    3.14 , 0.125,-3.789

字符型 ‘a’,‘b’,‘2’

字符串 “a”,“ab”,“1232”

变量:其值可以改变,变量名只能由字母、数字、下划线组成,第一个字必须为字母或下划线;变量在编译时为其分配相应的内存地址.

变量其实就是用来放置数值等内容的“盒子”

 

3. 整型数据

 

整型常量的表示方法:十进制;八进制以数字0开头,如0123;十六进制以0x开头,如0x1e

 整型变量分为

 

有/无符号基本整型     (un/signed) int

有/无符号短整型         (un/signed) short(int)

有/无符号长整型         (un/signed) long (int)

c99中的整数常量:在c99中,以LL或ll(两个字母大小写要一致)结尾的整数常量是long long int

注意:我们在学校学习的TC环境中,int为两个字节,因为TC实际上是在PC机上模拟了一个16位的环境,在VC、Linux等32位环境下都是4个字节;可以使用sizeof(类型|变量)运算符求得

 

4. 实型数据

 

 实型常量

 

实型也称为浮点型,实型常量也称为实数或者浮点数 

十进制形式:由数字和小数点组成:0.0、0.12、5.0

指数形式:123e3代表123*10的三次方

实型变量

单精度(float)和双精度(double)

float型:  占4字节,7位有效数字(十进制)

Double型: 占8字节,15~16位有效数字 (十进制)

包含小数点却不以f结尾的常量是double

小数点以f结尾

 

5. 字符数据

 

字符常量:用单引号括起来,如:‘a’、‘b’等.

 

转义字符:以反斜杠“\”开头,后跟一个或几个字符、如‘\n’ ‘\t’等,分别代表换行,横向跳格.

 

请在字符串字面量中小心使用八进制数和十六进制数的转义序列。八进制数的转义序列在3个数字之后结束,或者在第一个非八进制数字符处结束。例如字符串“\1234”包含两个字符(\123和4),而字符串“\189”包含3个字符(\1、8和9)。而十六进制数的转义序列则不限制为3个数字,而是直到第一个非十六进制数字符截止。

 

实例1:

 

 

实例2:

 

 

实例3:

 

 

大多数编译器会报以上错误,因为十六进制数的转义序列通常范围限制在\x0~\xff

 

字符变量:

 

用char定义的变量只能存放一个字符常量;

每个字符变量被分配一个字节的内存空间;字符值以ASCII码的形式存放在变量的内存单元中

注意:

a = 'x';

a变量中存放的是字符'x'的ASCII :120

即a=120跟a='x'在本质上是一致的

 

6. 字符串常量

 

是由双引号括起来的字符序列,如“CHINA”、“C program”,“$12.5”等都是合法的字符串常量

 

7. 字符串常量与字符常量的不同

 

 

例子1:

例子2:

上例说明a,b是等价的,谁与谁等价就去看他们内存中的值是否相等。

 

8. 符号常量

 

在C语言中,可以用一个标识符来表示一个常量,称之为符号常量,一般形式为:

 #define 标识符 常量

其中#define是一条预处理命令,称为宏定义命令,其功能是把该标识符定义为其后的常量值.

例:各数据类型的运算:(路径:\学生版\01_C语言基础\00_基础代码\1_0

 

9. C99中的布尔型

 

bool flag;//定义一个bool型变量,需要包含头文件#include <stdbool.h>

10. 数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题.转换的方法有两种

自动转换:

遵循一定的规则,由编译系统自动完成.

强制类型转换:

把表达式的运算结果强制转换成所需的数据类型

不管那样转换,它都会尽量保证数据不被丢失

 

11. 自动转换的原则

 

转换方向:

说明

 

横向箭头,表示必须的转换(有问题);char,short必须转换成int型

 数据类型转换的规律:占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低

上题:signed ---> unsigned 

 

12. 强制转换:通过类型转换运算来实现

 

(类型说明符) (表达式)

其功能:把表达式的运算结果强制转换成类型说明符所表示的类型,例如:

 

(float)a; // 把a的值转换为实型

(int)(x+y); // 把x+y的结果值转换为整型

注意:

类型说明符和表达式都必须加括号;

无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据定义的类型

例子1-类型不改变:

例子2-数值 不改变 :

 

 

知识详解07:运算符与表达式

1. 数据在运算中使用的运算符包括:

 

 

运算符的种类、优先级和结合性

 

2. 运算符的种类

 

C语言中运算符和表达式数量之多,在高级语言中是少见的.正是由于丰富的运算符和表达式使C语言功能十分完善

 

3. C语言常用运算符

 

算术运算符 (+、-、*、/、%)

关系运算符 (>、<、==、>=、<=、!= )

逻辑运算符 (!、&&、||)

位运算符   (<<、>>、&、|、 ~ 、∧ )

赋值运算符 (=、及其扩展赋值运算符)

条件运算符 (?:)

逗号运算符  (,)

指针运算符 (*和&)

求字节数运算符(sizeof( ))

强制类型转换运算符((类型))

分量运算符(.->)

下标运算符([])

其他( 如函数调用运算符())

例子:

等号大于逗号 的优先级。

 

4. 用算术运算符将运算对象(也称操作数)连接起来的、符合C语法规则的式子,称为C算术表达式.运算对象包括常量、变量、函数等(函数指的是函数的返回值)

 

例如: a*b/c-1.5+'a′

 

5. 复合的赋值运算符

 

在赋值符“=”之前加上其它二目运算符可构成复合赋值符:+=,-=,*=,%=,<<=,>>=,&=,^=

 

a += 5 //等价于 a = a+5; 

x *= y+7 //等价于x = x*(y+7)

6. 自增、自减运算符

作用是使变量的值增1或减1 

++i,--i(先加/减,后使用)

i++,i-- (先使用,后加/减)

例如1

例子2:

例子3:


7. 在判断同优先级运算符计算顺序时,要注意结合性,详细的优先级及结合性请参考以下表格
8. 优先级

 

 

 

知识详解08:C语言程序结构

1. C语言支持最基本的三种程序运行结构

 

顺序结构、选择结构、循环结构

2. 顺序结构:程序按顺序执行,不发生跳转.
3. 选择结构:依据是否满足条件,执行相应功能.

if(表达式)语句;

 

if(表达式)语句1  else 语句2;

 

if(表达式1)语句1;

else if(表达式2)语句2;

else 语句n

 

注意:if......else if..........else if.....else,这只能响应一个条件

举例

例子1:判断一个数能否被2整除。(练习if)

例子2:分别判断一个数被2取余的余数。(练习if{ }else{ })

例子3: 分别判断一个数被3取余的余数。(练习if{ }else if{ }else if{ })

4. 条件运算符

(a>b)?a:b;

说明:条件为真,表达式取值a,否则取值b

条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋值符;因max=(a>b)?a:b;可以去掉括号而写为 max=a>b?a:b;

? 和 :是一对运算符,不能分开单独使用.

条件运算符的结合方向是自右至左.

简洁、但容易出错,一般不推荐使用

表达式不能是浮点数、字符串。

5. 循环结构

goto语句(尽量少使用).

while语句 先判断表达式后执行.

do-while语句 先执行语句后判断表达式.

for( ; ; ){ }

C99中的for语句

在for语句的第一个表达式可以用来定义变量,该变量只能在循环体内使用

gcc编译

解决这个错误只需要在编译的时候加上-std=c99

6. break语句和continue语句的区别

break语句用于跳出本层循环.

continue用于结束本次循环