您的位置:首页 > 编程语言

第16章 C预处理器和C库 编程练习

2017-08-06 00:00 260 查看
1、开发一个包含您需要使用的预处理器定义的头文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mylib.c"

#define MAX 12

#define SUMSQ(x,y)((x)*(x)+(y)*(y))
#define P(x) printf("name: "#x"; value: %d; address: %p\n",x,&x)

2、两个数的调和平均数可用如下方法获得:首先对两个数的倒数取平均值,最后再取倒数。使用#define指令定义一个宏“函数”执行这个运算。编写一个简单的程序测试该宏。

#include <stdio.h>

#define HARMONIC_MEAN(X,Y)( 1/(1/X+1/Y) )

int main(void)
{
double x,y;
scanf("%lf%lf",&x,&y);
printf("harmonic mean of %g and %g : %g\n",x,y,HARMONIC_MEAN(x,y));
return 0;
}

3、极坐标用向量的长度和向量相对于x轴的逆时针转角来描述该向量。直角坐标用向量的x和y坐标来描述该向量。编写程序,它读取向量的长度和角度(以度表示)然后显示x和y坐标。相关等式如下:

x = r cos A y =r sin A

要完成这一转换,需要使用一个函数,该函数接受一个包含极坐标的结构作为参数,返回一个包含直角坐标的结构(也可以使用指向结构的指针)。

#include <stdio.h>
#include <math.h>

#define PI 4*atan(1)

struct polar_v{
double magnitude;
double angle;
}polar;

struct rectangular_v{
double x;
double y;
}rect;

struct rectangular_v polar_to_Rectangular(struct polar_v polar2);

int main(void)
{
printf("input magnitude and angle(in degrees),(input q to quit):");
while(scanf("%lf%lf",&polar.magnitude,&polar.angle)==2)
{
rect = polar_to_Rectangular(polar);
printf("x = %g,y = %g\n",rect.x,rect.y);
printf("input magnitude and angle(in degrees),(input q to quit):");
}
return 0;
}

struct rectangular_v polar_to_Rectangular(struct polar_v polar2)
{
struct rectangular_v rect2;
rect2.x = polar2.magnitude * cos(polar2.angle * PI / 180);
rect2.y = polar2.magnitude * sin(polar2.angle * PI / 180);
return rect2;
};

4、ANSI C 库这样描述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(double time);

int main(void)
{
double time;
printf("Input a time(in seconds) to delay(q to quit):");
while(scanf("%lf",&time) == 1)
{
delay(time);
printf("time is out !\n");
printf("Input a time(in seconds) to delay(q to quit):");
}
}

void delay(double time)
{
double origin;
origin = clock() / CLOCKS_PER_SEC;
while(clock()/CLOCKS_PER_SEC < origin + time);
/*每次循环clock()/CLOCKS_PER_SEC都会递增,直到等于origin+time。可以应用于类似倒计时的功能*/
}

5、编写一个函数。该函数接受下列参数:一个Int数组的名称,数组大小和一个代表选取个数的值。然后函数从数组中随机选择指定数量的元素并打印它们。每个元素最多选择一次(模拟抽奖或挑选陪审成员)。另外,如果您的实现支持time()或其他类似函数,可以rand()中使用这个函数的输出来初始化随机数生成器rand()。编写一个程序测试该函数。

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define M 20

void random_pick(int *p,int size,int number);  //number代表选取个数

int main(void)
{
int i,member[M],number;
srand(time(0));
/*参数time(0)是rand()的种子,用来初始化rand()的起始值。这样保证每次的起始值是变动的*/
/* 如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed一个变值,
这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)*/
printf("The M members are:\n");
for(i=0;i<M;i++)
{
member[i]=100+i;
printf("%d\t",member[i]);
}
printf("\nInput the size you want to pick(q to quit):");
while(scanf("%d",&number)==1)
{
random_pick(member,M,number);
printf("Input the size of you want to pick(q to quit):");
}  /*用一个循环来读取输入*/
}

void random_pick(int *p,int size,int number)
{
int i,j,count,pick[M],temp,repeat;  //pick数组用于存放已选取成员的下标
for(i=0,count=0;i<number;)
{
temp = rand() % size;   //取余获得随机值赋给temp
for(j=0,repeat=0;j<count;j++)  //去除重复数
if(temp==pick[j])
{
repeat=1;
break;
}
if(repeat==0)
{
pick[count++]=temp;  //随机数赋给下标数组pick[]
i++;
}
}

printf("The picks are:\n");
for(j=0;j<count;j++)
printf("%d\t",p[pick[j]]);  //pick[j]是所选元素的下标值
printf("\n");
}

6、修改程序清单16.15,使其使用由struct names元素(在程序清单后定义)组成的数组,而不是使用double数组。使用较少元素并显式初始化数组为由合适名字组成的数组。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM 5

struct names {
char first[10];
char last[10];
};

void showarray(const struct names *p,int n);
int comp(const void *p1,const void *p2);

int main(void)
{
struct names staff[NUM]={
{"Jawe",  "Hsadff"},
{"Jasff",  "Hsadff"},
{"Jasff",  "Paswqeq"},
{"Qmetrbv",  "Tsjdfef"},
{"Msdwersa", "Bsfwoo"}
};

puts("Random list:");
showarray(staff,NUM);
qsort(staff,NUM,sizeof(struct names),comp);
puts("\nSorted list:");
showarray(staff,NUM);

return 0;
}

void showarray(const struct names *p,int n)
{
int index;
for(index=0; index<n; index++)
printf("%-10s %-10s\n",p[index].first,p[index].last);
}

int comp(const void *p1,const void *p2)  /*mandatory form*/
{
/*get right type of pointer*/
const struct names *ps1 = (const struct names *) p1;
const struct names *ps2 = (const struct names *) p2;
int res;

res=strcmp(ps1->last,ps2->last);  /*compare last names*/
if(res!=0)
return res;
else /*last names identical ,so compare fist names */
return strcmp(ps1->first,ps2->first);
}

7、下面是使用了可变参数的程序片断:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void show_array(const double ar[],int n);
double *nes_d_array(int n,...);

int main(void)
{
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>

void show_array(const double ar[],int n);
double * new_d_array(int n,...);

int main(void)
{
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;
}

show_array(const double ar[],int n)
{
int index;
for(index=0; index<n; index++)
printf("%g\t",ar[index]);
printf("\n");
}

double * new_d_array(int n,...)
{
double * p;
int i;

va_list ap;
/* 数据对象ap用于存放参量列表中省略号部分代表的参量 */

p = (double *)malloc(n*sizeof(double));
/* 指向malloc()分配的内存块的指针 */

va_start(ap,n);
/*把参数列表复制到va_list变量中*/

for(i=0; i<n; i++)
p[i] = va_arg(ap,double); /*依次访问参数列表中的内容*/

va_end(ap);

return p;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息