@yy0518
2016-04-07T12:55:02.000000Z
字数 2943
阅读 1314
C语言学习笔记
switch语句是多重选择语句,用法诸如:
switch(number){case 1:statement1;break;case 2:statement2;break;……default:stament;}
switch后的圆括号中的表达式被求值,值的类型应为整数值(包括char类型),case后的值应为整型常量(包含char型)或者整数常量表达式(只包含整数常量的表达式),判断与哪个分支的值相同,便开始从哪条语句开始执行,如果语句后没有break,则一直往下执行剩下的语句。然后如果语句后有break,则执行到break之后就退出switch语句,执行switch之后的语句。所以在写程序的时候一定要根据具体需求,选择是否加break。statement可选。
特别提醒:break语句可用于循环和switch中,但continue只能用于循环。不过当switch位于一个循环中时,在switch中使用continue对switch并没有什么用,但能对循环产生效果,也就是跳过本次循环的剩余部分,直接进入下一次的循环。
貌似以前只在汇编里见过这样的指令。而且在C语言中不是很常用,而且说是最好不用。不过,goto相比break和continue的优点在于能够跳出多重嵌套循环,如goto help;在出现故障的时候挺好用的。
被“您可能还想知道是否存在更好的方法来终止输入”给吸引了,所以还有什么更好的方法呢?
(1)缓冲区(buffer)
首先,对于输入来说,有两种输入方式:有缓冲输入和非缓冲(直接)输入。两者的区别在于,有缓冲输时,键入的字符首先先被收集并存储在缓冲区中,然后等待缓冲区内容对程序可用(比如按下回车键),缓冲区的内容成块地传输给程序。而非缓冲输入则是将键入的字符立即传递给程序,不经过缓冲区。
相比之下,缓冲区存在的好处在于:将键入的字符成块地传输比单个地一个个传输所耗费的时间少;有缓冲输入时,在按下回车之前,所键入的内容还可以修改。
缓冲也分为两种:完全缓冲(fully buffered)和行缓冲(line-buffered)。
完全缓冲:缓冲区满了传输。(文件输入)缓冲区的大小取决于系统,常见的一般是512字节和4096字节。
行缓冲:遇到换行字符传输。(键盘输入)
(2)流
C对待输入和输出设备与其对待存储设备上普通文件相同。C程序处理这些输入输出以及文件读写,实际上都是都是对流进行操作。
流是一个理想化的数据流,实际的输入输出映射到这个数据流上。采用流的好处在于,将具有不同属性的多种输入输出统一用流来表示,能够减小系统差异所带来的麻烦,C用户只需要通过使用标准的IO包,对流进行处理,从而实现多种类型的输入输出操作。
如键盘的输入由一个被称为stdin的流表示,屏幕或其它显示设备上的输出由一个被称为stdout流表示。而标准IO中的scanf()、printf()等就能实现对这两个流的操作。
(3)文件的结尾及如何停止输入
在对文件进行处理时,计算机系统需要判断每个文件的起始和结束位置。判断文件结尾一般有两种方法:一种是根据文件的大小来判断文件结尾,如果已经读取了文件大小的内容,则表示到达了文件尾。一种是在文件中放置一个特殊的字符来标志结尾(如Ctrl+Z).
这两种方法,对于C语言来说其实都是,让getchar()函数和scanf()函数在到达文件结尾时,返回值为EOF。这个EOF的返回值通常定义为-1(因为它不与任何一个字符对应),这个实在stdio.h的头文件中已经定义过了,包含头文件后我们可以直接使用,也不用管它具体的值是多少。
对于char()函数,下面的写法可以用Ctrl+Z正常结束输入.
while ((ch = getchar()!=EOF))putchar(ch);
对于scanf()函数,下面的写法却不能用Ctrl+Z结束输入.
while (scanf_s("%c",&ch)!=EOF)putchar(ch);
但下面的这个却又可以用Ctrl+Z结束输入,不明白这其中的差别在哪里.
while (scanf_s("%c",&ch))putchar(ch);
为了简化上次的程序,首先介绍两个大小写转换的函数
(1)tolower()
函数功能:若字符为大写字母,则返回对应的小写字母;如果字符为小写字母,则返回原值。
函数原型: int tolower(int c);
(2)toupper()
函数功能:与上类似,若是小写字母,则返回对应的大写字母;若是大写字母,则返回原值。
函数原型:extern int toupper(int c);
这两个函数在使用时,都必须包含ctype.h的头文件。
采用二维数组的方式的程序如下:
#include "stdio.h"#include"ctype.h"#include"string.h"int main(){char ch[100][100], c_f;int i = 0, j = 1, k;int d_f1, d_f2, d_f;while ((ch[i][j] = getchar()) != '#'){if (ch[i][j] == '.') { ch[i][0] = j + 1; i++; j = 1; }else j++;}/*for (i -= 1;i >= 0;i--)for (j = 1;j < ch[i][0];j++)putchar(ch[i][j]);for (k = 0;k < 100;k++){if (ch[i][j] = getchar()!=EOF){if (ch[i][j] == '.') { i++; j = 0; }else j++;}else break;}*/for (i -= 1;i >= 0;i--){ch[i][1] = tolower(ch[i][1]);d_f2 = ch[i][0] - 1;for (j = ch[i][0]-1;j > 0;j--){if ((ch[i][j] == ' ') || (ch[i][j] == ',')){c_f = ch[i][j];d_f1 = j;d_f = d_f1;for (d_f1 += 1;d_f1 < d_f2;d_f1++)putchar(ch[i][d_f1]);putchar(c_f);d_f2 = d_f;}else if (j == 1){d_f1 = j;for (;d_f1 < d_f2;d_f1++)printf("%c", ch[i][d_f1]);}else continue;}printf(".");}return 0;}
程序分析:
将所输入的段落存储在二维数组中,每一行存一个句子。然后每一行的第一位即ch[i][0]存这个句子的长度。前面说过可以用strlen的函数计算字符数组的长度,但是因为对数组初始化的方式不一样,strlen(ch[i])出来的结果并不是存入的字符的个数,所以不能采用这种方式。而对于以单词为单位的倒序输出的方法,本质上跟上一次差不多。
缺陷:对于有换行符的字符段,不能很好地倒序输出。但是发现上一个程序也是这样的,只是之前木有发现。
问题:
1 被注释掉的那部分的输入方法不知道为什么不可行,为什么在输入结束之后就没有后续的输出了呢??
2 为什么有换行符输入的时候,倒序输出时却没有出现换行符?