`
xitongyunwei
  • 浏览: 916245 次
文章分类
社区版块
存档分类
最新评论

《C程序设计语言》 第三章 控制流

 
阅读更多

3.1 语句与程序块

在表达式之后加上一个分号(;),它们就变成了语句。
用一对花括号“{”与“}”把一组声明和语句括在一起就构成了程序块,在语法上等价于单条语句。


3.2 if-else语句

每个else与最近的前一个没有else配对的if进行匹配。

if (n > 0)
if (a > b)
z = a;
else
z = b;

程序的缩进结构明确表明了设计意图,但编译器无法获得这一信息,它会将else部分与内层的if配对。


3.3 else-if语句

/* binsearch: find x in v[0] <= v[1] <= ... <= v[n-1] */
int binsearch(int x, int v[], int n)
{
int low, high, mid;
low = 0;
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 /* found match */
return mid;
}
return -1;
}

练习3-1 上面折半查找的例子中,while循环语句内执行了两次测试。重写该函数,
使循环内部只执行一次测试。比较两种版本函数的运行时间。
答:
while (low <= high) {
mid = (low + high) / 2;
if (x < v[mid])
high = mid +1;
else
low = mid + 1;
}
if (x == v[mid])
return mid;
else
return -1;


3.4 switch语句

case的作用只是一个标号,从某个分支中的代码执行完后,程序将进入下一分支继续执行。
跳出switch语句最常用的方法是使用break和return语句。

作为一种良好的程序设计风格,在switch语句最后的default分支后面也加上一个break语句。
这样做在逻辑上没有必要,但当我们需要向该switch语句后添加其他分支时,这样会降低犯
错误的可能性。

练习3-2 编写一个函数escape(s, t),将字符串t复制到字符串s中,并在复制过程中将换行符、
制表符等不可见字符分别转换为\n、\t等相应可见的转义字符。再编写一个相反功能的函数。
答:
#include <stdio.h>
void escape(char s[], char t[])
{
int i, j;
for (i = 0, j = 0; s[i] != '\0'; i++) {
switch (s[i]) {
case '\n':
t[j++] = '\\';
t[j++] = 'n';
break;
case '\t':
t[j++] = '\\';
t[j++] = 't';
break;
default:
t[j++] = s[i];
break;
}
}
t[j] = '\0';
}
void escape2(char s[], char t[])
{
int i, j;
for (i = 0, j = 0; s[i] != '\0'; j++) {
switch (s[i]) {
case '\\':
if (s[i+1] == 'n') {
t[j] = '\n';
i += 2;
}
else if (s[i+1] == 't') {
t[j] = '\t';
i += 2;
}
else {
t[j] = s[i];
i++;
}
default:
t[j] = s[i++];
break;
}
}
}
main()
{
char s[] = "this is cdai";
char t[20];
escape(s, t);
printf("%s\n", t);

char t2[20];
escape2(t, t2);
printf("%s\n", t2);
}


3.5 while循环与for循环

for (表达式1; 表达式2; 表达式3)
语句

等价于=>

表达式1;
while (表达式2) {
语句
表达式3;
}

逗号运算符“,”在for语句中经常用到。被逗号分隔的一对表达式将按照从左到右的顺序进行求值,
分隔函数参数的逗号,分隔声明中变量的逗号等不是逗号运算符,不保证从左至右顺序求值。

/* reverse: reverse string s in place */
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;
}

练习3-3 编写函数expand(s1, s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中
扩展为等价的完整列表abc...xyz。该函数可以处理大小写字母和数字,并可以处理a-b-c、
a-z0-9与-a-z等类似的情况。作为前导和尾随的-字符原样排印。
答:
#include <stdio.h>
void expand(char s1[], char s2[])
{
int i, j, k;
i = j = 0;
while (s1[i] != '\0') {
if (s1[i] == '-' && 0 < i && s1[i+1] != '\0' &&
s1[i-1] != '-' && s1[i+1] != '-') {
j--; // avoid duplicate letter
for (k = s1[i-1]; k <= s1[i+1]; k++, j++)
s2[j] = k;
i += 2;
} else {
s2[j++] = s1[i++];
}
}
s2[j] = '\0';
}
main()
{
char s1[] = "-a-b-hAbC-G0-8---";
char s2[100];
expand(s1, s2);
printf("before expand:%s\nafter expand: %s\n", s1, s2);
}


3.6 do-while循环

/* itoa: convert n to characters in s */
void itoa(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign and make n positive */
n = -n;

i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* convert number to char */
} while ((n /= 10) > 0);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}

这里使用do-while语句会方便一些,因为即使n为0,也至少要把一个字符放到数组s中。
do-while中只有一条语句,(没有必要)但扔用花括号括起来,因为可以避免将while误认为
是另个while循环的开始。

练习3-4 在数的对二的补码表示中,上面的itoa函数不能处理最大的负数-2的(字长-1)次方
的情况。解释其原因,并修改函数使它在任何机器上运行时都能打印出正确的值。
答:
例如char字长为8位,则对二补码范围为-128~127。值为-128的char,n=-n;后值仍为-128。
128的二进制源码为01111111,通过补码的负数转换规则得到10000000,即-128二进制码为80(可用prinf("%hhx);验证)。

修改函数,不将n转为正数,而是将每次取模运算的结果转为正数。从而避开无法将最大负数转为正数的问题。
#include <stdio.h>
#define abs(x) ((x) < 0 ? -(x) : (x))
void itoa(int n, char s[])
{
int i, sign;
sign = n;

i = 0;
do {
s[i++] = abs(n % 10) + '0';
} while ((n /= 10) != 0);

if (sign < 0)
s[i++] = '-';
s[i] = '\0';
//reverse(s);
}
main()
{
char s[20];
itoa(10, s);
printf("%s\n", s);
itoa(-128, s);
printf("%s\n", s);
}

练习3-5 编写函数itob(n, s, b),将整数n转换为以b为底的数,并将转换结果以字符的形式
保存到字符串s中。例如,itob(n, s, 16)把整数n格式化为十六进制整数保存在s中。
答:
#include <stdio.h>
#include "reverse.c"
#define abs(x) (x) < 0 ? -(x) : (x)

void itob(int n, char s[], int b)
{
int i, x, sign;
sign = n;
i = 0;
do {
x = abs(n % b);
if (x >= 10)
s[i++] = (x - 10) + 'A';
else
s[i++] = x + '0';
} while ((n /= b) != 0);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
main()
{
char s[20];
itob(29, s, 2);
printf("%s\n", s);

itob(-257, s, 16);
printf("%s\n", s);
}

练习 3-6 修改itoa函数,使得该函数可以接收三个参数。第三个参数为最小字段宽度。
为了保证转换后结果至少具有第三个参数指定的最小宽度,必要时在结果左边填充一定的空格。
答:
...
if (sign < 0)
s[i++] = '-';
while (i <= w-1) // fill space
s[i++] = ' ';
...


3.7 break和continue语句


3.8 goto语句与标号


分享到:
评论

相关推荐

    C程序设计语言[第2版].pdf

    第3章 控制流 3.1 语句与程序块 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 whil循环与for特环 3.6 do-while循环 3.7 break语句与continue语句 3.8 goto语句与标号 第4章 涵数与程序结构 第5章 指针与...

    C程序设计语言(第2版_新版)习题解答.pdf

    内容简介 本书对Brain W. Kernighan和Dennis M. Ritchie所著的《The C Programming Language》(第2版)的所有...第3章 控制流 第4章 函数与程序结构 第5章 指针与数组 第6章 结构 第7章 输入与输出 第8章 UNIX系统接口

    《C程序设计语言》(非扫描.新版)

    C程序设计语言 第1章 导言 1.1 入门 1.2 变量与算术表态式 1.3 for语句 1.4 符号常量 1.5 字符输入/输出 1.6 数组 1.7 函数 1.8 参数——传值调用 1.9 字符数组 1.10 外部变量与作用域 第2章 类型、运算符与表达式 ...

    C程序设计语言(第2版·新版中文)

    第3章 控制流 3.1 语句与程序块 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 whil循环与for特环 3.6 do-while循环 3.7 break语句与continue语句 3.8 goto语句与标号 第4章 涵数与程序结构 第5章 ...

    C程序设计语言官方题解

    C程序设计语言官方题解。 第一张 导言 第二章 类型、运算符与表达式 第三章 控制流 第四章 函数与程序结构 第五章 指针与数组 第六章 结构 第七章 输入与输出 第八章 UNIX系统接口

    C程序设计语言 cccccccccccccccccccccccccccccccc语言学习资料

    《C程序设计语言》是由C语言的设计者Brian W. Kernighan和Dennis M. Ritchie编写的一部介绍标准C语言及其程序设计方法的权威性经典著作。全面、系统地讲述了C语言的各个特性及程序设计的基本方法,包括基本概念、...

    C程序设计语言 中文版高清新版

    《C程序设计语言》是由C语言的设计者Brian W. Kernighan和Dennis M. Ritchie编写的一部介绍标准C语言及其程序设计方法的权威性经典著作。全面、系统地讲述了C语言的各个特性及程序设计的基本方法,包括基本概念、...

    谭浩强C语言设计第三版.pdf

    第3章 C语言程序的流程控制  3.1 算法  3.1.1 算法的组成要素与基本性质  3.1.2 算法描述工具  3.1.3 自项向下、逐步细化的算法设计过程  3.2 判断  3.2.1 命题的“真”、“假”与C语言中的逻辑值  3.2.2 ...

    C程序设计语言(第2版·新版)

    C程序设计语言(第2版·新版)高清晰非扫描版 目 录 译者序 序 第1版序 前言 第1章 基本概念 1.1 入门 1.2 变量与算术表达式 1.3 for语句 1.4 符号常量 1.5 字符输入输出 1.5.1 文件复制 1.5.2 字符计数 1.5.3...

    C程序设计语言--全书四章

    原来自己看过的一本书《C程序设计语言》,写得挺实用的。 第1章 基本概念 第2章 类型、运算符与表达式 第3章 控制流 第4章 函数与程序结构 第5章 指针与数组 第6章 结构 第7章 输入与输出 第8章 UNIX系统界面 附录A ...

    C程序设计语言第2版新版[PDF]

    第3章 控制流 3.1 语句与程序块 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 whil循环与for特环 3.6 do-while循环 3.7 break语句与continue语句 3.8 goto语句与标号 第4章 涵数与程序结构 第5章 指针与数组...

    C程序设计语言

    第3章 控制流 3.1 语句与程序块 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 whil循环与for特环 3.6 do-while循环 3.7 break语句与continue语句 3.8 goto语句与标号 第4章 涵数与程序结构 第5章 指针与数组...

    C语言精典版本C程序设计语言

    第3章 控制流 3.1 语句与分程序 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 while与for循环语句 3.6 do-while循环语句 3.7 break语句与continue语句 3.8 goto语句与标号 第4章 函数与程序结构 ...

    C程序设计语言_第2版(带书签目录)

    第三章 流控制 3.1 语句与程序块 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 while循环与for循环 3.6 do-while循环 3.7 break语句与continue语句 3.8 goto语句与标号 第四章 函数与程序结构 4.1...

    C程序设计语言 很适合初学者和再学者学习和复习

    第3章 控制流 3.1 语句与分程序 3.2 if-else语句 3.3 else-if语句 3.4 switch语句 3.5 while与for循环语句 3.6 do-while循环语句 3.7 break语句与continue语句 3.8 goto语句与标号 第4章 函数与程序结构 ...

    程序设计语言编译原理 (陈火旺)

    第三章词法分析 3.1 对于词法分析器的要求 3.1.1词法分析器的功能和输出形式 3.1.2词法分析器作为一个独立子程序 3.2词法分析器的设计 3.2.1输入、预处理 3.2.2 单词符号的识别:超前搜索 3.2.3状态转换图 ...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    1.2 当代最优秀的程序设计语言 1.3 C语言版本 1.4 C语言的特点 1.5 面向对象的程序设计语言 1.6 C和C++ 1.7 简单的C程序介绍 1.8 输入和输出函数 1.9 C源程序的结构特点 1.10 书写程序时应遵循的规则 1.11 ...

    C程序设计语言(3)

    第1章 基本概念 第2章 类型、运算符与表达式 第3章 控制流 第4章 函数与程序结构 第5章 指针与数组 第6章 结构 第7章 输入与输出 第8章 UNIX系统界面

Global site tag (gtag.js) - Google Analytics