第十六章 C预处理器和C库
开发一个包含您需要使用的预处理器定义的头文件
//max.h #ifndef _MAX_H_ #define _MAX_H_ #define MAX(X, Y) ((X)>(Y)?(X):(Y)) #endif
2.两个数的调和平均数可用如下方法得到:首先对两数的倒数取平均值,最后再取倒数。使用#define指令定义一个宏“函数”执行这个运算。编写一个简单的程序测试该宏。
#include <stdio.h> #define HARMONIC_AVERAGEh(x, y) (1 / ((1/(x) + 1/(y)) /2)) //书上的答案,两个数的积的二倍除以两个数的和等于这两个数的调和平均数 //读书少,很多数学问题不懂,唉!!!! #define HMEAN(X,Y) (2.0 * (X) *(Y) / ((X) + (Y))) int main(void) { double x, y, z; x = 3; y = 9; z = HARMONIC_AVERAGEh(x, y); printf("%.2lf %.2lf的调和平均数是:%.2lf\n", x, y, z); printf("%.2lf %.2lf的调和平均数是:%.2lf\n", x, y, HMEAN(x, y)); return 0; }
3.极坐标用向量的长度和向量相对于x轴的逆时针转角来描述该向量。直角坐标用向量的x和y坐标来描述该向量(请参见图16.3)。编写程序,它读取向量的长度和角度(以度表示)然后显示x和y坐标。相关等式如下:
x = r cos A y = r sin A
要完成这个转换,需要使用一个函数,该函数接受一个包含极坐标的结构作为参数,返回一个包含直角坐标的结构(也可使用指向结构的指针)。
//完全是道数学题,不知道是否做对 #include <stdio.h> #include <math.h> #define PI 3.141592654 struct polar{ double len; double angle; }; struct tect{ double x; double y; }; struct tect PolarToTect(const struct polar * p); int main(void) { struct polar input; struct tect result; printf("Enter vector length and angle:"); scanf("%lf%lf", &input.len, &input.angle); result = PolarToTect(&input); printf("polar: %.2lf %.2lf\n", input.len, input.angle); printf("result: %.2lf %.2lf\n", result.x, result.y); return 0; } struct tect PolarToTect(const struct polar * p) { struct tect temp; //书上的答案为什么这里要求度数而不直角用输入的度数? //读书少不懂,就当是直角坐标需要吧。 double ang = PI / 180 * p->angle; temp.x = p->len * acos(ang); temp.y = p->len * asin(ang); return temp; }
4.ANSI库这样描述clock()函数:
#include <time.h>
clock_t clock(void);
clock_t是在time.h中定义的类型。clock()函数返回处理器时间,其单位依赖于实现(如果无法得到或无法表示处理器时钟,该函数返回-1).而同样在time.h中定义的CLOCKS_PER_SEC是每秒的处理器时间单位个数。因此,求出两次调用函数clock()的返回值差,再用CLOCKS_PER_SEC去除这个差值,结果就是以秒为单位的两次调用之间的时间间隔。在做除法之前,将值的类型指派为double类型,可以将时间精确到小数点以后。编写一个函数,接受一个时间延迟数作为参数,然后运行一个循环,直至这段时间过完。编写一个简单的程序测试该函数。
#include <stdio.h> #include <time.h> void delay(int time); int main(void) { int t; printf("请输入要延时的时间以秒为单位,输入字母Q退出:"); while (scanf("%d", &t) == 1) { delay(t); printf("时间到。\n"); printf("请输入要延时的时间以秒为单位,输入字母Q退出:"); } return 0; } void delay(int time) { double i; //i的值是执行到这条语句时程序运行的秒数 i = (double)clock() / CLOCKS_PER_SEC; while ((double)clock() / CLOCKS_PER_SEC - i < time) ; }
5.编写一个函数。访函数接受下列参数:一个int数组的名称,数组大小和一个代表选取次数的值。然后函数从数组中随机选择指定数量的元素并打印它们。每个元素最多选择一次(摸拟抽奖或挑选陪审成员)。另外,如果您的实现支持time()(在第12章中介绍)或其他类似函数,可在srand()中使用这个函数的输出来初始化随机数生成器rand()。编写一个简单的程序测试该函数。
#include <stdio.h> #include <stdlib.h> #include <time.h> #define NUM 36 void fun(int * pa, int n, int b); int main(void) { int a[NUM]; int i, num; for (i = 0; i < NUM; i++) a[i] = i + 1; srand((unsigned)time(NULL)); printf("请输入个数:"); while (scanf("%d", &num) == 1 && num > 0 && num <= NUM) { fun(a, NUM, num); printf("请输入个数:"); } return 0; } void fun(int * pa, int n, int b) { int len, temp; do { len = rand() % n; printf("%3d", pa[len]); if (len == n + 1) n--; else { temp = pa[n]; pa[n] = pa[len]; pa[n] = temp; n--; } } while (--b); printf("\n"); }
6.修改程序清单16.15使其使用struct names元素(在程序清单后定义)组成的数组,而不是使用用double数组,使用较少元素并显式初始化数组为由合适名字组成的数组。
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NUM 6 struct names{ char first[12]; char last[12]; }; void showarray(struct names ar[], int n); int mycomp(const void *p1, const void *p2); int main(void) { struct names name[NUM] ={ { { "dehua" }, { "liu" } }, { { "xueiyou" }, { "zhang" } }, { { "fucheng" }, { "guo" } }, { { "jahun" }, { "zhang" } }, { { "jahun" }, { "liang" } }, { { "chaowei" }, { "liang" } } };//不光英文不懂,拼音也好烂 puts("Random list: "); showarray(name, NUM); qsort(name, NUM, sizeof(struct names), mycomp); puts("\nSorted list: "); showarray(name, NUM); return 0; } void showarray(struct names * pname, int n) { int index; for (index = 0; index < n; index++) { printf("%s.%s", pname[index].last, pname[index].first); putchar(‘\n‘); } } int mycomp(const void *p1, const void *p2) { const struct names * a1 = (const struct names *)p1; const struct names * a2 = (const struct names *)p2; int i = strcmp(a1->last, a2->last); if (i != 0) return i; else return strcmp(a1->last, a2->last); }
7.下面是使用了可变函数的程序片断:
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> void show_array(const double ar[], int n); double * new_d_array(int n, ...); int main() { double * p1; double * p2; p1 = new_d_array(5, 1.2, 2.3, 3.4, 4.5, 5.6); p2 = new_d_array(4, 100.0, 20.00, 8.08, -1890.0); show_array(p1, 5); show_array(p2, 4); free(p1); free(p2); return 0; }
new_d_array()函数接受一个int参数和数量可变的double参数。该函数返回一个指向malloc()分配的内存块的指针。int参数指定动态数组中的元素个数:double值用于初始化元素(第一个值赋予第一个元素,依些类推)。提供show_array()和new_d_array()代码,使程序完整。
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> //此题关键是stdarg.h与函数可变参数的运用 void show_array(const double ar[], int n); double * new_d_array(int n, ...); int main() { double * p1; double * p2; p1 = new_d_array(5, 1.2, 2.3, 3.4, 4.5, 5.6); p2 = new_d_array(4, 100.0, 20.00, 8.08, -1890.0); show_array(p1, 5); show_array(p2, 4); free(p1); free(p2); return 0; } double * new_d_array(int lim, ...) { va_list va; va_start(va, lim); double * p; p = (double *)malloc(lim * sizeof(double)); for (int i = 0; i < lim; i++) p[i] = va_arg(va, double); va_end(va); return p; } void show_array(const double ar[], int n) { int i; for (i = 0; i < n; i++) printf("%.2lf ", ar[i]); printf("\n"); }
本文出自 “30岁学编程” 博客,请务必保留此出处http://xiongyi85.blog.51cto.com/8756903/1661356
C Primer Plus (第五版) 第十六章 C预处理器和C库 编程练习
原文:http://xiongyi85.blog.51cto.com/8756903/1661356