define

define是C语言的预处理,作用是宏定义。

所谓宏,是将一些命令组织在一起,作为一个单独命令完成一个特定任务。

预处理命令以“#”号开头,如包含命令#include,宏定义命令#define等。

一般都放在源文件的前面,它们称为预处理部分。

所谓预处理是指在进行编译之前所作的工作。 在进行编译C语言源程序的前一个步骤就是预处理。

define可以定义函数,常量(也就是定义一个不可变的变量,包括字符,字符串)。

使用方式:

(1)定义常量

#include<string.h>
#include<stdio.h>
#define PI 3.14
#define PI_Name "pi is" int main(void)
{
printf("%s\t%f",PI_Name,PI); //\t是TAB。输出宏
}

定义了两个宏,一个数字,一个字符串。

我们使用正常的方式可以输出。

他们是不可修改的常量。如果对其修改,会报错。

(2)定义函数(有参数)

定义函数可以分为有参数,无参数(定义表达式)两种。

#include<string.h>
#include<stdio.h>
#define A (a,b)(a)+(b) int main(void)
{
int x=A(,);
printf("%d",x);
}

我们定义一个宏,是一个带有参数的宏。

A函数带有a,b两个参数,并返回a+b的值。

为什么a+b要写成(a)+(b)呢?

是为了保证运算。

请看下面的例子

#include<string.h>
#include<stdio.h>
#define A(a)a*a int main(void)
{
int x,c=;
x=A(c+);
printf("%d",x);
}

我们希望返回a*a值。

此代码我们在A函数中填入的C+1也就是3,A函数返回的值应该是9。

但确实返回的5,这与我们所期望的值有很大的偏差。

因为,A(c+1)拆开后等于c*c+1所以等于5。

如果我们将a*a加上括号

不出所料,我们得到正确的值。

这回将宏拆开。

A(C+1)=(c+1)*(c+1)

括号将运算的优先级提高了。所以会得到一个正确的值。

但是!

有时候加这么样加括号还是不好用的! 为什么呢?请我们考虑一下运算的优先级。

请看下面的代码

#include<string.h>
#include<stdio.h>
#define A(a)(a)*(a)
int main(void)
{
int x,c=;
x=/A(c+);
printf("%d",x);
}

在上面的代码中A函数返回值是9,我们这把依旧让返回值等于9,不过我们让X的值等于99/A(c+1).

我们希望得到的值是11。

但是我们为什么得到的却是99呢?

因为优先级的关系,99/A(c+1)等于99/(c+1)*(c+1)也就是99/3*3,所以的值是99。

那怎么解决呢?

我们根据A函数的含义,将A函数内的表达式的预算优先级提高。

也就是

#include<string.h>
#include<stdio.h>
#define A(a)((a)*(a))
int main(void)
{
int x,c=;
x=/A(c+);
printf("%d",x);
}

OK

(3)定义函数(无参数)(定义表达式)

其实定义常量也算是定义函数无参数的一种,但是我为了好区分这两种定义宏的区别,特地分开。

毕竟定义的方法上有一定的区别。

#include<string.h>
#include<stdio.h>
#define A (a+3)
int main(void)
{
int x,a=;
x=/A;
printf("%d",x);
}

我们依旧是定义一个A“函数”,但是无参数。

这回这个A“函数”可以理解为一个表达式。

请注意看在代码中使用A“函数”的方式,并没有括号,也就是A“函数”不接受参数。而且在再宏定义的时候A“函数”内a是存在代码内。

这种行为,更像是一种提前定义好的表达式。其中的“参数” 都是必须严格符合A“函数”。

也就是x=99/A;这句等于x=99/(a+3)

当然这句话也要考虑优先级的问题。所有A“函数”加上了括号。

因为是我想要a+3,根据含义,最后形成了A(a+3)这个样子

