码迷,mamicode.com
首页 > 其他好文 > 详细

《C Primer Plus》学习笔记——C预处理器和C库

时间:2014-07-13 11:42:50      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   使用   

1、在Unix系统中,尖括号告诉预处理器在一个或多个标准系统目录中寻找文件。双引号告诉预处理器先在当前目录(或文件名中指定的其他目录)中寻找文件,然后在标准位置寻找文件。

2、#undef指令:取消定义一个给定的#define

#define LIMIT 400
#undef LIMIT

3、条件编译

#ifdef、#else#endif指令

#ifdef 宏名
  //语句段1
#else
  //语句段2
#endif

作用:当标识符已经被定义过(一般是用#define命令定义),则对语句段1进行编译,否则编译语句段2。

其中#else部分可以没有

#ifdef 宏名
  //语句段1
#endif

#ifndef指令

#ifndef 宏名
  //语句段1
#else
  //语句段2
#endif

作用:若标识符未被定义则编译语句段1,否则编译语句段2。

#else可以用于#ifdef#ifndef中,但#elif不可以

 

#if和#elif指令

#if 表达式
    // 语句段1
[#else
    // 语句段2]
#endif
#if 表达式1
    // 语句段1
#elif 表达式2
    // 语句段2
#else
    // 语句段3
#endif

#error

指令将使编译器显示一条错误信息,然后停止编译

#line

指令可以重置由__LINE__和__FILE__宏报告的行号和文件名

#line 1000            //把当前行号重置为1000
#line 10 “cool.c”   //把行号重置为10,文件名重置为cool.c

#pragma

指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息

 

实际的例子

#include <stdio.h>
#define LETTER 1
int main( int argc, char * argv[] )
{
    char str[20]="C Language",c;
    int i;
    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 );
    }
    return 0;
}
运行的结果:C LANGUAGE

用条件编译命令的好处:采用条件编译,可以减少被编译的语句,从而减少目标的长度。当条件编译段比较多时,目标程序长度可以大大减少

 

4、qsort函数

原型:

void  qsort (void *base,size_t num,size_t width,int ( *compar)(const void *,const void*))

 

其中base是排序的一个集合数组,num是这个数组元素的个数,width是一个元素的大小,comp是一个比较函数

例子:对一个长为1000的数组进行排序时,int a[1000]; 那么base应为anum应为 1000,width应为 sizeof(int),comp函数随自己的命名

qsort(a,1000,sizeof(int),compar);

由小到大排序:

int compar(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}

 

5、string.h库中的memcpy()memmove()

memcpy

原型:

void *memcpy(void *dest, const void *src, size_t n);

从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

memmove()

原型:

void *memmove( void* dest, const void* src, size_t n );

从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

 

6、可变参数步骤:

(1)在函数原型中使用省略号

(2)在函数定义中创建一个va_list类型的变量

(3)用宏将该变量初始化为一个参数列表

(4)用宏访问这个参数列表

(5)用宏完成清理工作

例子

bubuko.com,布布扣
 1 #include <stdio.h>
 2 #include <stdarg.h>
 3 double sum(int, ...);
 4 
 5 int main(void)
 6 {
 7     double s,t;
 8 
 9     s = sum(3, 1.1, 2.5, 13.3);
10     t = sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1);
11     printf("return value for "
12            "sum(3, 1.1, 2.5, 13.3):                %g\n", s);
13     printf("return value for "
14            "sum(6, 1.1, 2.1, 13.1, 4.1, 5.1, 6.1): %g\n", t);
15  
16     return 0;
17 }
18 
19 double sum(int lim,...)
20 {
21     va_list ap;                   // declare object to hold arguments
22     double tot = 0;
23     int i;
24 
25     va_start(ap, lim);            // initialize ap to argument list
26     for (i = 0; i < lim; i++)
27        tot += va_arg(ap, double); // access each item in argument list
28     va_end(ap);                   // clean up
29  
30     return tot;
31 }
View Code

 

习题

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

bubuko.com,布布扣
 1 #include <stdio.h>
 2 
 3 #define FUN(X, Y) (1/(1/X+1/Y))
 4 
 5 int main(void)
 6 {
 7  double m, n;
 8  scanf("%lf%lf",&m, &n);
 9  printf("FUN of %g and %g : %g\n",m, n, FUN(m, n));
10  return 0;
11 }
View Code

2、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类型,可以将时间精确到小数点以后。编写一个函数,接受一个时间延迟数作为参数,然后运行一个循环,直至这段时间过完。编写一个简单的程序测试该函数。

bubuko.com,布布扣
 1 #include <stdio.h>
 2 #include <time.h>
 3 
 4 void delay(double time);
 5 
 6 int main(void)
 7 {
 8  double time;
 9  printf("input a time(in seconds) to delay(q to quit):");
10  while( scanf("%lf",&time) == 1 )
11  {
12   delay(time);
13   printf("time is out!\n");
14   printf("input a time(in seconds) to delay(q to quit):");
15  }
16 }
17 
18 void delay(double time)
19 {
20  double origin;
21  origin = clock() / CLOCKS_PER_SEC ;
22  while(clock() / CLOCKS_PER_SEC < origin + time);
23 }
View Code

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

bubuko.com,布布扣
 1 #include <stdio.h>
 2 #include <time.h>
 3 #include <stdlib.h>
 4 
 5 #define M 20
 6 
 7 void random_pick(int *p, int size, int number);
 8 
 9 int main(void)
10 {
11      int i, member[M], number;
12      srand(time(0));
13      printf("the M members are:\n");
14      for(i=0; i<M; i++)
15      {
16          member[i] = rand()%100;
17          printf("%d\t",member[i]);
18      }
19      printf("\ninput the size you want to pick (q to quit):");
20      while( scanf("%d", &number) == 1 )
21      {
22          random_pick(member, M, number);
23          printf("input the size you want to pick (q to quit):");
24      }
25 }
26 
27 void random_pick(int *p, int size, int number)
28 {
29  int i,j,count,pick[M],temp,repeat; //pick数组用于存放已选取成员的下标
30  for(i=0, count=0; i<number; )
31  {
32   temp = rand() % size;
33   for(j=0, repeat=0; j<count; j++)   //去除重复数
34    if ( temp == pick[j] )
35    {
36     repeat = 1;
37     break;
38    }
39   if ( repeat == 0 )
40   {
41    pick[count++] = temp ;
42    i++;
43   }
44  }
45 
46  printf("the picks are:\n");
47  for(j=0; j<count; j++)
48   printf("%d\t",p[pick[j]]);
49  printf("\n");
50 }
View Code

 

 

《C Primer Plus》学习笔记——C预处理器和C库,布布扣,bubuko.com

《C Primer Plus》学习笔记——C预处理器和C库

标签:des   style   blog   http   color   使用   

原文地址:http://www.cnblogs.com/cxyfreedom/p/3837729.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!