目录
1.下面的几组代码由一个或多个宏组成,其后是使用宏的源代码。在每种情况下代码的结果是什么?这些代码是否是有效代码?(假设其中的变量已声明)
4.定义EVEN_GT(X, Y)宏,如果X为偶数且大于Y,该宏返回1
5.定义一个宏函数,打印两个表达式及其值。例如,若参数为3+4和4*12,则打印:
7.定义一个宏,以下面的格式打印名称、值和int类型变量的地址:
name: fop; value: 23; address: ff464016
8.假设在测试程序时要暂时跳过一块代码,如何在不移除这块代码的前提下完成这项任务?
9.编写一段代码,如果定义了PR_DATE宏,则打印预处理的日期
10.内联函数部分讨论了3种不同版本的square()函数。从行为方面看,这3种版本的函数有何不同
11.创建一个使用泛型选择表达式的宏,如果宏参数是_Bool类型,对"boolean"求值,否则对"not boolean"求值
13.假设 scores 是内含 1000 个 int 类型元素的数组,要按降序排序该数组中的值。假设你使用qsort()和comp()比较函数。
14.假设data1是内含100个double类型元素的数组,data2是内含300个double类型元素的数组。
a.编写memcpy()的函数调用,把data2中的前100个元素拷贝到data1中。
b.编写memcpy()的函数调用,把data2中的后100个元素拷贝到data1中。
2.两数的调和平均数这样计算:先得到两数的倒数,然后计算两个倒数的平均值,最后取计算结果的倒数。使用#define指令定义一个宏“函数”,执行该运算。编写一个简单的程序测试该宏
需要一个函数来完成转换,该函数接受一个包含极坐标的结构,并返回一个包含直角坐标的结构(或返回指向该结构的指针)
6.修改程序清单16.17,使用struct names元素(在程序清单16.17后面的讨论中定义过),而不是double类型的数组。使用较少的元素,并用选定的名字显式初始化数组
复习题
1.下面的几组代码由一个或多个宏组成,其后是使用宏的源代码。在每种情况下代码的结果是什么?这些代码是否是有效代码?(假设其中的变量已声明)
a.
#define FPM 5280 /*每英里的英尺数*/
dist = FPM * miles;
dist = 5280 * miles
有效
b.
#define FEET 4
#define POD FEET + FEET
plort = FEET * POD;
plort = 4 * 4 + 4;
有效,但是如果想要表示4 * (4 + 4)的话应该修改POD的定义为(FEET + FEET)
c.
#define SIX = 6;
nex = SIX;
nex = = 6;;
无效
d.
#define NEW(X) X + 5
y = NEW(y);
berg = NEW(berg) * lob;
est = NEW(berg) / NEW(y);
nilp = lob * NEW(-berg);
y = y + 5;
有效
est = berg + 5 * lob;
有效,但可能有误
est = breg + 5 / y + 5
有效,但可能有误
nilp = lob * (-berg) + 5;
有效【传递进去的是负值不是一个符号加变量】
2.修改复习题1中d部分的定义,使其更可靠
#define NEW(X) ((X) + 5)//尽可能地多使用括号将宏函数的变量括起
3.定义一个宏函数,返回两值中的较小值
#define MIN(X, Y) ((X) > (Y) ?(Y) : (X))
4.定义EVEN_GT(X, Y)宏,如果X为偶数且大于Y,该宏返回1
#define EVEN_GT(X, Y) ((X) % 2 == 0 && (X) > (Y) ? 1 : 0)
//(X) % 2 == 0 && (X) > (Y)是一个完整的表达式
5.定义一个宏函数,打印两个表达式及其值。例如,若参数为3+4和4*12,则打印:
3+4 is 7 and 4*12 is 48
#define SHOW(X, Y) printf(#X "is %d and" #Y "is %d\n", X, Y)
//因为没有运算符作用于X或Y所以可以不加,括号这种东西注意就好- -
6.创建#define指令完成下面的任务。
a.创建一个值为25的命名常量。
b.SPACE表示空格字符。
c.PS()代表打印空格字符。
d.BIG(X)代表X的值加3。
e.SUMSQ(X, Y)代表X和Y的平方和。
a. #define CON 25
b. #define SPACE ' '
c. #define PS() printf(" ")
d. #define BIG(X) ((X) += 3)
e. #define SUMSQ(X,Y) ((X)*(X)+(Y)*(Y))
7.定义一个宏,以下面的格式打印名称、值和int类型变量的地址:
name: fop; value: 23; address: ff464016
#define SHOW(X) printf("name:"#X";value:%d;address:%p", X, &X)
8.假设在测试程序时要暂时跳过一块代码,如何在不移除这块代码的前提下完成这项任务?
#define DROP
#ifdef DROP
/*代码块*/
#endif
9.编写一段代码,如果定义了PR_DATE宏,则打印预处理的日期
#ifdef PR_DATE
printf("%s\n", __DATE__);
#endif
10.内联函数部分讨论了3种不同版本的square()函数。从行为方面看,这3种版本的函数有何不同
第一个正常返回一个double类型的数,输入1.3时,返回值为1.69
第二个在返回之前将结果强制转化为了int型,丢失精度。在返回转换时,返回值的小数部分全为0,输入1.3时,程序中返回值为1
第三个也在返回之前也将结果强制转化为int型,但在强制转化前结果加上了0.5,当输入为1.3时,返回值为2,输入为1.2时,返回值为1,以此来判断是调用了哪一个函数
11.创建一个使用泛型选择表达式的宏,如果宏参数是_Bool类型,对"boolean"求值,否则对"not boolean"求值
#define BOOL(X) _Generic((X), _Bool : "boolean", default : "not boolean")
12.下面的程序有什么错误
#include <stdio.h>
int main(int argc, char argv[])
{
printf("The square root of %f is %f\n", argv[1],sqrt(argv[1]) );
}
argv[] 应该改为 *argv[]
第一个%f应该改为%s
第二个argv[1]应当使用类似于atof()的函数转换为float型
应当在头文件中加上math.h
程序在使用sqrt应该排除参数是负数
13.假设 scores 是内含 1000 个 int 类型元素的数组,要按降序排序该数组中的值。假设你使用qsort()和comp()比较函数。
a.如何正确调用qsort()?
b.如何正确定义comp()?
qsort(scores, 1000, sizeof(int), comp);
int comp(const void *a, const void *b)
{
return (*(int*)a) - (*(int*)b);
}
14.假设data1是内含100个double类型元素的数组,data2是内含300个double类型元素的数组。
a.编写memcpy()的函数调用,把data2中的前100个元素拷贝到data1中。
b.编写memcpy()的函数调用,把data2中的后100个元素拷贝到data1中。
a. memcpy(data1, data2, 100 * sizeof(double));
b. memcpy(date1, &date2[200], 100 * sizeof(double));
编程题
1.开发一个包含你需要的预处理器定义的头文件
#ifndef DRAFT_ALLDEFINE_H
#define DRAFT_ALLDEFINE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define MIN(X, Y) ((X) > (Y) ? (Y) : (X))
#endif //DRAFT_ALLDEFINE_H