温故而知新_C语言_define_宏的更多相关文章

  1. 温故而知新_C语言_递归

    递归. 是的,差不多就是这种感觉.上面就是类似递归的显示表现. 2017 10 24更新: 递归这个问题放了很久.也没有写.大概是自己还没有好好理解吧. 在这里写下自己理解的全部. 一 何为递归. 字 ...

  2. 温故而知新_C语言_前缀++(--)和后缀++(--)

    前缀++(--)和后缀++(++)是有区别的. 再单独使用的时候是没有区别的,都是自身递增或者递减1. 但是综合使用起来会一样吗? 下面的例子都是++,替换成--也是一样,道理都是一样的. 请先看下面 ...

  3. 【书籍下载链接】_1_第一轮_C语言书籍

    各位朋友,如果您觉得下载的电子书,看的还可以,请购买纸质版的图书,如果您觉得 您下载的书,不值得一看请在下载后直接删除. Windows汇编:http://dl.vmall.com/c0jk1v970 ...

  4. C语言中宏定义(#define)时do{}while(0)的价值(转)

    C语言中宏定义(#define)时do{}while(0)的价值 最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总 ...

  5. c 语言中宏定义和定义全局变量的区别

    宏定义和定义全局变量的区别: 1 作用时间不同. 宏定义在编译期间即会使用并替换,而全局变量要到运行时才可以. 2 本质类型不同. 宏定义的只是一段字符,在编译的时候被替换到引用的位置.在运行中是没有 ...

  6. 选择排序_C语言_数组

    选择排序_C语言_数组 #include <stdio.h> void select_sort(int *); int main(int argc, const char * argv[] ...

  7. 插入排序_C语言_数组

    插入排序_C语言_数组 #include <stdio.h> void insertSort(int *); int main(int argc, const char * argv[]) ...

  8. 快速排序_C语言_数组

    快速排序_C语言_数组 #include <stdio.h> void quickSort(int *, int, int); int searchPos(int *, int, int) ...

  9. 冒泡排序_C语言_数组

    冒泡排序_C语言_数组 #include <stdio.h> //冒泡排序 小->大 void sort(int * pArray, int len); int main(int a ...

随机推荐

  1. Zabbix配置微信报警通知

    Zabbix告警可以通过邮件,微信,电话,短信等方式发送告警消息. 电话和短信需要向运营商购买相应的网关,需要付费: 邮件和微信是免费的,可以根据业务需要选择相应的告警模式 Zabbix版本:3.2 ...

  2. DataGridview刷新异常的问题

    datsSet 绑定到dataGrieView,在刷新dataSet的数据时,常会bug:索引0没有值或索引(int)x没有值 昨天弄了一个下午,发现bug原因: dataGridView中有数据时, ...

  3. java代码异常捕获throws抛出异常

    总结:Throwable 是所以异常的父类.error和Exception是继承它的类 Exception: 这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环 ...

  4. 高效C#编码优化

    1.foreach VS for 语句 Foreach 要比for具有更好的执行效率Foreach的平均花费时间只有for的30%.通过测试结果在for和foreach都可以使用的情况下,我们推荐使用 ...

  5. web编程的初步认识

    一直以后, 只知道打开浏览器, 输入网址便可以上网浏览网页, 但是当认真琢磨起这web编程的时候, 对于很多细节却是感觉很迷惑, 在慢慢的学习中, 才逐渐有了些了解. web有client/serve ...

  6. C#改变LInqToSQL的引用地址,读取config的数据库字符串

    C#改变LInqToSQL的引用地址,读取config的数据库字符串修改Properties 下 Settings.Settings 下 Settings.Designer.cs 下 return ( ...

  7. leetcode443

    使用两个数组分别记录字符和对应的数字,然后清除原来的vector,重新向里面添加元素.注意判断1个字符时,不将'1'加入vector. int compress(vector<char>& ...

  8. vesamenu.c32:not a COM32R image报错解决方案

    今天用U盘刻录安装Linux Mint 的时候,一直出现 vesamenu.c32:not a COM32R image这个报错,查了很久,原因好像是电脑是老电脑的原因.处理的办法很简单,只需要输入l ...

  9. session详解&和cookie的区别

    session简介 1. 定义 session用来保存会话数据, 将数据保存到服务器中. 2. 作用 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),一个浏览器独占一 ...

  10. Codeforces #505(div1+div2) C Plasticine zebra

    题意:给你一段字符串,可以选择任意多的位置,每个位置会反转两边的字符串,问交错的字符串最长是多长? 思路:找规律,仔细分析样例1.假设位置为 1 2 3 4 5 6 7 8 9,反转之后会发现答案是7 ...