define的用法小结

define的用法只是一种纯粹的替换功能,宏定义的替换是预处理器处理的替换。

 一:简单的宏定义用法

  格式:#define 标识符 替换内容

  替换的内容可以是数字,字符,字符串,特殊字符和空格,后面是什么内容就会替换成什么内容。

  例如:

  #define  N   5    效果等同于    int  array [5];

  int  array[N];

  同样效果:

  #define N = 5

  int array[N];       效果等同于    int  array[= 5];

  同样效果:

  #define N   5;

  int array[N];       效果等同于    int  array[5;];

  常见的一种错误:

  #define  pin  int*

  pin  a  , b ;     实际上的效果是    int  *a , b;

  

  #define N 2+2

  void main(void)

  {

    int a = N * N;

    printf("%d\n" , a );

  }

  结果是2+2*2+2=8


二:带参数的宏定义的使用

例子说话:一个求正方形面积的函数

  使用#define的正确写法应该是:   

#include<stdio.h>
#define area(x)   ((x)*(x))
int main(void)
{
int s = area(3 + 3);
printf("s = %d\n" , s);
return 0;
}

运行结果:(3+3)*(3+3)= 36  是我们想要的结果

  常见问题写成:

#include<stdio.h>
#define area(x)   x*x
int main(void)
{
int s = area(3 + 3);
printf("s = %d\n" , s);
return 0;
}

运行结果:3 + 3 * 3 + 3 = 15   不是我们想要的结果

这更能体现出前面说的define的宏定义就是纯粹的一种替换,做的是先替换后计算的工作。

防止这种问题的方法:

   要想能够真正使用好宏定义,防止出现上面一二两种常用情况的一些错误,一定要记住在思路上先将程序中对宏的使用全部替换成它所代表的字符串,不要自作主张地添加任何其他符号,完全展开后再进行相应的计算,就不会写错运行结果。在编程使用宏替换时,当字符串中不只一个符号时,加上括号表现出优先级,如果是带参数的宏定义,则要给宏体中的每个参数加上括号,并在整个宏体上再加一个括号。


三:常用作对函数的封装

例子说话:现在原有一个求两个数乘积的函数mult

[Linux@centos-64-min exercise]$ cat mul.c
#include <stdio.h>
int mult(int x , int y )
{
  int result = x * y;
  return result;
}

现在需要不同的两个功能函数,一个是求正方形面积的函数 square_area和一个求长方形的面积的函数rectangle_area。

可以这样写:

[Linux@centos-64-min exercise]$ cat mul.c
#include <stdio.h>
int mult(int x , int y )
{
int result = x * y;
return result;
}
[Linux@centos-64-min exercise]$ cat try.c
#include <stdio.h>
int mult(int x , int y);              /*两个数字相乘的函数的声明*/

#define square_area(str , x) mult(x , x)      /*封装成一个求正方形面积的函数*/
#define rectangle_area(str , x , y) mult(x , y)  /*封装成一个求长方形面积的函数*/

/*上面那些函数声明和宏定义按照比较规范的书写,本来应该放在一个头文件里面的,这里为了说明问题就简单放在函数里了*/
int main(void)
{
  int s = 0;
  s = square_area("This is the area of the square" , 3);
  printf("This is the area of the square : s = %d\n" , s);
  s = rectangle_area("This is the area of the rectangle" , 3 ,4);
  printf("This is the area of the rectangle : s = %d\n" , s);
  return 0;
}

运行结果:

[Linux@centos-64-min exercise]$ gcc -o try try.c mul.o
[Linux@centos-64-min exercise]$ ./try
This is the area of the square : s = 9
This is the area of the rectangle : s = 12


四:define中的三个特殊符号:#,##,#@

#define Conn(x,y) x##y
#define ToChar(x) #@x
#define ToString(x) #x

x##y表示x连接y,举例说:
int n = Conn(123,456);   结果就是n=123456;
char* str = Conn("asdf", "adf")结果就是 str = "asdfadf";

#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:
char a = ToChar(1);结果就是a='1';
做个越界试验char a = ToChar(123);结果就错了;
但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015: too many characters in constant   :P

#x,表示给x加双引号
char* str = ToString(123132);就成了str="123132";


五:小结#define宏定义

(1)   方便程序的修改
      使用简单宏定义可用宏代替一个在程序中经常使用的常量,这样在将该常量改变时,不用对整个程序进行修改,只修改宏定义的字符串即可,而且当常量比较长时, 我们可以用较短的有意义的标识符来写程序,这样更方便一些。

