1. 语句与程序块
Ø 表达式语句由表达式加上分号“;”组成,在C语言中,分号是语句结束符。
Ø 用一对花括号”{”与”}”把一组声明和语句括在一起就构成了一个复合语句(程序块)
复合语句在语法上等价于单条语句
2. if-else/else-if语句
Ø if-else语句的else部分是可选的,每个else与最近的前一个没有else配对的if进行匹配
if (n >= 0)
for (i = 0; i < n; i++)
if (s[i] > 0)
{
printf (“...”);
return i;
}
else /*错误 */
printf(“error – n is negative\n”);
程序的缩进结构明确的表明了设计的意图,但编译器无法获得这一信息,它会将else部分与内层的if配对。
Ø 如果匹配不符合我们的设计意图,则必须使用花括号强制实现正确的匹配关系
Ø 通过折半查找函数说明三路判定程序的用法。该函数用于判定已排序的数组v中是否存在某个特定的值x。数组v的元素必须以升序排列。如果v中包含x,则该函数返回x在v中的位置(介于0~n-1之间的一个整数);否则该函数返回-1
/*折半查找binsearch函数:在v[0]<=v[1]<=v[2]...<=v[n-1]中查找x */
int binsearch (int x, int v[], int n)
{
int low, high, mid;
high = n – 1;
while (low <= high)
{
mid = (low + high) / 2;
if (x < v[mid])
high = mid – 1;
else if (x > v[mid])
low = mid + 1;
else /* 找到匹配的值 */
return mid;
}
return -1; /* 没有匹配的值 */
}
3. switch语句
Ø switch语句是一种多路判定语句,它测试表达式是否与一些常量整数值中的某一个值匹配,并执行相应的分支动作。
switch (表达式)
{
case 常量表达式: 语句序列
case常量表达式: 语句序列
default: 语句序列
}
每一个分支都由一个或多个整数值常量或常量表达式标记
/*统计数字、空白符及其他字符 */
#include <stdio.h>
main()
{
int c, i, nwhite, nother, ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; i++)
ndigit[i] = 0;
while ((c = getchar()) != EOF)
{
switch (c)
{
case ‘0’: case ‘1’: case ‘2’: case ‘3’: case ‘4’:
case ‘5’: case ‘6’: case ‘7’: case ‘8’: case ‘9’:
ndigit[c – ‘0’]++;
break;
case ‘ ’:
case ‘\n’:
case ‘\t’:
nwhite++;
break;
default:
nother++;
break;
}
}
}
Ø 在switch语句中,case的作用只是一个标号,因此,某个分支中的代码执行完后,程序将进入下一分支继续执行,除非在程序中显式的跳转。跳出switch语句最常用的方法是使用break语句与return语句
为防止直接进入下一个分支执行,每个分支后必须以一个break语句结束
4. while循环与for循环
Ø while循环语句
while (表达式)
语句
Ø 首先求表达式的值,如果其值为真(非0),则执行语句,并再次求该表达式的值。这一循环过程一直进行下去,直到该表达式的值为假(0)为止,随后继续执行语句后面的部分
Ø for循环语句
for (表达式1;表达式2;表达式3)
语句
它等价于下列while语句(while或for中包含continue语句,两者不一定等价):
表达式1;
while (表达式2)
{
语句
表达式3;
}
表达式1与表达式3是赋值表达式或函数调用,表达式2是关系表达式。
for(; ;)
{
...
}
是一个无限循环语句
Ø Shell排序算法
先比较距离远的元素,而不是像简单交换排序算法那样先比较相邻的元素。这样可 以快速减少大量的无序情况,从而减轻后续的工作。被比较的元素之间的距离逐步 减少,直到减少为1,这时排序变成了相邻元素的互换
/* shellsort函数:按递增顺序对v[0]... v[n-1]进行排序*/
void shellsort(int v[], int n)
{
int gap, i, j, temp;
for (gap = n/2; gap > 0; gap /= 2)
for (i = gap; i < n; i++)
for (j = i – gap; j >= 0 && v[j] > v[j+gap]; j -= gap)
{
temp = v[j];
v[j] = v[j+gap];
v[j+gap] = temp;
}
}
#include <ctype.h>
int atoi(char s[])
{
int i, n, sign;
for (i = 0; isspace(s[i]); i++) //跳过空白符
;
sign = (s[i] == ‘-’) ? -1 : 1;
if (s[i] == ‘+’ || s[i] == ‘-’) //跳过符号
i++;
for (n = 0; isdigit(s[i]); i++)
n = 10 * n + (s[i] – ‘0’);
return sign * n;
}
#include <string.h>
/* reverse函数:倒置字符串s中各个字符的位置 */
void reverse(char s[])
{
int c, i, j;
for (i = 0; j = strlen(s)-1; i<j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
Ø 被逗号分隔的一对表达式将按照从左到右的顺序进行求值,各表达式右边的操作数的类型和值即为其结果的类型和值
5. goto语句与标号
终止程序在某些深度嵌套的结构中的处理过程,例如一次跳出多层循环
for (...)
for (...)
{
...
if (disaster)
goto error;
}
...
error:
处理错误情况
6. do-while循环
Ø do-while循环语句
do
语句
while (表达式);
/* itoa函数:将数字n转换为字符串并保存到s中 */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0)
n = -n;
i = 0;
do {
s[i++] = n % 10 + ‘0’;
}while ((n /= 10) > 0)
if (sign < 0)
s[i++] = ‘-’;
s[i] = ‘\0’;
reveres(s);
}
7. break语句与continue语句
Ø break语句可用于从for、while和do-while等循环中提前退出,从switch语句或最内层循环中立即跳出。
/* trim函数:删除字符串尾部的空格符、制表符与换行符 */
int trim(char s[])
{
int n;
for(n = strlen(s)-1; n >= 0; n--)
if (s[n] != ‘ ’ && s[n] != ‘\t’ && s[n] != ‘\n’)
break;
s[n+1] = ‘\0’;
return n;
}
Ø continue语句用于使for、while或do-while语句开始下一次循环的执行。在while和do-while语句中,continue语句的执行意味着立即执行测试部分;在for循环中,则意味着使控制转移到递增循环变量部分。