1. 简介
1.1 C语言的字符集
字符是组成语言的最基本的元素。C语言字符集由字母,数字,空 格,标点和特殊字符组成。在字符常量,字符串常量和注释中还可以 使用汉字或其它可表示的图形符号。
- 字母 小写字母a~z共26个,大写字母A~Z共26个
- 数字 0~9共10个
- 空白符 空格符、制表符、换行符等统称为空白符。 空白符只在字符常量和字符串常量中起作用。在其它地方出现时, 只起间隔作用, 编译程序对它们忽略。因此在程序中使用空白符与 否,对程序的编译不发生影响,但在程序中适当的地方使用空白符 将增加程序的清晰性和可读性。
- 标点和特殊字符
1.2 C语言词汇
在C语言中使用的词汇分为六类: 标识符, 关键字, 运算符, 分 隔符 , 常量, 注释符。
- 标识符
在程序中使用的变量名、函数名、标号等统称为标识符。除库函数 的函数名由系统定义外,其余都由用户自定义。C 规定,标识符只 能是字母(A~Z,a~z)、数字(0~9)、下划线()组成的字符串,并 且其第一个字符必须是字母或下划线。
- 关键字
关键字是由C语言规定的具有特定意义的字符串,通常也称为保留 字。用户定义的标识符不应与关键字相同。C语言的关键字分为以 下几类:
- 类型说明符
用于定义、说明变量、函数或其它数据结构的类型。如 int,double等
- 语句定义符
用于表示一个语句的功能。如if else就是条件语句的语句定义 符。
- 预处理命令
用于表示一个预处理命令。如include。
- 类型说明符
- 运算符
C语言中含有相当丰富的运算符。运算符与变量,函数一起组成表 达式,表示各种运算功能。运算符由一个或多个字符组成。
- 分割符
在C语言中采用的分隔符有逗号和空格两种。逗号主要用在类型说 明和函数参数表中,分隔各个变量。空格多用于语句各单词之间, 作间隔符。在关键字,标识符之间必须要有一个以上的空格符作间 隔, 否则将会出现语法错误,例如把int a;写成 inta;C编译器会 把inta当成一个标识符处理,其结果必然出错。
- 常量
C 语言中使用的常量可分为数字常量、字符常量、字符串常量、符 号常量、转义字符等多种。
- 注释符
C 语言的注释符是以“/*”开头并以“*/”结尾的串。在“/*”和“*/”之 间的即为注释。程序编译时,不对注释作任何处理。注释可出现在 程序中的任何位置。注释用来向用户提示或解释程序的意义。在调 试程序中对暂不使用的语句也可用注释符括起来,使翻译跳过不作 处理,待调试结束后再去掉注释符。
2. 数据类型
2.1 分类
C语言程序中使用的各种变量都应预先加以说明,即先说明,后使用。 对变量的说明可以包括三个方面:
- 数据类型
- 存储类型
- 作用域
本节只说明数据类型,所谓数据类型是按被说明量的性质,表示形 式,占据存储空间的多少,构造特点来划分的。在C语言中,数据类 型可分为: 基本数据类型, 构造数据类型, 指针类型, 空类型 四 大类。
- 基本数据类型
基本数据类型最主要的特点是,其值不可以再分解为其它类型。也 就是说,基本数据类型是自我说明的。
- 构造数据类型
是根据已定义的一个或多个数据类型用构造的方法来定义的。也就 是说,一个构造类型的值可以分解成若干个“成员”或“元素”。每个 “成员”都是一个基本数据类型或又是一个构造类型。在C语言中,构 造类型有以下几种:
- 数组类型
- 结构类型
- 联合类型
- 指针类型
指针是一种特殊的,同时又是具有重要作用的数据类型。其值用来 表示某个量在内存储器中的地址。虽然指针变量的取值类似于整型 量,但这是两个类型完全不同的量,因此不能混为一谈。
- 空类型
在调用函数值时,通常应向调用者返回一个函数值。这个返回的函 数值是具有一定的数据类型的,应在函数定义及函数说明中给以说 明。但是,也有一类函数,调用后并不需要向调用者返回函数值, 这种函数可以定义为“空类型”。其类型说明符为void。
2.2 基本数据类型
对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。 在程序执行过程中,其值不发生改变的量称为常量,取值可变的量称 为变量。它们可与数据类型结合起来分类。例如,可分为整型常量、 整型变量、浮点常量、浮点变量、字符常量、字符变量、枚举常量、 枚举变量。在程序中,常量是可以不经说明而直接引用的,而变量则 必须先说明后使用。
2.2.1 整型
整型量包括整型常量、整型变量。整型常量就是整常数。在C语言 中,使用的整常数有八进制、十六进制和十进制三种。
2.2.1.1 整型常量
- 八进制整型常量
八进制整常数必须以0开头,即以0作为八进制数的前缀。数码 取值为0~7。八进制数通常是无符号数。
- 十六进制整型常量
十六进制整常数的前缀为0X或0x。其数码取值为0~9,A~F或 a~f。
- 十进制整型常量
在程序中是根据前缀来区分各种进制数的。因此在书写常数时不要 把前缀弄错造成结果不正确。
2.2.1.2 整型变量
- 基本型 类型说明符为int,在内存中占2个字节,其取值为基本整常数。
- 短整型 类型说明符为short int或short。所占字节和取值范围均与基本型相同。
- 长整型 类型说明符为long int或long ,在内存中占4个字节,其取值为长整常数。
- 无符号型
类型说明符为unsigned。
无符号型又可与上述三种类型匹配而构成:
- 无符号基本型 类型说明符为unsigned int或unsigned。
- 无符号短整型 类型说明符为unsigned short
- 无符号长整型 类型说明符为unsigned long
2.2.2 实型
2.2.2.1 实型常量
实型也称为浮点型。实型常量也称为实数或者浮点数。在C语言 中,实数只采用十进制。它有二种形式: 十进制数形式指数形式
2.2.2.2 实型变量
- 单精度型 float
- 双精度型 double
2.2.3 字符量
2.2.3.1 字符常量
字符常量是用单引号括起来的一个字符。例如'a','b','=','+','?'都 是合法字符常量。在C语言中,字符常量有以下特点:
- 只能用单引号括起来
- 只能是单个字符
- 可以是字符集中任意字符,但数字定义为字符后就不能参与运算。
2.2.3.2 转义字符
2.2.3.3 字符变量
字符变量的取值是字符常量,即单个字符。字符变量的类型说明符是char。
2.2.3.4 字符串常量
字符串常量是由一对双引号括起的字符序列。例如: "CHINA" ,"C program: , "$12.5" 等都是合法的字符串常量。字符串常量和字符 常量是不同的量。它们之间主要有以下区别:
- 字符常量由单引号括起来,字符串常量由双引号括起来。
- 字符常量只能是单个字符,字符串常量则可以含一个或多个字符。
- 可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量 赋予一个字符变量。在C语言中没有相应的字符串变量,但是可以 用一个字符数组来存放一个字符串常量。
- 字符常量占一个字节的内存空间。字符串常量占的内存字节数等于
字符串中字节数加1。增加的一个字节中存放字符"***\0***"(ASCII码为
0)。这是字符串结束的标志。例如,字符串 "=C program="在内存中
所占的字节为:
C program\0。
2.2.3.4 符号常量
在C语言中,可以用一个标识符来表示一个常量,称之为符号常量。 符号常量在使用之前必须先定义,其一般形式为:
#define 标识符 常量
其中 #define 也是一条预处理命令(预处理命令都以 "#" 开头), 称为宏定义命令,其功能是把该标识符定义为其后的常量值。一经定 义,以后在程序中所有出现该标识符的地方均代之以该常量值。习惯 上符号常量的标识符用大写字母,变量标识符用小写字母,以示区别。
#include <stdio.h> #define HELLO "C编程 --- 测试 #define" int main () { printf ("%s \n",HELLO); return 0; }
编译并运行:
root@dev3-168:/data/lab/c# gcc -Wall 宏操作.c -o 宏操作 root@dev3-168:/data/lab/c# ./宏操作 C编程 --- 测试 #define
2.2.3 变量类型和转换
变量的数据类型是可以转换的。转换的方法有两种, 一种是自动转 换,一种是强制转换。
2.2.3.1 自动转换
2.2.3.2 强制转换
强制类型转换是通过类型转换运算来实现的。其一般形式为:
(类型说明符) (表达式)
其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。 例如: (float) a 把a转换为实型(int)(x+y) 把x+y的结果转换为整 型在使用强制转换时应注意以下问题:
- 类型说明符和表达式都必须加括号(单个变量可以不加括号),如把 (int)(x+y)写成(int)x+y则成了把x转换成int型之后再与y相加了。
- 无论是强制转换或是自动转换,都只是为了本次运算的需要而对变 量的数据长度进行的临时性转换,而不改变数据说明时对该变量定 义的类型。
3. 基本运算符和表达式
3.1 运算符的种类、优先级和结合性
3.1.1 C语言运算符的分类
3.1.1.1 算数运算符 (7个)
加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(--)
3.1.1.2 关系运算符 (6个)
大于(>)、小于(<)、等于(==)、 大于等于(>=)、小于等于(<=) 不等于(!=)
3.1.1.3 逻辑运算符 (3个)
与(&&)、或(||)、非(!)
3.1.1.4 位操作符 (6个)
位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)
3.1.1.5 赋值运算符 (3类11个)
简单赋值(=) 复合算术赋值(+=,-=,*=,/=,%=) 复合位运算赋值(&=,|=,^=,>>=,<<=)
3.1.1.6 条件运算符 (唯一的1个3目操作符)
?:
3.1.1.7 逗号运算符 (1个)
,
3.1.1.8 指针运算符 (1个)
*
3.1.1.9 求字节数运算符(1个)
sizeof
3.1.1.10 特殊运算符
括号(),下标[],成员(→,.) 等
3.1.2 优先级和结合性
C语言中,运算符的运算优先级共分为15级。1级最高,15级最低。在 表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算 量两侧的运算符优先级相同时, 则按运算符的结合性所规定的结合方 向处理。C语言中各运算符的结合性分为两种,即左结合性(自左至 右)和右结合性(自右至左)。
数据类型和运算符小结
1. C的数据类型
基本类型,构造类型,指针类型,空类型
2. 基本类型的分类及特点
类型说明符 字节 数值范围 字符型char 1 C字符集 基本整型int 2 -32768~32767 短整型short int 2 -32768~32767 长整型 long int 4 -214783648~214783647 无符号型 unsigned 2 0~65535 无符号长整型 unsigned long 4 0~4294967295 单精度实型 float 4 3/4E-38~3/4E+38 双精度实型 double 8 1/7E-308~1/7E+308
3. 常量后缀
L或l 长整型 U或u 无符号数 F或f 浮点数
4. 常量类型
整数,长整数,无符号数,浮点数,字符,字符串,符号常数,转义字符。
5. 数据类型转换
- 自动转换
在不同类型数据的混合运算中,由系统自动实现转换, 由少字节类 型向多字节类型转换。 不同类型的量相互赋值时也由系统自动进行 转换,把赋值号右边的类型转换为左边的类型。
- 强制转换
由强制转换运算符完成转换。
6. 运算符优先级和结合性
一般而言,单目运算符优先级较高,赋值运算符优先级低。 算术运算 符优先级较高,关系和逻辑运算符优先级较低。 多数运算符具有左结 合性,单目运算符、三目运算符、 赋值
7. 表达式
表达式是由运算符连接常量、变量、函数所组成的式子。 每个表达式 都有一个值和类型。 表达式求值按运算符的优先级和结合性所规定的 顺序进行。
C语言语句概叙
C语句可分为五类:
- 表达式语句
- 函数调用语句
- 控制语句
- 复合语句
- 空语句
表达式语句
表达式语句由表达式加上分号“;”组成。 执行表达式语句就是计算表 达式的值。其一般形式为:
表达式;
函数调用语句
函数名 ( 实际参数表 );
控制语句
控制语句用于控制程序的流程, 以实现程序的各种结构方式。它们由 特定的语句定义符组成。C语言有九种控制语句。 可分成以下三类:
条件判断语句
if 语句 , switch 语句
循环执行语句
do while 语句 , while 语句 , for 语句
转向语句
break 语句 , goto 语句 , continue 语句 , return 语句
复合语句
把多个语句用括号 {} 括起来组成的一个语句称复合语句。 在程序中 应把复合语句看成是单条语句,而不是多条语句,复合语句内的各条 语句都必须以分号
“;”结尾,在括号“}”外不能加分号。
空语句
只有分号“;”组成的语句称为空语句。 空语句是什么也不执行的语句。 在程序中空语句可用来作空循环体。例如
while(getchar()!='\n');
本语句的功能是,只要从键盘输入的字符不是回车则重新输入。这里 的循环体为空语句。
C语言常用语句详述
赋值语句
赋值语句是由赋值表达式再加上分号构成的表达式语句。其一般形式 为: 变量=表达式; 。赋值语句的功能和特点都与赋值表达式相同。 它 是程序中使用最多的语句之一。 在赋值语句的使用中需要注意以下几 点:
- 由于在赋值符 = 右边的表达式也可以是一个赋值表达式,因此,下 述形式 变量=(变量=表达式); 是成立的,从而形成嵌套的情形。
- 注意在变量说明中给变量赋初值和赋值语句的区别。给变量赋初值 是变量说明的一部分,赋初值后的变量与其后的其它同类变量之间 仍必须用逗号间隔,而赋值语句则必须用分号结尾。
- 在变量说明中,不允许连续给多个变量赋初值。 如下面是错误的声 明: int a=b=c=5; 必须写为 int a=5,b=5,c=5; 而赋值语句允许 连续赋值
- 注意赋值表达式和赋值语句的区别。赋值表达式是一种表达式,它 可以出现在任何允许表达式出现的地方,而赋值语句则不能。下述 语句是合法的 : if((x=y+5)>0)z=x; 语句的功能是,若表达式 x=y+5大于0则z=x。下述语句是非法的: if((x=y+5;)>0) z=x; 因 为=y+5;是语句,不能出现在表达式中。
数据输出语句
在C语言中,所有的数据输入/输出都是由库函数完成的。 因此都是 函数语句。
printf() 函数
printf() 函数是一个标准库函数,它的函数原型在头文件 stdio.h 中。但作为一个特例,不要求在使用
printf()函数之前必须包含stdio.h文件。printf()函数调用的一般形式为 :
printf("格式控制字符串",输出表列);
其中 格式控制字符串 用于指定输出格式。格式控制串可由 格式字符 串 和 非格式字符串 两种组成。格式字符串是以 % 开头的字符串, 在%后面跟有各种格式字符,以说明输出数据的类型、形式、长度、小 数位数等。如
%d表示按十进制整型输出,%ld表示按十进制长整型 输出,%c表示按字符型输出等。非格式字符串在输出时原样照印, 在显示中起提示作用。 输出表列中给出了各个输出项, 要求格式字 符串和各输出项在数量和类型上应该一一对应。
格式字符串的一般形式:
[标志][输出最小宽度][.精度][长度]类型
- 类型
- 类型字符用以表示输出数据的类型,其格式符和意义下表所示:
表示输出类型的格式字符 格式字符意义 d 以十进制形式输出带符号整数(正数不输出符号) o 以八进制形式输出无符号整数(不输出前缀O) x 以十六进制形式输出无符号整数(不输出前缀OX) u 以十进制形式输出无符号整数 f 以小数形式输出单、双精度实数 e 以指数形式输出单、双精度实数 g 以%f%e中较短的输出宽度输出单、双精度实数 c 输出单个字符 s 输出字符串
- 标志
- 标志字符为 - 、 + 、 # 、 空格 四种,其意义下表所示:
标志格式字符 标 志 意 义 - 结果左对齐,右边填空格 + 输出符号(正号或负号)空格输出值为正时冠以空格,为负时冠以负号 # 对c,s,d,u类无影响;对o类, 在输出时加前缀o 对x类,在输出时加前缀0x;对e,g,f 类当结果有小数时才给出小数点
- 输出最小宽度
- 用十进制整数来表示输出的最少位数。 若实际位数 多于定义的宽度,则按实际位数输出, 若实际位数少于定义的宽度 则补以空格或0。
- 精度
- 精度格式符以 "." 开头,后跟十进制整数。本项的意义是: 如果输出数字,则表示小数的位数;如果输出的是字符, 则表示输 出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。
- 长度
- 长度格式符为h,l两种,h表示按短整型量输出,l表示按长整型量输出。
putchar() 函数
putchar() 函数是字符输出函数, 其功能是在显示器上输出单个字符。 其一般形式为 :
putchar(字符变量)
数据输入语句
scanf() 函数
scanf() 函数是一个标准库函数,它的函数原型在头文件 stdio.h 中, 与printf函数相同,C语言也允许在使用scanf函数之前不必包含 stdio.h文件。scanf函数的一般形式为:
scanf("格式控制字符串",地址表列);
其中, 格式控制字符串 的作用与printf函数相同, 但不能显示非格 式字符串 , 也就是不能显示提示字符串。地址表列中给出各变量的 地址。地址是由地址运算符 & 后跟变量名组成的。例如,&a,&b分别 表示变量a和变量b 的地址。这个地址就是编译系统在内存中给a,b变 量分配的地址。在C语言中,使用了地址这个概念,这是与其它语言 不同的。应该把变量的值和变量的地址这两个不同的概念区别开来。 变量的地址是C编译系统分配的,用户不必关心具体的地址是多少。在 赋值表达式中给变量赋值,如: a=567 在赋值号左边是变量名,不能 写地址,而scanf函数在本质上也是给变量赋值,但要求写变量的地 址,如&a。这两者在形式上是不同的。 & 是一个取地址运算符, &a 是一个表达式,其功能是求变量的地址。
格式字符串的一般形式为:
%[*][输入数据宽度][长度]类型
- 类型
- 表示输入数据的类型,其格式符和意义下表所示 :
格式 字符意义 d 输入十进制整数 o 输入八进制整数 x 输入十六进制整数 u 输入无符号十进制整数 f或e 输入实型数(用小数形式或指数形式) c 输入单个字符 s 输入字符串
- * 符号
- 用以表示该输入项读入后不赋予相应的变量,即跳过该输入值。 如
scanf("%d %*d %d",&a,&b);
当输入为:1 2 3 时,把1赋予a,2被跳过,3赋予b。
- 宽度
- 用十进制整数指定输入的宽度(即字符数)
- 长度
- 长度格式符为l和h,l表示输入长整型数据(如%ld) 和双精度 浮点数(如%lf)。h表示输入短整型数据。
使用 scanf() 函数注意:
- scanf函数中没有精度控制,如: scanf("%5.2f",&a); 是非法的。 不能企图用此语句输入小数为2位的实数。
- scanf中要求给出变量地址,如给出变量名则会出错。如 **scanf("%d",a);**是非法的,应改为 scnaf("%d",&a); 才是合法的。
- 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数 据之间的间隔则可用空格,TAB或回车作间隔。C编译在碰到空 格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时 即认为该数据结束。
- 在输入字符数据时,若格式控制串中无非格式字符,则认为所有输 入的字符均为有效字符。
键盘输入函数
getchar() 函数
getchar函数的功能是从键盘上输入一个字符。
#include <stdio.h> int main () { char c; printf ("输入一个字符:"); c = getchar(); putchar(c); return 0; }
使用 getchar() 函数注意:
- getchar() 函数只能接受单个字符,输入数字也按字符处理。输入 多于一个字符时,只接收第一个字符。
- 使用本函数前必须包含文件 stdio.h
示例
1.输出各种数据类型的字节长度
#include <stdio.h> int main () { char CHAR; int INT; short SHORT; long LONG; float FLOAT; double DOUBLE; printf ("本计算机上C语言的各种类型数据占用字节数如下:\n"); printf ("%-10s 占用 %2d字节\n","char",sizeof(CHAR)); printf ("%-10s 占用 %2d字节\n","int",sizeof(INT)); printf ("%-10s 占用 %2d字节\n","short",sizeof(SHORT)); printf ("%-10s 占用 %2d字节\n","long",sizeof(LONG)); printf ("%-10s 占用 %2d字节\n","float",sizeof(FLOAT)); printf ("%-10s 占用 %2d字节\n","double",sizeof(DOUBLE)); return 0; }
编译并运行 :
root@dev3-168:/data/lab/c# gcc -Wall 输出各种数据类型的字节长度.c -o 输出各种数据类型的字节长度 root@dev3-168:/data/lab/c# ./输出各种数据类型的字节长度 本计算机上C语言的各种类型数据占用字节数如下: char 占用 1字节 int 占用 4字节 short 占用 2字节 long 占用 4字节 float 占用 4字节 double 占用 8字节
分支结构程序
关系运算符和表达式
关系运算符
比较两个量的运算符称为关系运算符。 在C语言中有以下关系运算符:
< 小于 <= 小于或等于 > 大于 >= 大于或等于 == 等于 != 不等于
关系运算符都是双目运算符,其结合性均为左结合。 关系运算符的优 先级低于算术运算符,高于赋值运算符。 在六个关系运算符 中,<,<=,>,>=的优先级相同,高于==和!=,==和!=的优先级相同。
关系表达式
关系表达式的一般形式为: 表达式 关系运算符 表达式 例如: a+b>c-d, x>3/2,'a'+1<c,-i-5*j==k+1;都是合法的关系表达式。由于 表达式也可以又是关系表达式。 因此也允许出现嵌套的情况,例 如:a>(b>c),a!=(c==d)等。关系表达式的值是“真”和“假”,用“1”和 “0”表示。
逻辑运算符和表达式
逻辑运算符
C语言中提供了三种逻辑运算符:
&& 与运算 || 或运算 ! 非运算
与运算符 && 和或运算符 || 均为双目运算符。具有左结合性。 非运 算符 ! 为单目运算符,具有右结合性。按照运算符的优先顺序可以得出:
a>b && c>d 等价于 (a>b) && (c>d) !b==c||d<a 等价于 ((!b)==c)||(d<a) a+b>c && x+y<b 等价于 ((a+b)>c) && ((x+y)<b)
逻辑运算的值也为“真”和“假”两种,用“1”和“0 ”来表示。
if语句
用if语句可以构成分支结构。它根据给定的条件进行判断, 以决定执 行某个分支程序段。C语言的if语句有三种基本形式。
第一种: if (表达式) 语句 ; 第二种: if(表达式) 语句1; else 语句2; 第三种: if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; … else if(表达式m) 语句m; else 语句n;
#include <stdio.h> #include <stdlib.h> /*程序首先询问用户:他们来自中国还是说英语的国家, *然后根据用户的选择判断使用什么欢迎语言*/ int main () { char xuan_ze; printf ("您来自哪里(Where are your come from)?\n"); printf ("1. 中国(china) 2.英语国家(english)\n"); /*使用getchar()函数得到用户输入的第一个字符*/ xuan_ze=getchar(); printf ("你的选择是(your choice is) : %c\n",xuan_ze); /*判断用户输入的字符: * '1' --- 输出中文欢迎语 * '2' --- 输出english欢迎语 * '其他字符' -- 输出出错信息*/ if (xuan_ze=='1') printf ("欢迎!\n"); else if (xuan_ze=='2') printf ("Welcome !\n"); else printf ("你的选择不对(Your choice is wrong)!\n"); /*程序做错执行到结尾了,返回一个0值,通常这都代表顺利!*/ return 0; }
if 语句中需要注意:
- 在三种形式的if语句中,在if关键字之后均为表达式。 该表达式通 常是逻辑表达式或关系表达式,但也可以是其它表达式,如赋值表 达式等,甚至也可以是一个变量。例如: if(a=5) 语句;if(b) 语 句;都是允许的。只要表达式的值为非0,即为“真”。如在 if(a=5)…;中表达式的值永远为非0,所以其后的语句总是要执行 的,当然这种情况在程序中不一定会出现,但在语法上是合法的。
- 在if语句中,条件判断表达式必须用括号括起来, 在语句之后必须 加分号。
- 在if语句的三种形式中,所有的语句应为单个语句,如果要想在满 足条件时执行一组(多个)语句,则必须把这一组语句用{} 括起来组 成一个复合语句。但要注意的是在}之后不能再加分号。
条件运算符和条件表达式
由条件运算符组成条件表达式的一般形式为:
表达式1? 表达式2: 表达式3
使用条件运算符注意:
- 条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋 值符。因此 max=(a>b)?a:b可以去掉括号而写为 max=a>b?a:b
- 条件运算符?和:是一对运算符,不能分开单独使用。
- 条件运算符的结合方向是自右至左。例如: a>b?a:c>d?c:d 应理解 为 a>b?a:(c>d?c:d) 这也就是条件表达式嵌套的情形,即其中的表 达式3又是一个条件表达式。
switch 语句
C语言还提供了另一种用于多分支选择的switch语句, 其一般形式为:
switch(表达式){
case 常量表达式1 : 语句1;
case 常量表达式2 : 语句2;
…
case 常量表达式n : 语句n;
default : 语句n+1;
}
通常一个现实中的有用的switch语句在每一个case执行的语句最后一 行会有一个break语句,用来跳出switch语句,不然程序一直往后执 行,default分支就也执行了。
while 语句
while语句的一般形式为: while (表达式) {语句}; 其中表达式是 循环条件,语句为循环体。while语句的语义是:计算表达式的值,当 值为真(非0)时, 执行循环体语句。例如下列计算字符串长度:
#include <stdio.h> int main () { int n=0; printf ("输入一段字符串,我能计算它的长度:\n"); while (getchar() != '\n') n++; printf ("你输入的字符串长度是:%d\n",n); return 0; }
do-while 语句
先执行语句,在判断条件。一般形式如下:
do {
语句;
}while(表达式);
for 语句
for语句是C语言所提供的功能更强,使用更广泛的一种循环语句。其一般形式为:
for(表达式1; 表达式2; 表达式3) {
语句;
}
- 表达式1 通常用来给循环变量赋初值,一般是赋值表达式。也允许 在for语句外给循环变量赋初值,此时可以省略该表达式。
- 表达式2 通常是循环条件,一般为关系表达式或逻辑表达式。
- 表达式3 通常可用来修改循环变量的值,一般是赋值语句。
这三个表达式都可以是逗号表达式, 即每个表达式都可由多个表达式 组成。三个表达式都是任选项,都可以省略。
for语句的语义是:
- 首先计算表达式1的值。
- 再计算表达式2的值,若值为真(非0)则执行循环体一次, 否则跳出循环。
- 然后再计算表达式3的值,转回第2步重复执行。在整个for循环过程
中,表达式1只计算一次,表达式2和表达式3则可能计算多次。循环
体可能多次执行,也可能一次都不执行。
用for来计算那个具名的”1+2+3+...+100"吧!
#include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i,n; double sum=0; if (argc>2 || argc==1){ printf ("用法:%s 整数\n",argv[0]); return 100; } else n=atoi(argv[1]); for (i=1;i<=n;i++) sum += i; printf ("从 1 加到 %d 的和是:%f\n",n,sum); return 0; }
编译并执行(看看你机器上同样执行需要多长时间^_^):
root@dev3-168:/data/lab/c# gcc -Wall -g -o for语句 for语句.c root@dev3-168:/data/lab/c# time ./for语句 900000000 从 1 加到 900000000 的和是:405000000067108992.000000 real 0m2.737s user 0m2.728s sys 0m0.000s
转义语句(4种)
程序中的语句通常总是按顺序方向, 或按语句功能所定义的方向执行的。 如果需要改变程序的正常流向, 可以使用本小节介绍的转移语句。在C 语言中提供了4种转移语句: goto,break, continue和return。
小结
1. 从程序执行的流程来看, 程序可分为三种最基本的结构: 顺序结 构,分支结构以及循环结构
2. 程序中执行部分最基本的单位是语句。C语言的语句可分为五类:
- 表达式语句
- 任何表达式末尾加上分号即可构成表达式语句, 常用 的表达式语句为赋值语句。
- 函数调用语句
- 由函数调用加上分号即组成函数调用语句。
- 控制语句
- 用于控制程序流程,由专门的语句定义符及所需的表达 式组成。主要有条件判断执行语句,循环执行语句,转向语句等。
- 复合语句
- 由{}把多个语句括起来组成一个语句。 复合语句被认为 是单条语句,它可出现在所有允许出现语句的地方,如循环体等。
- 空语句
- 仅由分号组成,无实际功能。
3. C语言中没有提供专门的输入输出语句, 所有的输入输出都是由调 用标准库函数中的输入输出函数来实现的。
- scanf和getchar函数是输入函数,接收来自键盘的输入数据。
- scanf是格式输入函数, 可按指定的格式输入任意类型数据。
- getchar函数是字符输入函数, 只能接收单个字符。
- printf和putchar函数是输出函数,向显示器屏幕输出数据。
- printf是格式输出函数,可按指定的格式显示任意类型的数据。
- putchar是字符显示函数,只能显示单个字符。
4.关系表达式和逻辑表达式是两种重要的表达式, 主要用于条件执行的 判断和循环执行的判断。
5.C语言提供了多种形式的条件语句以构成分支结构。
- (1)if语句主要用于单向选择。
- (2)if-else语句主要用于双向选择。
- (3)if-else-if语和switch语句用于多向选择。
这几种形式的条件语句一般来说是可以互相替代的。
6.C语言提供了三种循环语句。
- (1)for语句主要用于给定循环变量初值, 步长增量以及循环次数的循环结构。
- (2)循环次数及控制条件要在循环过程中才能确定的循环可用 while 或do-while语句。
- (3)三种循环语句可以相互嵌套组成多重循环。循环之间可以并列但不能交叉。
- (4)可用转移语句把流程转出循环体外,但不能从外面转向循环体内。
- (5)在循环程序中应避免出现死循环,即应保证循环变量的值在运行 过程中可以得到修改,并使循环条件逐步变为假,从而结束循环。
7.C语言语句小结
名 称 一 般 形 式
简单语句 表达式语句表达式;
空语句;
复合语句 { 语句 }
条件语句 if(表达式)语句;
if(表达式)语句1; else语句2;
if(表达式1)语句1; else if(表达式2) 语句2…else语句 n;
开关语句 switch(表达式){ case常量表达式: 语句…default: 语句; }
循环语句 while语句
while(表达式)语句;
for语句 for(表达式1; 表达式2; 表达式3)语句;
break语句 break;
goto语句 goto;
continue语句 continue;
return 语句 return(表达式);
数组
在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形 式组织起来。这些按序排列的同类数据元素的集合称为数组。在C语言 中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些 数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不 同,数组又可分为数值数组、字符数组、指针数组、结构数组等。
数组一般声明形式:
类型说明符 数组名 [常量表达式],……;
注意:
- 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所 有元素的数据类型都是相同的。
- 数组名的书写规则应符合标识符的书写规定。
- 数组名不能与其它变量名相同
- 不能在方括号中用变量来表示元素的个数, 但是可以是符号常数或 常量表达式。
数组元素的表示方法
数组名[下标]
其中的下标只能为整型常量或整型表达式。如为小数时,C编译将自动取 整。数组元素通常也称为下标变量。必须先定义数组, 才能使用下标变 量。在C语言中只能逐个地使用下标变量, 而不能一次引用整个数组。
二维数组
C语言允许构造多维数组。多维数组元素有多个下标, 以标识它在数组 中的位置,所以也称为多下标变量。二维数组类型说明二维数组类型说 明的一般形式是:
类型说明符 数组名[常量表达式1][常量表达式2]…;
二维数组在概念上是二维的,即是说其下标在两个方向上变化, 下标变 量在数组中的位置也处于一个平面之中,而不是象一维数组只是一个向 量。但是,实际的硬件存储器却是连续编址的, 也就是说存储器单元是 按一维线性排列的。如何在一维存储器中存放二维数组,可有两种方 式:一种是按行排列, 即放完一行之后顺次放入第二行。另一种是按列 排列,即放完一列之后再顺次放入第二列。在C语言中,二维数组是按 行排列的。
字符数组
C语言允许用字符串的方式对数组作初始化赋值。例如:
static char c[]={'c', ' ','p','r','o','g','r','a','m'}; 可写为:
static char c[]={"C program"}; 或去掉{}写为:
sratic char c[]="C program";
字符串常用函数
C语言提供了丰富的字符串处理函数, 大致可分为字符串的输入、输出、 合并、修改、比较、转换、复制、搜索几类。使用这些函数可大大减轻 编程的负担。用于输入输出的字符串函数, 在使用前应包含头文件 "stdio.h" ;使用其它字符串函数则应包含头文件"string.h"。
puts() 把字符数组中的字符串输出到显示器
gets() 从标准输入设备键盘上输入一个字符串
strcat()
strcat (字符数组名1,字符数组名2);
把字符数组2中的字符串连接到字符数组1 中字符串的后面,并删去字 符串1后的串标志“\0”。本函数返回值是字符数组1的首地址。
strcpy()
strcpy (字符数组名1,字符数组名2);
把字符数组2中的字符串拷贝到字符数组1中。串结束标志“\0”也一同 拷贝。字符数名2, 也可以是一个字符串常量。这时相当于把一个字 符串赋予一个字符数组。
strcmp()
strcmp(字符数组名1,字符数组名2);
按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回比较 结果。
字符串1=字符串2,返回值=0; 字符串2〉字符串2,返回值〉0; 字符串1〈字符串2,返回值〈0。
