内容比较多。
大家可以复制做一个文档,然后用得时候直接搜索就好了,非常方便,不用网络也可以使用。
第二周的学习总结
1.对C语言的介绍与初步认识
C语言的产生与发展
FORTRAN(1957年)
ALGOL 60(1960年) 传统C或K&R C(1978)
CPL(1963年) ANSI C(1989,美国国家标准)
BCPL(1967年) 标准 C(ISO/IEC 9899:1990,俗称C90)
B(1969年-1970年) 最新标准 C(ISO/IEC 9899:1999俗称C99)
C(1971年-1973年)
1.2 C语言的语言特征
- 语言简洁紧凑
- 目标代码质量高
- 语言表达能力强
- 流程控制结构化
- 弱类型
- “中级语言”特性
- 书写自由、使用灵活
- 可移植性好
1.3 计算机硬件系统
- 一台计算机硬件系统由CPU、内存、外存、其他I/O设备和总线组成。
- CPU又称为中央处理器。 CPU又是由运算器、控制器、指令计数器、内部寄存器、标志寄存器等部件组成。
- 内存又称为内存储器,用以存放程序和数据。
- 总线是用以连接计算机各个部件的线路,它完成各个部件之间的信息传送。根据传送信号种类
- 的不同,总线又分成地址总线、数据总线和控制总线。
- 内存以字节为单位线性连续编址。即按照0x0000,0x0001,0x0002,…的方式;从低地址端开始向高地址端为每一个内存字节进行顺序连续编号。
- 1024个字节称为1K字节,1024K字节称为1M字节,1024M字节称为1G字节。1024G字节称为1T字节。
- CPU数据总线的宽度(bit数)称为计算机的机器字长。对8位CPU,机器字长为1字节;对16位CPU,机器字长为2字节;对32位CPU,机器字长为4字节。
- 外存指计算机的外存储器。常用的硬盘、软盘、U盘、光盘、以及磁盘阵列都属于外存。外存存储的信息在断电之后仍然能够保存,这是外存的第一个特点。
- 其他I/O设备 :键盘 ,显示器 ,打印机 ,绘图仪
1.3.1 二进制
- 二进制数是由0和1组成的数字串。对于一个二进制数来讲,它具有两个下面基本特点:
- (1) 只有0和1两个不同的数字符号。
- (2) 逢2进位1。
1.3.2 八进制(O或o)
- 八进制数是由0到7组成的数字串。八进制数具有如下两个基本特点:
- (1) 只有0,1,2,3,4,5,6,7八个不同的数字符号。
- (2) 逢8进位1。
- 在C语言中,通过加前导零的方式来表示一个数是八进制数。如:0136表示的是八进制数(136)8。
1.3.3 十六进制(Ox或ox)
- 将4位二进制数组合成为十六进制数。与二进制、八进制数类似,十六进制数也有两个基本特点:
- (1)只有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F十六个不同的数字符号(A∼F也可以采用小写英文字母a∼f)。这十六个数字符号与二进制、八进制、十进制数之间的关系如表1.2所示。
- (2)逢16进位1。
- 在C语言中,通过加前导0x或前导0X的方式来表示一个数是十六进制数。如:0x2d5b表示的是十六进制数(2d5b)16。0XABCD也是合法的十六进制数。
1.4.1 机器数与真值
- 机器数: 在计算机中,将一个数的最高位定义为符号位,其余各位为数值位。并且规定符号位之值为0表示正,符号位之值为1表示负。用这种方法表示的数称为机器数。
- 真值: 机器数的数值称为该机器数的真值。也就是正、负号后跟二进制数的绝对值就构成真值。
1.4.2 原码
定义: 对于一个二进制数X,如果规定用最高位为符号位,其余各位为该数的绝对值。并且规定符号位之值为0表示正,符号位之值为1表示负,则采用这种方式形成的二进制编码称为称为该二进制数X的原码。
值得注意的是,根据定义,真值0的原码表示不惟一,有+0和-0之分。
[+0]原=00000000 (8位)
[-0]原=10000000 (8位)
1.4.3 补码
定义:正数的补码等于正数的原码,负数的补码为其原码除符号位不动,其余各位变反再加1所得。
例1.13 分别求十进制数35和-1在8位机和16位机中的补码表示。
解 设x1=35,x2=-1;
在8位机中,∵x1>0,∴[x1] 补=[x1] 原 =00100011;
∵x2<0,∴[x2]原 =10000001,
[x2] 补 =11111110+1=11111111;
在例1.13中,如果令x1和x2都为零,则容易算出它们的补码都是零。也就是说,对于真值0,其补码是惟一的。即:
[+0]补=[-0]补=000…000
最右边式子中0的个数等于机器的字长数。
1.4.4 反码
定义:在计算机中,有时还会用到数的反码。对正数而言,其反码与原码、补码的表示相同;对负数而言,反码符号位的定义与原码、补码相同,但需要将对应原码的数值位按位变反。
例1.15 分别求十进制数6和-1在8位机中的反码表示。
解 [6]反=00000110;[-1]反=对10000001的数值位按位变反=11111110
2.数据类型、运算符和表达式
C程序是一个字符序列,字符序列先被分解为称之为记号(token)的词法元素,再根据语法规则检查这些记号组合是否合法。
C语言是一门大小写敏感的,抢类型的语言,随便写一个数它都是有类型固定的。
词法元素(记号)分析举例:
例2.1 sum=x+y
分解成sum、=、x、+和y 共5个记号。
例2.2 int a,b=10 ;
分解成int、a、,、b、=、10和 ; 共7个记号
例2.3 x+++++y
分解成x、++、++、+、y 共5个记号
(一个数值是不可以自增的!)
语法图是另一种表示文法的常见方式,对应于每个非终结符有一个子图,图中每条路径对应于该非终结符的一个生成式,路径上的是生成式右端的终结符和非终结符。终结符用弧形框表示,非终结符用矩形框表示。
通俗的说,椭圆形:定义的关键字,方括号:我们编写的
分隔符统称为空白字符(包括空格符、制表符、换行符、换页符及注释符),在语法上仅起分隔单词的作用。
当程序中两个相邻的单词之间如果不用分隔符就不能区分开时则必须加分隔符(通常用空格符)。
例如,int x,y;不能写成 intx,y;
能写成 int x , y ;
char的存储长度是一字节 。
多数系统中char与signed char同(-128~127). unsigned char (0~255).
字符数据以ASCII码存储在内存中 。
在不要求大整数的情况下,可用字符型代替整型 。
int型值存储在一个机器字中 .
int(负2的31次方~2的31次方-1),2B指2个字节长,B = bye(字节)
假设字长为2B,int取值范围为-32768~32767,unsigned取值范围为0 ~ 65535
指数区称为阶码;
阶码的+-分别用来表示正数与小数。
尾数所占的位数决定值的精度,指数所占的位数决定值的范围。
float占4字节,其中符号1b,指数8b,尾数23b,其精度大约为7位,范围约10-38~10+38。
double占8字节,其中符号1b,指数11b,尾数52b,其精度大约为15位,范围约为10-308~10+308。
很多编译器将long double处理为double,在某些系统中,它占用10或12B。很少被使用。
浮点数的表示可能只是近似的。其值与表示法之间的差称为“可表示误差”。
计算也可能造成可表示误差。不能使用==和!=运算符比较浮点数据。
可以用两个数值之差同一个预定的小正数epsilon比较的方法解决这个问题。
如: x==0 可以用 abs(x-0)<0.000001表示 下溢时,有些系统指数域全为0,尾数域非0,有些系统简单地用0表示。
上溢后,用称为“无穷大”的特殊位模式表示,即指数域全为1,尾数域0。有些系统中将输出+Infinity或-Infinity。
整型常量
有三种表示方法(通过前缀字符区分):
十进制:无前缀
八进制:前缀为0
十六进制:前缀为0x或0X时。
例如,31可写成037,也可写成0x1f或0X1F
整型常量可以带有后缀,用以指定其类型:
字母u或U表示unsigned
字母l或L表示long
字母ul或UL
表示unsigned long
字母ll或LL表示long long (C99)
字母ull或ULL表示unsigned long long (C99)
无后缀时,表示int
当常量值超出指定类型的范围时,其实际类型取决于数值大小、前缀等,确定类型的规则很复杂,在标准化前的C语言、C89和C99中各不相同
转义序列
有些以\开头的特殊字符称为转义序列
转义序列有两种形式,一种是“字符转义序列”,即反斜线后面跟一个图形符号,用于表示字符集中的非图形符号和一些特殊的图形字符。
\n 换行 \t 水平制表符
\\ 反斜杠 \‘ 单引号
\“ 双引号 \0 空字符
\? 问号
\t 打印八个字节,用于对齐和补齐。
100%打印时应该再加一个%为100%%
写成用一对双引号括住0至多个字符的形式。
"string\n" /* 包含7个字符的字符串 */
"" /* 包含0个字符的空字符串*/
字符串中的单引号可以用图形符号表示,但双引号和反斜线必须用转义序列表示。例如:
"3'40\"" /* 表示5个字符的字符串:3'40" */
“c:\tc” /* 表示4个字符的字符串 */
“c:\\tc” /* 表示5个字符的字符串 */
如何将一个较长的字符串写成多行?有两种方法:
(1)行连接:在前一行的末尾输入续行符(\) 再换行。
"Hello,\
how are you " /* 换行后应紧靠行首 */
(2)字符串连接:将字符串分段,分段后的每个字符串用双引号括起来。
"Hello, "
"how are you" /* 换行后不必紧靠行首*/
‘a’与 “a”有何区别 ?
‘a’ : 字符常量,占1 B内存空间
“a” : 字符串常量,占2B内存空间
“a”存储时,系统自动在后面补上\0( 空字符,ASC11值为0,作为字符串结束标志)
字符串的存储长度比字符串的实际长度大1
“a”2个字符
“a\n”3个字符
字符串长度比实际长度小于1
strlen查看字符串长度
用一个标识符表示一个常量.
C语言中有三种定义符号常量的方法:
(1) 用#define指令(预处理指令,宏命令)
(2) 用const声明语句
(3) 用枚举类型
const是关键字,称为类型限定符。格式为:
const 类型名 标识符=常量;
例如:
const double PI=3.14159;
const int DOWN=0x5000;/* 下光标键的扫描码 */
const int YES=1,NO=0;
const声明的标识符是一个只读变量,编译时系统会根据定义的类型为该标识符分配存储单元,并把对应的常量值放入其中,该值不能再被更改,此后,程序中每次出现该标识符都是对所代表存储单元的访问。
#define定义的标识符没有对应的存储单元,只是在编译之前由预处理程序进行简单的文本替换。
变量代表内存中具有特定属性的一个存储单元,它用来存放数据,这就是变量的值,在程序运行期间,这些值是可以改变的。
要求对所有用到的变量作定义,也就是“先定义,后使用” 。
形式: 类型名 变量表;
如: int total,average;
变量在声明时可以同时赋一个初值(称为变量的显示初始化),每个变量必须分别显示初始化。
如:int count=0,sum=0;
char alert=‘\a’, c ;
int count=0,sum=0;(不能 int count=sum=0;)
3.流程控制
语句,表达式语句,复合语句。
复合语句在程序设计中主要有以下两种用途:
1)用于语法上只允许出现单个语句而处理上需要执行多个语句的地方,例如作为if语句的子句及循环语句的循环体。
(2)用于改变嵌套if-else语句的配对规则。
此外,当需要说明临时使用的局部变量时,也可使用复合语句。
if语句有两种形式:
(1) if格式:if (表达式)语句1;
(2) if-else格式:if (表达式)语句1;else语句2;
嵌套的if 语句
当if子句或else子句中又包含if 语句时,则形成嵌套的if语句。例如,可以用下面的一个嵌套的if语句求a,b,c三个数中最大值:
if ( a > b )
if ( a > c ) max = a;
else max = c;
else
if ( b > c ) max = b;
else max = c;
嵌套if 语句中else的配对规则
对嵌套if语句中else与if的配对必须制定一个规则,否则会造成理解上的二义性。例如:
if ( n > 0 )
if ( a > b ) z = a;
else z = b;
编译程序约定:else与其前面最靠近的还未配对的if配对,即内层优先配对原则。
switch语句的一般形式为:
switch(表达式){
case 常量表达式1:语句序列1;
case 常量表达式2:语句序列2;
…
case 常量表达式n:语句序列n;
default:语句序列n+1;
}
switch语句的使用要点
第一要注意列出的case应能包括选择表达式所有的取值情况,如果不能全部包括,则应使用default子句处理余下的情况。
第二应特别注意break在switch中的作用,如果希望执行完某一case下的语句之后便跳出switch语句,则必须使用break或return转移语句。break跳出switch语句之后继续执行switch语句后面的一个语句(如果有),return语句则立即结束函数并返回到调用处(如果是主函数,则结束程序)。
例如:下面是一个不含转移语句的switch语句,注意观察该语句执行时的输出。
i = 1;
switch ( i ){
case 0:printf("%d\t", i);
case 1:printf("%d\t", i++);
case 2:printf("%d\t", i++);
case 3:printf("%d", i++);
default:printf("\n");
}
printf("%d\n", i);
输出:1 23
4
while语句的一般形式为:
while (表达式) 语句
while语句流程图:
for语句的形式
for语句的一般语法形式表示为:
for语句流程图:
for(e1;e2;e3) s
等价于:
e1;
while(e2) {
s;
e3;
}
使用for语句时须注意表达式e1,e2,e3的用法:
(1)三个表达式可以全部或部分缺省,但无论缺省e1,e2或e3,它们之间的分号不能省。
(2)缺省e1和e3时的for语句形如for(;e2;)s,等价于一个形如while (e2) s的while语句。
(3)缺省e2时的for语句for(e1 ; ; e3) s和三个表达式都缺省的for语句for(; ;)s都是无限循环语句。被省略的e2缺省值恒为非0(e1和e3没有缺省值)。
for循环语句示例:
int i;
for(i = 1; i < 4; i++)
printf(”i=%d s=%d\n”, i, 2 * i);
几种等价的形式:
i = 1;
for(; i < 4; i++)
printf(”i=%d s=%d\n”, i, 2 * i);
或
for( i = 1; i < 4;){
printf(”i=%d s=%d\n”, i, 2 * i);
i++;
}
或
i = 1;
for(; i < 4;){
printf(”i=%d s=%d\n”, i, 2 * i);
i++;
}
或
i = 1;
for(; ;){
printf(”i=%d s=%d\n”, i, 2 * i);
i++;
if (!(i < 4)) break;
}
do-while语句的一般形式为:
do 语句 while (表达式);
do-while语句流程图:
可以用以下等价的while循环语句来代替。
语句
while (表达式)
{
语句
}
三种循环语句的区别及使用要点归纳如下(s是循环体;e,e1,e2,e3是表达式):
(1)while(e)s和for(e1;e2;e3)s先测试e或e2,后执行s,若第一次测试时e或e2结果为0,则s一次也不执行;do s while(e);先执行s,后测试e,所以s总是至少被执行一次。使用时应根据具体情况选用,一般说来,必定要执行的循环可以用三种循环语句中任何一种;可能不被执行的循环则不能用do-while。
(2)第一次测试循环条件(e或e2)之前,循环变量必须赋初值,初值只赋一次;在循环体(s)或e3(对于for语句)中必须有能够改变循环变量值的语句或表达式。写循环条件时,应注意避免无限循环、永不执行的循环或执行次数不正确的循环等情况。
(3)for语句控制部分的e1可以包含给循环变量赋初值以及其他与循环有关的运算,即在循环开始之前仅执行一次的运算;e2不要求一定是关系表达式或逻辑表达式,只要能正确控制循环体的执行(非0值执行循环体,0值结束循环),任何表达式都可以;e3是每次执行循环体后紧接着要执行的表达式,通常用于改变循环变量的值,如i++之类,e3也可以包括某些属于循环体部分的内容,也可将e3放到循环体最后。可见,for语句使用非常灵活,其控制部分的三个表达式可以容纳除循环变量赋初值、测试循环条件和修改循环变量值的运算以外的其他与循环有关的运算。
(4)任何循环语句当循环体含有一个以上语句时,必须写成复合语句(用{ }括起来);当循环体为空语句时不要掉了分号(;)。
goto语句又称为无条件转移语句,它的一般形式为:
goto 标号;
任何可执行C语句都可以加标号前缀成为标号语句。
标号语句的形式为:
标号:语句
goto语句中的标号是对标号的引用,标号语句中的标号是对标号的定义。
被goto语句引用的标号必须有且仅有一个对应的标号语句,对应的标号语句称为称为该goto语句的
目标语句;而允许标号语句没有对应的goto语句。
概而言之,有标号的引用必须有惟一的标号定义,而有标号的定义不必有标号的引用。
goto语句的目标语句允许出现的范围称为标号的作用域。
C语言中标号的作用域是goto语句所在的函数,即goto语句不能从一个函数转移到另一个函数中,但可以在一个函数内从嵌套结构的内层直接转到最外层。
使用标号语句时,要注意同一函数内的标号不能同名。
goto语句和标号语句在函数中出现的先后位置没有约束,即对标号的定义和对标号的引用没有先后次序的规定。
注意:goto语句不是必需的语言成分。因为用goto语句实现的任何控制转移,都可以通过循环语句、if语句和其他转移语句的适当配合以及用整型变量标记状态的方法实现。
goto语句的惟一好处是可以从嵌套结构的最内层(switch语句或循环语句)直接转到最外层(隔层转移),用起来较方便.
但如果随意地使用goto语句则会破坏程序的结构化特性,使程序的逻辑结构不清,