最近为了准备新学期的课程设计,我打算重新系统地复习一下C语言。我所看的教材是由美国Brian W.Kernighan和Dennnis M.Ritchie编写,徐宝文和李志翻译的《C程序设计语言》。确切地说,几乎不会有我自己创造的内容,而我写博文的目的是将每一章所学的内容进行总结和复习,当然其中也会有我自己在学习中的一些感悟和疑惑。希望自己可以坚持写下去,也同时希望对浏览我的文章的同行有所帮助,并对我提一些建议。
一、利用公式 C=(5/9)(F-32)打印华氏温度与摄氏温度对照表。
#include <stdio.h>
//当fahr=0,20,……,300时,分别打印华氏温度与摄氏温度的对照表
int main() //尽管C语言默认main函数返回int,但在visual studio 2013里int不能省略
{ //原因是C++不支持默认int,而这里只是利用了<stdio.h>头文件,但编译器依然认为这是C++程序
int fahr, celsius;
int lower, upper, step;
lower = 0; //温度表下限
upper = 300; //温度表上限
step = 20; //步长
fahr = lower;
while (fahr <= upper){
celsius = 5 * (fahr - 32) / 9; //这里没有使用5/9的原因是整数除法操作将执行舍位,结果中的任何
//小数部分都会被舍弃,所以相除结果为0,故所有摄氏温度结果都会为0
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
return 0;
}
\n表示换行符,\t表示制表符,\b表示回退符,\"表示双引号,\\表示反斜杠本身,另外在练习1-2中提到\c,实验结果是直接输出c。
为了输出美观,在printf语句的%d中指明打印宽度,则打印的数字会在打印区域内右对齐,例如:
printf("%3d %6d\n",fahr,celsius);
为了实现对应温度的精确,采用浮点数版本,就之前的代码改动仅三句,如下:
float fahr,celsius;
celsius = (5.0/9.0)*(fahr-32.0);
printf("%3.0f %6.1f\n",fahr,celsius); //%3.0表示待打印浮点数至少3个字符宽,%6.1表示至少6个字符宽,且有一位小数
%o表示八进制数,%x表示十六进制数,%c表示字符,%s表示字符串,%%表示百分号本身。
for语句的使用:
#include <stdio.h>
int main()
{
int fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20)
printf("%3d %6.1f\n", fahr, (5.0 / 9.0)*(fahr - 32.0)); //printf的第三个参数在此表明此处可以使用任何浮点表达式
return 0;
}
符号常量的使用:
#include <stdio.h>
#define LOWER 0
#define UPPER 300
#define STEP 20
//上面LOWER,UPPER,STEP都是符号常量,且注意#define指令行末尾没有分号
int main()
{
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
printf("%3d %6.1f\n", fahr, (5.0 / 9.0)*(fahr - 32.0));
return 0;
}
二、字符输入/输出
1、文件复制:
#include <stdio.h>
int main()
{ //将输入复制到输出------版本1
int c;
c = getchar();
while (c != EOF)
{
putchar(c); //写
c = getchar(); //读
}
return 0;
}
这里之所以不把c声明成char类型,是因为踏必须足够大,除了能存储任何可能的字符外还要能存储文件结束符EOF。
#include <stdio.h>
int main() //将输入复制到输出,版本2
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;
}
将c的赋值操作放在while循环语句的测试部分,使程序更紧凑且易读。另外注意,不等于运算符!=的优先级比赋值运算符=的优先级要高。
c = getchar() != EOF; 等价于 c = (getchar() != EOF); 结果c的值将被置为0或1
2、字符计数
#include <stdio.h>
int main()
{ //统计输入的字符数,版本1
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
return 0;
}//当输入12345后按一下回车,在按Ctrl+z后,计数结果为6,原因为计数计了5个数和一个换行
#include <stdio.h>
int main()
{ //统计输入的字符数,版本2
double nc;
for (nc = 0; getchar() != EOF; ++nc)
; //for语句循环体为空,故用单独分号代替
printf("%.0f\n", nc); //%.0f强制不打印小数点和小数部分,因此小数部分位数为0
return 0;
}
3、行计数
#include <stdio.h>
int main()
{
int c, nl;
nl = 0;
while ((c = getchar())!=EOF)
if (c == '\n') //统计行数等价于统计换行符的个数
++nl;
printf("%d\n", nl);
return 0;
}
单引号中的字符表示一个整数值,该值等于此字符在机器字符集中对应的数值。(可以利用这个特点,实现大小写字母相互转换)
4、单词计数
#include <stdio.h>
#define IN 1 //在单词内
#define OUT 0 //在单词外
//通过两个状态,记录程序当前计数是否位于一个单词中
int main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF)
{
++nc;
if (c == '\n')
++nl;
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT){
state = IN;
++nw;
}
}
printf("%d %d %d \n", nl, nw, nc);
//nl统计行数,nw统计空格、换行及制表符的个数,nc统计所有字符,包括空格及换行等等
return 0;
}