(预处理)
#define  标识符  字符串
其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等

宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用# undef命令。 


宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。 


带参宏定义(使用它要格外小心啊)
最好:定义时要注意每个参数要加括号,最外层也要加括号





1. 带参宏定义中,宏名和形参表之间不能有空格出现。(字符串中可以出现空格)





2. 在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参
,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时
要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。






3. 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。
#define SQ(y) (y)*(y)
 sq=SQ(a+1);
 sq=a+1*a+1;
这与函数的调用是不同的,函数调用时要把实参表达式的值求出来再赋予形参。而宏代换中对实参表达式不作计算直接地照原样代换。




4. 在宏定义中,字符串内的形参通常要用括号括起来以避免出错。在上例中的宏定义中(y)*(y)表达式的y都用括号括起来,因此结果是正确的。
宏定义也可用来定义多个语句,在宏调用时,把这些语句又代换到源程序内。看下面的例子。
【例9.11】
#define SSSV(s1,s2,s3,v) s1=l*w;s2=l*h;s3=w*h;v=w*l*h;
main(){
  int l=3,w=4,h=5,sa,sb,sc,vv;
  SSSV(sa,sb,sc,vv);
  printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n",sa,sb,sc,vv);
}

在宏调用时,把4个语句展开并用实参代替形参。使计算结果送入实参之中。



5

#include<stdio.h>
#define swap(x,y,t) (t=x,x=y,y=t)
void main(){
  int x=3,y=9,t;
  swap(x,y,t);
  printf("%d\n%d\n",x,y);
}


#include <stdio.h>


#define dprint(expr) printf(#expr " 111\n")
#define lian(a,b) a ## b
///第一个是把expr变为字符串;;;第二个是把a和b连在一起
void move1();
void main() 
{
dprint(9%%\\);和程序中的字符串转换一样
    lian(move,1)();

void move1()
{
dprint(9/3);
}



6

#include<stdio.h>
#include<stdlib.h>
#include <assert.h>// 断言
//下面是数组堆栈的宏 函数依次是 判空 判满 压入 置顶 输出
//##起到连接文本的作用
#define generic_stack(stack_type,suffix,stack_size)        \
        static stack_type stack##suffix[stack_size];    \
        static int  top_element##suffix=-1;                 \
        int is_empty##suffix()                             \
        {                                                 \
           return top_element##suffix==-1;                 \
        }                                                  \
        int is_full##suffix()                              \
        {                                                   \
           return top_element##suffix==stack_size-1;         \
        }                                                    \
        void push##suffix(stack_type value)                     \
        {                                                     \
                assert(!is_full##suffix());                     \
               top_element##suffix+=1;                         \
         stack##suffix[top_element##suffix]=value;             \
        }                                                    \
        void pop##suffix()                                    \
        {                                                     \
                assert(!is_empty##suffix());                 \
               top_element##suffix-=1;                         \
        }                                                    \
        stack_type top##suffix()                            \
        {                                                    \
               assert(!is_empty##suffix());                    \
              return stack##suffix[top_element##suffix];    \
        }                                                    
    
generic_stack(int,_int,10)//这里最好不要用分号




void main()
{


push_int(5);//输入5
push_int(10);
push_int(20);
    while(!is_empty_int())
    {
        printf("%d\n",top_int());//输出
        pop_int();
    }




}
但是楼主一定要小心宏定义后面的\,这个符号后面必须马上回车,不能加任何一个字符,空格 tab都不行。
C语言不支持嵌套函数定义  
















































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫云的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值