王老师 预处理

1.宏定义

语法: #define 宏名字[(形参表)] 替换文本

其中,宏名字是一个标识符;

形参表为:(形参名1, 形参名2,...形参名n), 没有类型;

替换文本是一串字符.

宏调用和函数调用不同,是把程序中所有宏调用 "宏名字(实参表)", 用替换文本(实参代替形参)代替.

没有函数的跳转过程.

例如:

#define mul(x, y) ((x) * (y))

注意:此处必须加括号,否则,

(1)mul(x - 1,  y + 1);  展开为 x - 1 * y + 1;  //内层必须加()

(2)1 / mul(x, y);  展开为1 / x * y;  //外层也必须加()

另外,替换时,实参尽可能不要有副作用.

例如:

#define max(x, y) ((x) > (y) ? (x) : (y))

max(x++, y)  展开为 ((x++) > (y) ? (x++) : (y))

2.文件包含

#include "文件名"

头文件(*.h)一般包含:

类型定义,宏定义,函数原型,外部变量定义.

调用其它文件中函数的代码,是在link的过程中由linker将*.obj文件进行link处理的.

3.条件编译

#if 条件1

代码1

#else 条件2

 代码2

#endif

4.参数个数不确定的函数

形参表写法:(形参类型1 形参名1, ..., 形参类型n  形参名n, ... )

在程序中如何获取不确定的参数?

函数库提供了 stdarg.h, 一个类型, 2个宏.

typedef void * va_list;  //va_list是一个指针类型

va_start(p, para);         //para是最后一个确定参数的名字,这个宏给指针变量p赋初值,指向第一个不确定的参数

变量 = va_arg(p, 类型说明符); 

//取出p所指的不定参数的值,类型说明符说明了这个值的类型,同时p自动的改指下一个可变参数.

示例程序代码如下:

#include "stdio.h"
#include "stdarg.h"
#include "stdlib.h"

void scanf_e(char *c, ...)
{
 char a[1000], *p, *q;
 va_list r;
 va_start(r, c);
 while(*c != '/0')
 {
  gets(a);
  switch(*c)
  {
  case 'd':
   *va_arg(r, int *) = atoi(a);
   break;
  case 'f':
   *va_arg(r, double *) = atof(a);
   break;
  case 's':
   p = va_arg(r, char *);
   q = a;
   while(*p++ = *q++);
  }
  c++;
 }
}

void main()
{
 int a;
 double b;
 char c[100];
 scanf_e("dfs", &a, &b, c);
 printf("%d/t%f/t%s", a, b, c);
}

 <补充>
找了一下源代码, <stdarg.h>.
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )

这里的宏 _INTSIZEOF(n) 挺有意思。

例如:
#include <stdio.h>

struct student
{
int id;
int sex;
int age;
char name[10];
};

struct student s1, s2;

#define size(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))

int main()
{

printf("%d/n", &s1);
printf("%d/n", &s2);

printf( "%d/n", size(student));
return 0;
}

输出结果:
4373256
4373280
24

相差24个字节,而不是3 * 4 + 10 = 22个。

宏_INTSIZEOF(n) 达到此目的。

牛。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值