1.4-1.5

1.4符号常量

这里书中仍以打印温度表为目标,运用了宏定义来操作

#include<stdio.h>
#define LOWER 0
#define UPPER 300
#define STEP 20
main()
{
  int fahr;
   for(fahr=LOWER;fahr<=UPPER;fahr=fahr+STEP)
     printf(%3d %6.1f\n",fahr,(5.0/9.0)*(fahr-32));
}
//定义的宏是大写字母,赋值不用等号,结尾没有分号
//宏可以当做一个数的载体,当程序复杂时,修改数据,只需要把宏中的值修改,程序中引用的宏的值都会修改

1.5 字符输入/输出

1.5.1文件复制

书中给了这样的一个思路:

读一个字符

while(该字符不是文件结束指示符,也就是EOF)

         输出刚读入的字符

         读下一个字符

好,简单观察这个逻辑,就是用while循环,然后只要不是结束符就能一直打,一直循环工作

这种思想在以后的数组中也会有应用

#include<stdio.h>
//版本一
int main(void) {
	int c;
	c = getchar();
	while (c != EOF) {
		putchar(c);
		c = getchar();

	}
	return 0;
}

这里我没有按照书上那种main()旧格式打,按标准的来。可以看到这是一个基础的getchar,putchar函数的运用。

其中!=就是不等于符号,如果初学者还不熟练,要先着重记住这个,以后还会常见

那么EOF通俗的讲,就是在告诉计算机:你不要停下来,初学者不用深入去理解这个,你只需要知道怎么用,让它在合适的地方起到作用就行。

然后书中给出了一个简练的版本,也是比较常见的:

#include<stdio.h>
int main(void) {
	int c;
	while ((c = getchar()) != EOF)
	putchar(c);
	return 0;
}

如果你在pta上做到一个题,叫统计各类字符数量,你要想到这个哦

这里书中强调:!= 的优先级大于 = 所以在上面的代码中c=getchar() 这个整体要括起来不然就成了

getchar!=EOF先运算,再=c了,那样是不行的

1.5.2字符计数

同样的利用getchar函数,达到统计输入的字符数的目的

先来看书中第一个例子:

#include<stdio.h>
int main(void) {
	long nc;
	nc = 0;
	while (getchar() != EOF)
		++nc;
	printf("%ld\n", nc);

	return 0;
}

 我们来看里面出现的新的东西:
首先long,这个也是一个类型,也就是定义了nc的类型是long的,这个与int是一个意思,具体以后会有介绍,不急

然后是++nc,这就是一个自增运算,也可以写成nc=nc+1,也就是每次循环后,nc的值加1

还有注意long类型对应的是%ld,如果还按原来int对应的%d打是不行的

这个代码挺有意思,你可以一直输入,nc一直增加,一直循环,你发现就是打不出来nc的值,如果你需要结束,那么请按回车然后ctrl z然后回车,就输出nc的值,当然了最后一个回车不算字符,但是ctrl z前每一个回车都是要算进字符总数的

比如我现在直接就打ctrl z然后回车,结果:

 是0

然后我打3个字母再回车,再ctrl z再回车,结果:

 是4,

为什么不能直接在字符后面打ctrl z,因为无法识别,结果是这样的:

 我按了回车,编译器不理我...

同样,书中又给出了一种写法:

#include<stdio.h>
int main(void) {
	double nc;
	for (nc = 0; getchar() != EOF; ++nc)
		;
	printf("%.0f\n", nc);
	return 0;
}

 这里他不用long而用了双精度double,这都无关紧要,只是又换了种类型,可以处理更大的数字而已,与其对应的是%f,当然,这里.0表示还要取小数点后一位

然后运用的是for循环,循环中是一个 ;  就相当于空语句,其实,把 ; 直接放在括号后面就行

1.5.3行计数

这里要求统计输入的行数,我们知道换行符是\n,所以,我们要统计的是\n的数量,来看书中的例子:

#include<stdio.h>
int main(void) {
	int c, n1;
	n1 = 0;
	while ((c = getchar()) != EOF)
		if (c == '\n')
			++n1;
	printf("%d\n", n1);

	return 0;
}

道理与1.5.2中完全相同,我们打两个空格,然后ctrl z再回车,结果如下:

 两行,没问题

里面要注意的是'\n',这个\n外面要加上单引号,编译器才能认出这个换行符

1.5.4单词计数

#include<stdio.h>
#define IN 1//定义宏,也就是IN是1,OUT是0
#define OUT 0
int main(void) {
	int c, n1, nw, nc, state;//定义变量,可以看出,nc是字符数,n1是行数,nw是单词数,nc这里可以理解为单词数,行数,空格,tab数的总和
	state = OUT;//给state先赋值,也就是0
	n1 = nw = nc = 0;
	while ((c = getchar()) != EOF) {
		++nc;
		if (c=='\n')
			++n1;
		if (c == ' ' || c == '\n' || c == '\t')//利用了'||'或的运算符,就跟大家高中学的那个逻辑判断倒u那个意思差不多
			state = OUT;
		else if (state == OUT) {//else if可以这么理解,就是上面那个if不满足条件不执行时,执行else 然后里面有个if,那就再判断是否满足条件,若满足就执行这个if语句
			state = IN;
			++nw;
		}
	}
	printf("%d %d %d\n", n1, nw, nc);//最后打出统计的各个数量
	return 0;
}

这个代码中比较难懂的是那两个宏定义的值的作用,其实,就是说,如果输入的是单词,那么前两个if就不执行,前面赋值时state == OUT,满足了else if的条件,nw要加一,如果输入的是回车,那么第一个if会执行,n1要加一,然后,再执行第二个if,使state=0,当然了,这一步在这里没有起到什么实质作用,书中解释了这种写法提高了可读性。如果输入的是单词,那么就会执行else if使nw加1,但是无论输入什么(ctrl z不算),nc总要加1,相当于是输入字符的总数是nc.

我们试着输入两个单词,中间有一个回车,hi后面还打了一个空格,再打一个回车,打ctrl z,再回车

结果如下:

 可以看到,行数是2,单词数是2(这里即使你写的不是单词,比如www,只要他连在一起,就判定为单词),总字符数是8,五个字母,两个回车,一个空格。

好,本章到此为止,拖了好几天才补完...,如有疏漏,还请指正,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值