(2)  宏定义是在预编译的时候就进行替换。程序中调用子函数执行完之后都必须饭后调用该子函数的现场继续往下执行,这样就会出现了函数转换的消耗。但是使用带参数的宏定义就不会出现这个问题,因为它是在预处理阶段即进行了宏展开,在执行时不需要转换,即在当地执行,但复杂的操作还是要由函数调用来完成,而且宏定义所占用的目标代码空间相对较大。所以在使用时要依据具体情况来决定是否使用宏定义。

define的用法的更多相关文章

  1. typedef和#define的用法与区别

    typedef和#define的用法与区别 typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程 ...

  2. C语言中#define的用法(转)

    转自:http://www.dingge.com/main/article.asp?id=10 今天整理了一些#define的用法,与大家共享! 1.简单的define定义 #define MAXTI ...

  3. C语言中#define的用法

    今天整理了一些#define的用法,与大家共享! 1.简单的define定义 #define MAXTIME 1000 一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写 if(i& ...

  4. 【转】typedef和#define的用法与区别

    typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...

  5. c++define的用法

    c++define的用法   在写程序时经常会碰到这样一个问题,我们需要重复写很多相同的代码,并且这些代码结构相同.总是想自己把这段代码封装一下然后直接进行调用,但是如果这段代码逻辑并不复杂,并且代码 ...

  6. (转)typedef和#define的用法与区别

    typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...

  7. c++ define的用法(转)

    #define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用 ...

  8. define的用法与注意事项

    ------------------------------------------------- 在编程使用宏替换时,当字符串中不只一个符号时,加上括号表现出优先级, 如果是带参数的宏定义,则要给宏 ...

  9. 90.#define高级用法

    define把参数变成字符串 #define f(x) printf("%s",#x); define连接两个字符串 #define a(x) a##x define把参数变成字符 ...

随机推荐

  1. selenium修改控件属性

    起因:在进行退出的时候,控件属性显示为不可显示,于是在界面上是不可以点击的,如果想点击这个按钮,只能通过修改控件属性,进行点击 上图看控件,正常来说,点击坐边的用户名,下拉会出现一个logout,退出 ...

  2. 数理方程:Laplace变换 & 留数(更新中)

    更新:25 APR 2016 Laplace变换 设函数\(f(t)\)在\(t>0\)时有定义,积分 \(F(s)=\int_0^{+\infty}f(t)e^{-st}dt \qquad ( ...

  3. WPF ScrollViewer(滚动条) 自定义样式表制作 再发一套样式 细节优化

    艾尼路 出的效果图 本人嵌套 WPF ScrollViewer(滚动条) 自定义样式表制作 图文并茂 WPF ScrollViewer(滚动条) 自定义样式表制作 (改良+美化) 源代码

  4. 【CSS3】---层模型position之fixed固定定位、absolute绝对定位和relative相对定位

    什么是层模型? 什么是层布局模型?层布局模型就像是图像软件PhotoShop中非常流行的图层编辑功能一样,每个图层能够精确定位操作,但在网页设计领域,由于网页大小的活动性,层布局没能受到热捧.但是在网 ...

  5. 自定义View(一)-ViewGroup实现优酷菜单

    自定义View的第一个学习案例 ViewGroup是自动以View中比较常用也比较简单的一种方式,通过组合现有的UI控件,绘制出一个全新的View 效果如下: 主类实现如下: package com. ...

  6. Part 8 AngularJS filters

    Filters in angular can do 3 different things 1. Format data 2. Sort data 3. Filter data Filters can ...

  7. Swiper之滑块2

    对比之前Swiper滑块1来说,我们添加一下背景颜色来看看: <!DOCTYPE html> <html> <head> <meta http-equiv=& ...

  8. 第九篇、自定义底部UITabBar

    国际惯例先上图: 代码实现(在UITabBarViewController设置): - (void)setUpTabBar { LHLTabBar *tabBar = [[LHLTabBar allo ...

  9. 10款经典的web前端特效的预览及源码

    1.CSS3响应式导航菜单 今天我给大家介绍一下如何使用纯CSS来实现的一个响应式导航菜单,我们使用的是HTML5+CSS3技术,当浏览器窗口变小或者使用手机浏览器访问的时候,原本横条菜单会收缩成一个 ...

  10. 三款精美的html5及css3的源码插件

    1.HTML5 3D爱心动画 晚来的七夕礼物 七夕情人节刚过,今天小编却在国外的网站上看到一个利用HTML5和CSS3制作的3D爱心动画,莫非老外也过七夕?当然小编还是将这款HTML5 3D爱心动画收 ...