该文章内容整理自《C程序设计(第四版)》、《高质量C编程指南》、以及网上各大博客
一个函数包含声明部分和执行部分。执行部分由语句组成,经编译后产生机器指令。声明部分不是语句,不产生机器指令。一个C程序的结构如下:
分类
C语句分为以下5类
(1). 控制语句
- 条件语句:if(表达式) … else if(表达式) … else …
- 循环语句:
(1). for(表达式1; 表达式2; 表达式3) …。在C99标准中允许表达式1定义变量并赋予初值。推荐在这里给仅在循环中用到的变量定义,因为这样能缩短变量的作用域
(2). while(表达式) …
(3). do … while(表达式);(注意最后有分号)
多层循环嵌套时,一般长循环放在内层,短循环放在外层 - 跳过本次循环语句:continue
- 结束switch或循环语句:break
- 多分支选择语句:switch。
switch(整型数据(包括枚举型)或字符型数据) {
case 常量1: 语句1; break;
case 常量2: 语句2; break;
case 常量3:
case 常量4: 语句3; break;//此时常量3和常量4都进入到语句3
...
default: 语句n;(没有default时不符合则跳过)
}
//对于if、switch等选择语句,通常把正常情况,也即出现可能性最大的分支放前面,而可能性小的分支放后面
- 函数返回语句:return
- 转向语句:goto。先在程序某处添加标记,如"mark: ",然后使用"goto mark;"跳转
(2). 函数调用语句
如printf(“Hello world.”);
(3). 表达式语句
如赋值表达式a=3;,++i;等
(4). 空语句
直接只有一个分号的一行语句。
(5). 复合语句
用{}将语句和声明括起来的复合语句,也称语句块
常用语句
C程序中最常用的是赋值语句和输入输出语句
赋值语句
复合赋值运算符中,x%=y+3、x%=(y+3)、与x=x%(y+3)三者等价
赋值表达式的一般形式为,变量 赋值运算符 表达式三项。其中,算术表达式、常量、以及赋值表达式不能作为左值
连等式中a=(b=5)与a=b=5等价,也即连等式的运算顺序为从右到左
在赋值过程中将占字节多的数据赋值给占字节少的变量时,直接截取相应数据范围的部分
输入输出语句
(1). printf
一般形式为printf(格式控制,输出表列)
- d格式符。用来输出有符号十进制整数。%5d表示数据占据5列且数据靠右,若想靠左则为%-5d。但%+d则表示输出整数前的正负号。长整型则为%ld,双长整型为%lld。l可放在d、o、x、u前。而在scanf中%5d则表示只读取前5位整数
- c格式符。用来输出一个字符
- s格式符。用来输出一个字符串。%5s在printf中表示只输出前5个字符,在scanf中表示只读取前5个字符
- f格式符。用来输出实数
(1). 基本型用%f。实数部分全部输出,小数部分输出6位
(2). 指定数据宽度和小数位数%m.nf。如果n为0则不会输出小数点。注意其中m是指包含小数点在内的整个浮点数长度而不单单指整数部分 - e格式符。用来输出指数形式实数。同样可以用%m.ne形式声明。也可用写成%E,此时输出指数中为大写E
- i格式符。在 printf 中没有区别,在 scanf 时,%d 只与十进制形式的整数相匹配;而%i 则可以匹配八进制、十进制、十六进制表示的整数。 如输入的数字有前缀 0(018、025),%i会把它当作八进制数来处理,如果有前缀0x (0x54),它将以十六进制来处理
- o格式符。连同符号位一起以八进制整数形式输出
- x格式符。连同符号位一起以十六进制整数形式输出。%X时以大写形式输出
- u格式符。用来输出无符号整数
- g格式符。用来输出浮点数,并由系统自动选择为f格式或e格式输出。%G时以大写形式输出
- p格式符。用来输出地址
(2). scanf
一般形式为scanf(格式控制,地址表列)
其中,l可用于输入长整型数据如ld、lo、lx、lu以及double型数据lf、le。h可用于输入短整型数据如hd、ho、hx
在scanf(“a=%d, b=%d”, &a, &b);中输入则必须为a=1, b=2。若为scanf(“a=%d b=%d”, &a, &b);则a=1与b=2之间必须要有1个以上的空白字符
scanf和printf函数都有返回值,scanf返回正确读入了多少个变量,printf返回输出了包括换行符在内的有多少个字符
(3). sprintf
一般形式为sprintf(目标字符串,格式控制,地址表列)
sprintf函数用于将字符串输出到目标字符串而不是屏幕中,要注意字符串的长度要足够容纳打印的内容,否则会出现内存溢出
(4). sscanf
一般形式为sscanf(源字符串,格式控制,地址表列)
sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。sscanf可用来进行数据类型或进制转换以及按特定规则读取源字符串的特定规则。也即使用正则表达式,但是功能并没有正则表达式强大,并且使用时有较多限制。同理,在scanf以及printf中的格式控制都能使用正则表达式。C语言并不直接支持正则表达式,而需要通过函数库regex.h来完成
几种常见的表达方法:
- %[abc]读取a、b、或c的任意一员,[a-z]表示匹配小写字母,[a-z0-9]表示匹配小写字母及数字
- %[^a-z]读取不在a-z之间的字符串,如果碰到 a-z 之间的字符则停止
- %[^=]读取字符串直到碰到=号
- %*[^=]%s前面带*号表示不保存变量。跳过字符串中以=结尾的子串而读后包括=在内的后面部分子串
另外,可用*匹配变量到格式字符串中,如printf("%*d\n", a, A);即输出a长度宽的整数A,而printf("%.*lf\n", a, A);则输出a位小数的浮点数A
(4). 字符输入输出
- putchar( c )。用于输出字符变量c。若c为整数则当ASCII码处理
- c = getchar()。用于输入一个字符,包括控制字符。注意getchar函数返回的不是char类型而是int类型,此时有可能出现潜在错误。一般用法为while((a = getchar() && a!=EOF) != ‘\n’) { }。EOF是指检测文件尾,在头文件中通过宏定义定义值为-1。键盘输入EOF其实是命令行环境遗留下来的,但是很多系统支持仿真的EOF,如用Ctrl+D(Linux系统)或Ctrl+Z(Windows系统)来模拟输入EOF