C语言谭浩强第三版第九章例题及课后题:预处理命令
9.1定义一个带参数的宏,使两个参数的值互换
#include<stdio.h>
#define swap(a,b) tmp = a; a = b; b = tmp;
void main(void){
int a;
int b;
int tmp;
printf("Please input two integers:");
scanf("%d%d", &a, &b);
swap(a,b);
printf("交换后的值为:%d,%d\n", a, b);
}
9.2输入两个整数,求它们相除的余数
//#define remainder(a,b) a%b //自己
#define remainder(a,b) ((a)%(b)) //课本
//60 13 结果为:8
#include<stdio.h>
//#define remainder(a,b) a%b //自己
#define remainder(a,b) ((a)%(b)) //课本
void main(void){
int a;
int b;
int tmp;
printf("Please input two integers:");
scanf("%d%d", &a, &b);
printf("%d和%d相除的余数为:%d\n", a, b, a%b);
}
9.3求三角形面积
#define S(a,b,c) (((a)+(b)+(c))/2.0 )
要把参数带上,否则是错误的 一般宏定义用大写 |
#include<stdio.h>
#include<math.h>
#define S(a,b,c) (((a)+(b)+(c))/2.0 )
//#define AREA(a,b,c) sqrt(S*(S-a)*(S-b)*(S-c))
#define AREA(a,b,c) sqrt(S(a,b,c)*(S(a,b,c)-a)*(S(a,b,c)-b)*(S(a,b,c)-c))
/*
//自己有两个失误 1.边长应该用浮点型 2.未考虑三角形的形成条件
void main(void){
int a;
int b;
int c;
printf("请输入三角形的三条边:");
scanf("%d%d%d", &a, &b, &c);
printf("三角形面积为:%d\n", AREA(a,b,c));
}
*/
void main(void){
float a;
float b;
float c;
printf("请输入三角形的三条边:");
scanf("%f%f%f", &a, &b, &c);
if(a+b>c && a+c>b && b+c>a){
printf("三角形面积为:%.2f\n", AREA(a,b,c));
}else{
printf("It's not a triangle.\n");
}
}
9.4(5)判断闰年
// 7:10 - 7:15
#include<stdio.h>
#define LEAP_YEAR(y) (y%400 == 0 || (y%4==0 && y%100!=0))
void main(void){
int year;
printf("请输入一个年份:");
scanf("%d", &year);
if(LEAP_YEAR(year)){
printf("%d is a leap year.\n", year);
}else{
printf("%d is not a leap year.\n", year);
}
}
9.5分析下面的宏所定义的输出格式
对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。
9.6设计输出实数的格式
#include<stdio.h>
#define PR printf
#define NL "\n"
#define Fs "%f"
#define F "%6.2f"
#define F1 F NL
#define F2 F"\t"F NL
#define F3 F"\t"F"\t"F NL
void main(void){
float a;
float b;
float c;
PR("Please input three floating number:\n");
scanf(Fs, &a);
scanf(Fs, &b);
scanf(Fs, &c);
PR(NL);
PR("output one floating number each line:\n");
PR(F1, a);
PR(F1, b);
PR(F1, c);
PR(NL);
PR("output two floating number each line:\n");
PR(F2, a, b);
PR(F1, c);
PR(NL);
PR("output three floating number each line:\n");
PR(F3, a, b, c);
PR(NL);
}
9.7设计所需的各种各样的输出格式,用头文件包含进去
//format.h
#define INTEGER(d) printf("%d\n", d)
#define FLOAT(f) printf("%8.2f\n", f)
#define STRING(s) printf("%s\n", s)
#include<stdio.h>
#include"format.h"
void main(void){
int d;
float f;
char s[80];
int num;
printf("选择数据格式:1-integer, 2-float, 3-string:");
scanf("%d", &num);
switch(num){
case 1:
printf("input integer: ");
scanf("%d", &d);
INTEGER(d);
break;
case 2:
printf("input float: ");
scanf("%f", &f);
FLOAT(f);
break;
case 3:
printf("input string: ");
scanf("%s", s);
STRING(s);
break;
default:
printf("input error.\n");
}
}
9.8分别用函数和带参的宏,从3个数中找出最大值
/*
#include<stdio.h>
int max(int a, int b, int c);
int max(int a, int b, int c){
return (a>b ? a:b) > c ? (a>b ? a:b) : c;
}
void main(void){
int a, b, c;
printf("请输入3个整数:");
scanf("%d%d%d", &a, &b, &c);
printf("%d、%d和%d中最大的数为:%d\n", a, b, c, max(a, b, c));
}
*/
#include<stdio.h>
//#define MAX ((a>b)?a:b)
#define MAX(a, b) ((a>b)?a:b)
void main(void){
int a, b, c;
printf("请输入3个整数:");
scanf("%d%d%d", &a, &b, &c);
printf("%d、%d和%d中最大的数为:%d\n", a, b, c, MAX(MAX(a,b), c));
}
9.9试述“文件包含”和程序文件的连接的概念,二者有何不同?
“文件包含”是事先将程序中需要用到的信息分别存放在不同的“头文件”中(文件后缀为.h),用户在编写程序时,利用#include命令将该头文件的内容包含进来,成为程序中的一部分,特别应当注意的是,该头文件与它所在的源文件共同组成一个文件模块(而不是两个文件模块)。在编译时它是作为一个文件进行编译的。
连接(link)则与此不同,它的作用是将多个目标文件连接起来,得到两个或多个目标文件(后缀为.obj),在连接(link)阶段,把这些目标文件与系统提供的函数库等文件连接成一个可执行的文件(后缀为.exe)。 |
eg9.7输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出
一般情况下,源程序中所有行都参加编译。但是有时候希望程序中一部分内容只在满足一定条件时才进行编译,也就是对这一部分内容指定编译的条件,这就是“条件编译”。
疑问:不用条件编译命令而直接用if语句也能达到要求,用条件编译命令有什么好处? 的确,对这个问题完全可以不用条件编译处理而用if语句处理,但那样做,目标程序长(因为所有语句都编译),运行时间长(因为在程序运行时对if语句进行测试)。而采用条件编译,可以减少被编译的语句,从而减少目标程序的长度,减少运行时间。当条件编译段比较多时,目标程序长度可以大大减少。
|
#include<stdio.h>
//#define LETTER 1
//在对条件编译命令进行预处理时,由于LETTER为真,则对第一个if语句进行编译,运行时使小写字母变成大写
#define LETTER 0
//在对条件编译命令进行预处理时,由于LETTER为假,则对第二个if语句进行编译,运行时使大写字母变成小写
void main(void){
char str[20] = "C language";
char c;
int i = 0;
while((c = str[i]) != '\0'){
i++;
#if LETTER
if(c >= 'a' && c <= 'z'){
c = c-32;
}
#else
if(c >= 'A' && c <= 'Z'){
c = c+32;
}
#endif
printf("%c", c);
}
printf("\n");
}
9.10用条件编译输入一行电报文字选择输出形式
#include<stdio.h>
#define MAX 80
#define CHANGE 1void main(void){
char str[MAX];
int i;
printf("Please input text:");
gets(str);
#if(CHANGE)
{
for(i = 0; i < MAX; i++){
if(str[i] != '\0'){
if((str[i] >= 'a' && str[i] < 'z') || (str[i] >= 'A' && str[i] < 'Z')){
str[i]+=1;
}else if(str[i] == 'z' || str[i] == 'Z'){
str[i]-=25;
}
}
}
}
#endif
printf("output:%s\n", str);
}
比较(这两个很相似):
|
|
#include<stdio.h>
#define MAX 80
#define CHANGE 1
void main(void){
char str[MAX];
int i;
printf("Please input text:");
gets(str);
#if(CHANGE)
{
for(i = 0; i < MAX; i++){
if(str[i] != '\0'){
if((str[i] >= 'a' && str[i] < 'z') || (str[i] >= 'A' && str[i] < 'Z')){
str[i]+=1;
}else if(str[i] == 'z' || str[i] == 'Z'){
str[i]-=25;
}
}
}
}
#endif
printf("output:%s\n", str);
}