GVKun编程网logo

#define用法,C语言#define详解(#define在c语言中怎么使用)

32

如果您想了解#define用法,C语言#define详解和#define在c语言中怎么使用的知识,那么本篇文章将是您的不二之选。我们将深入剖析#define用法,C语言#define详解的各个方面,并

如果您想了解#define用法,C语言#define详解#define在c语言中怎么使用的知识,那么本篇文章将是您的不二之选。我们将深入剖析#define用法,C语言#define详解的各个方面,并为您解答#define在c语言中怎么使用的疑在这篇文章中,我们将为您介绍#define用法,C语言#define详解的相关知识,同时也会详细的解释#define在c语言中怎么使用的运用方法,并给出实际的案例分析,希望能帮助到您!

本文目录一览:

#define用法,C语言#define详解(#define在c语言中怎么使用)

#define用法,C语言#define详解(#define在c语言中怎么使用)

C语言中,可以用 #define 定义一个标识符来表示一个常量。其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了

预编译又叫预处理预编译不是编译,而是编译前的处理。这个操作是在正式编译之前由系统自动完成的。

用 #define 定义标识符的一般形式为:

#define  标识符  常量   //注意,最后没有分号

#define 和 #include 一样,也是以“#”开头的。凡是以“#”开头的均为预处理指令,#define也不例外。

#define又称宏定义,标识符为所定义的宏名,简称。标识符的命名规则与前面讲的变量的命名规则是一样的。#define 的功能是将标识符定义为其后的常量。一经定义,程序中就可以直接用标识符来表示这个常量。是不是与定义变量类似?但是要区分开!变量名表示的是一个变量,但宏名表示的是一个常量。可以给变量赋值,但绝不能给常量赋值。

宏所表示的常量可以是数字、字符、字符串、表达式。其中最常用的是数字。

那么,程序中什么时候会使用宏定义呢?用宏定义有什么好处呢?我们直接写数字不行吗?为什么要用一个标识符表示数字呢?

宏定义最大的好处是“方便程序的修改”。使用宏定义可以用宏代替一个在程序中经常使用的常量。注意,是“经常”使用的。这样,当需要改变这个常量的值时,就不需要对整个程序一个一个进行修改,只需修改宏定义中的常量即可。且当常量比较长时,使用宏就可以用较短的有意义的标识符来代替它,这样编程的时候就会更方便,不容易出错。因此,宏定义的优点就是方便和易于维护。

那么程序在预编译的时候是怎么处理宏定义的呢?或者说是怎么处理预处理指令的呢?

其实预编译所执行的操作就是简单的“文本”替换。对宏定义而言,预编译的时候会将程序中所有出现“标识符”的地方全部用这个“常量”替换,称为“宏替换”或“宏展开”。替换完了之后再进行正式的编译。所以说当单击“编译”的时候实际上是执行了两个操作,即先预编译,然后才正式编译。#include<stdio.h>也是这样的,即在预处理的时候先单纯地用头文件stdio.h中所有的“文本”内容替换程序中#include<stdio.h>这一行,然后再进行正式编译。

需要注意的是,预处理指令不是语句,所以后面不能加分号。这是很多新手经常犯的错误。#include 后面也没有加分号。

宏定义 #define 一般都写在函数外面,与 #include 写在一起。当然,写在函数里面也没有语法错误,但通常不那么写。#define 的作用域为自 #define 那一行起到源程序结束。如果要终止其作用域可以使用 #undef 命令,格式为:

#undef  标识符

undef 后面的标识符表示你所要终止的宏。比如前面在程序开头用 define 定义了一个宏 M,它原本的作用范围是一直到程序结束,但如果现在在程序中某个位置加了一句:
#undef  M
那么这个宏的作用范围到此就结束了。#undef 用得不多,但大家要了解。

为了将标识符与变量名区别开来,习惯上标识符全部用大写字母表示。宏定义用得最多的地方是在数组中用于指定数组的长度。下面来写一个程序:
# include <stdio.h>
# define NUM 5
int main(void)
{
    int i,j = NUM;
    int a[NUM] = {0};
    printf("请输入%d个数:",j);
    for (i=0; i<NUM; ++i)
    {
        scanf("%d",&a[i] );
    }
    for (i=0; i<NUM; ++i)
    {
        printf("%d\x20",a[i]);
    }
    printf("\n");
    return 0;
}
输出结果是:
请输入5个数:5 4 3 2 1
5 4 3 2 1

NUM 是定义的宏,它表示的是其后的常量(而不是变量)。此外,程序中用双引号括起来的宏在预处理的时候是不会被宏替换的。因为在 C 语言中,用双引号括起来表示的是字符串。下面再写一个程序看一下:
# include <stdio.h>
# define PI 3.14159
int main(void)
{
    double r,s;
    printf("请输入圆的半径:");
    scanf("%lf",&r);  //scanf中,double只能用%lf
    s = PI * r * r;
    printf("s=PI*r^2 = %.6f\n",s);  //PI不会被宏替换
    return 0;
}
输出结果是:
请输入圆的半径:1
s=PI*r^2 = 3.141590

2——PHP defined函数 ill defined be defined by already defined

2——PHP defined函数 ill defined be defined by already defined

*/
 * Copyright (c) 2016,烟台大学计算机与控制工程学院
 * All rights reserved.
 * 文件名:text.cpp
 * 作者:常轩
 * 微信公众号:Worldhello
 * 完成日期:2016年5月18日
 * 版本号:V1.0
 * 问题描述:PHP
 * 程序输入:无
 * 程序输出:无
 */
<?php define("PI1",3.14);
$p = "PI1";
$is1 = defined($p);
$is2 = defined("PI2");
var_dump($is1);
var_dump($is2);
?>
登录后复制

defined()函数可以帮助我们判断一个常量是否已经定义,其语法格式为:

bool defined(string constants_name

若存在则返回布尔类型true,否则返回布尔类型false; (注:bool表示函数返回值类型为布尔类型)

以上就介绍了2——PHP defined函数,包括了defined方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

c++中define用法

c++中define用法

#define

将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本

该命令有两种格式:一种是简单的宏定义,另一种是带参数的宏定义

#define   <宏名>  <字符串>

#define PI 3.1415926


#define   <宏名> (<参数表>)   <宏体>

#define   A(x) x

在程序被编译前,先将宏名用被定义的字符串替换然后才进行编译,宏替换是简单的替换


运行时机

c语言或c++运行经过以下阶段

               (预处理)                                 (编译)                          (汇编)                                      (链接)
源程序------------>修改后的源程序------------->汇编程序----------->可重定位的目标程序------------->可执行目标程序

预处理主要进行如下步骤替换

以把源程序中的#include 扩展为文件正文,即把包含的.h文件找到并展开到#include 所在处

预处理器根据#if和#ifdef等编译命令及其后的条件,将源程序中的某部分包含进来或排除在外,通常把排除在外的语句转换成空行

预处理器将源程序文件中出现的对宏的引用展开成相应的宏定义,即本文所说的#define的功能,由预处理器来完成。经过预处理器处理的源程序与之前的源程序有所有不同,在这个阶段所进行的工作只是纯粹的替换与展开,没有任何计算功能,所以在学习#define命令时只要能真正理解这一点,这样才不会对此命令引起误解并误用

原则:先替换再计算

#include<iostream>
using namespace std;
#define Max 100
#define N 2+2
#define M (2+2)
int i=1;
int main(){
        
        cout<<"Max is "<<Max<<endl;
        cout<<"N*N is "<<N*N<<endl;//2+2*2+2
        cout<<"M*M is "<<M*M<<endl;//(2+2)*(2+2)
        system("pause");
        return 0;
}

输出:

Max is 100

N*N is 8

M*M is 16

注意事项

要想能够真正使用好宏定义,一定要记住先将程序中对宏的使用全部替换成它所代表的字符串

在编程使用宏替换时,当字符串中不只一个符号时,加上括号表现出优先级

如果是带参数的宏定义,则要给宏体中的每个参数加上括号,并在整个宏体上再加一个括号。

例:

写一个标准的宏MIN,这个宏有两个参数,返回较小值

#define MIN(a,b)  ((a)>(b)?(b):(a))    //每一个参数都要用括号括起来,总体也要放在括号中

使用宏的优点

方便程序的修改

提高效率

使用带参数的宏定义可完成函数调用的功能,又能减少系统开销,提高运行效率。正如C语言中所讲,函数的使用可以使程序更加模块化,便于组织,而且可重复利用,但在发生函数调用时,需要保留调用函数的现场,以便子函数执行结束后能返回继续执行,同样在子函数执行完后要恢复调用函数的现场,这都需要一定的时间,如果子函数执行的操作比较多,这种转换时间开销可以忽略,但如果子函数完成的功能比较少,甚至于只完成一点操作,如一个乘法语句的操作,则这部分转换开销就相对较大了,但使用带参数的宏定义就不会出现这个问题,因为它是在预处理阶段即进行了宏展开,在执行时不需要转换,即在当地执行。宏定义可完成简单的操作,但复杂的操作还是要由函数调用来完成,而且宏定义所占用的目标代码空间相对较大。所以在使用时要依据具体情况来决定是否使用宏定义。



define的用法与注意事项 - 宠辱不惊,看庭前花开花落;去留无意,望天空云卷云舒 - C++博客



c/c++中define用法详解及代码示例

c/c++中define用法详解及代码示例

https://blog.csdn.net/u012611878/article/details/52534622

 
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012611878/article/details/52534622

c++中define用法

define在c++语言中用法比较多,这里对其进行整理。

1.无参宏定义

无参宏的宏名后不带参数。 
其定义的一般形式为:

#define  标识符  字符串
  • 1

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

#define MAXNUM 99999
  • 1

这样MAXNUM就被简单的定义为99999。

2.有参宏定义

C++语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。 
对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。 
带参宏定义的一般形式为:

 #define  宏名(形参表)  字符串
  • 1

在字符串中含有各个形参。在使用时调用带参宏调用的一般形式为:宏名(实参表); 
例如:

#define add(x, y) (x + y)
int main()
{
    cout << "1 plus 1 is " << add(1, 1.5) << ".\n"; //输出“1 plus 1 is 2.5.” system("pause"); return(0); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这个“函数”定义了加法,但是该“函数”没有类型检查,有点类似模板,但没有模板安全,可以看做一个简单的模板。

注意:该“函数”定义为(a + b),在这里加括号的原因是,宏定义只是在预处理阶段做了简单的替换,如果单纯的替换为a + b时,当你使用5 * add(2, 3)时,被替换为5 * 2 + 3,值为13,而非5 * (2 + 3),值为25。

3.宏定义中的特殊操作符 
define 中的特殊操作符有#,##和… and __VA_ARGS__ 
(1)# 
假如希望在字符串中包含宏参数,ANSI C允许这样作,在类函数宏的替换部分,#符号用作一个预处理运算符,它可以把语言符号转化程字符串。例如,如果x是一个宏参量,那么#x可以把参数名转化成相应的字符串。该过程称为字符串化。

例如:

#incldue <stdio.h>
#define PSQR(x) printf("the square of" #x "is %d.\n",(x)*(x))
int main(void)
{
    int y =4; PSQR(y); //输出:the square of y is 16. PSQR(2+4); //输出:the square of 2+4 is 36. return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(2)##

##运算符可以用于类函数宏的替换部分。另外,##还可以用于类对象宏的替换部分。这个运算符把两个语言符号组合成单个语言符号。 
例如:

#include <stdio.h>
#define XNAME(n) x##n
#define PXN(n) printf("x"#n" = %d\n",x##n)
int main(void) { int XNAME(1)=12;//int x1=12; PXN(1);//printf("x1 = %d\n", x1); //输出:x1=12 return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

(3)可变参数宏 …和__VA_ARGS__

__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。 
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏__VA_ARGS__就可以被用在替换部分中,替换省略号所代表的字符串。

例如:

#define PR(...) printf(__VA_ARGS__)
int main()
{
    int wt=1,sp=2; PR("hello\n"); //输出:hello PR("weight = %d, shipping = %d",wt,sp); //输出:weight = 1, shipping = 2 return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

省略号只能代替最后面的宏参数。 
#define W(x,…,y)错误! 
但是支持#define W(x, …),此时传入的参数个数必须能够匹配。

这里再介绍几个系统的宏:

1) __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的”,”去掉的作用,否则会编译出错, 你可以试试。 
2) __FILE__ 宏在预编译时会替换成当前的源文件名 
3) __LINE__宏在预编译时会替换成当前的行号 
4) __FUNCTION__宏在预编译时会替换成当前的函数名称

4.宏定义中的多行定义

非常经典。

#define MACRO(arg1, arg2) do { /
/* declarations */ /
stmt1; /
stmt2; /
/* ... */ /
} while(0) /* (no trailing ; ) */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

记得要在每一个换行的时候加上一个”/”

5.宏定义中的条件编译

在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

#ifdef WINDOWS
......
(#else)
......
#endif
#ifdef LINUX
......
(#else)
......
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

可以在编译的时候通过#define设置编译环境。

6.如何取消宏

//定义宏
#define [MacroName] [MacroValue]
//取消宏
#undef [MacroName] 
  • 1
  • 2
  • 3
  • 4
  • 5

7.防止重复包含头文件 
由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。 
通过条件编译开关来避免重复包含(重复定义) 
例如:

#ifndef __headerfileXXX__
#define __headerfileXXX__
…
文件内容
…
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

小结及说明

1) 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。 
2) 宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。 
3) 宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令。只要函数定义在#undefine之后,则函数无法使用#define的内容。 
4) 宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。 
5) 宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。 
例如:

 #define PI 3.1415926
 #define S PI*y*y          /* PI是已定义的宏名*/
  • 1
  • 2

6) 习惯上宏名用大写字母表示,以便于与变量区别。但也允许用小写字母。 
7) 可用宏定义表示数据类型,使书写方便。 
应注意用宏定义表示数据类型和用typedef定义数据说明符的区别。 
宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。 
请看下面的例子:

#define PIN1 int *
typedef (int *) PIN2;
  • 1
  • 2

从形式上看这两者相似, 但在实际使用中却不相同。 
下面用PIN1,PIN2说明变量时就可以看出它们的区别: 
PIN1 a,b;在宏代换后变成: 
int *a,b; 
表示a是指向整型的指针变量,而b是整型变量。 
然而: 
PIN2 a,b; 
表示a,b都是指向整型的指针变量。因为PIN2是一个类型说明符。由这个例子可见,宏定义虽然也可表示数据类型, 但毕竟是作字符代换。在使用时要分外小心,以避出错。 
8) 对“输出格式”作宏定义,可以减少书写麻烦。 
例如:

#define P printf
#define D "%d\n"
#define F "%f\n" main(){ int a=5, c=8, e=11; float b=3.8, d=9.7, f=21.08; P(D F,a,b); P(D F,c,d); P(D F,e,f); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

9)带参宏定义中,宏名和形参表之间不能有空格出现。 
10)在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。 
11)在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。

C/C++中的typedef和#define详解

C/C++中的typedef和#define详解

C/C++中的typedef和#define

前言:

     在C/C++中,我们平时写程序可能经常会用到typedef关键字和#define宏定义命令,在某些情况下使用它们会达到相同的效果,但是它们是有实质性的区别,一个是C/C++的关键字,一个是C/C++的宏定义命令,typedef用来为一个已有的数据类型起一个别名,而#define是用来定义一个宏定义常量。下面谈谈两者在实际使用中应当注意的地方。

1.typedef关键字

   typedef是用来声明类型别名的,在实际编写代码过程使用typedef往往是为了增加代码的可读性。它可以为一串很长的类型名起一个别名,那么使用这个别名可以达到与原类型名相同的效果。

    如:

typedef int INT;
typedef char CHAR;@H_301_20@

就为int和char分别起了一个别名,那么在程序中使用INT a;和int a;达到的效果是等同的。在使用typedef时应注意一下几点:

 1)typedef是为一个数据类型起一个新的别名,如typedef int INT;那么要告诉我的是INT表示整型,typedef int* INTPTR;则告诉我们INTPTR是一个指向整型变量的指针类型,这点与#define是决然不同的,#define只是作简单的字符串替换,不表达任何含义。如:

#define INTPTR1 int*
typedef int* INTPTR2;

INTPTR1 p1,p2;
INTPTR2 p3,p4;

@H_301_20@

INTPTR1 p1,p2;和INTPTR2 p3,p4;这两句的效果决然不同。INTPTR1 p1,p2;进行字符串替换后变成int* p1,p2;要表达的意义是声明一个指针变量p1和一个整型变量p2;而INTPTR2 p3,p4;由于INTPTR2是具有含义的,告诉我们是一个指向整型数据的指针,那么p3和p4都为指针变量,这句相当于int* p1,*p2;从这里可以看出,进行宏替换是不含任何意义的替换,仅仅为字符串替换;而用typedef为一种数据类型起的别名是带有一定含义的。

    再看下面这个例子:

#define INTPTR1 int*
typedef int* INTPTR2;

int a=1;
int b=2;
int c=3;
const INTPTR1 p1=&a;
const INTPTR2 P2=&b;
INTPTR2 const p3=&c;

@H_301_20@

上述代码中,const INTPTR1 p1表示p1是一个常量指针,即不可以通过p1去修改p1指向的内容,但是p1可以指向其他内容;而对于const INTPTR2 p2,由于INTPTR2表示是一个指针类型,因此用const去限定,表示封锁了这个指针类型,因此p2是一个指针常量,不可使p2再指向其他的内容,但可以通过p2修改其当前指向的内容,INTPTR2 const p3同样声明的是一个指针常量。

2)对于宏定义:

#define INT int
unsigned INT a;@H_301_20@

  这种用法是可行的;

typedef int INT;
unsigned INT a;@H_301_20@

是绝对错误的用法。

2.#define宏定义

   #define是一个宏定义命令,用来定义一个常量(包括无参常量和有参常量),它本身并不在编译过程中执行,而是在预处理阶段就已经完成了,因此不作任何正确性检查,只进行不关含义的字符串替换。在使用宏定义时,如果稍不注意就会发生错误,而且这个错误往往是你意想不到的。如:

#define ADD(a,b) a+b

int i=1;
int j=2;
int k=3;
int s=ADD(i,j)*k;

@H_301_20@

程序可能想求算的是(i+j)*k的结果,然而这段程序并没有达到这种效果,由于宏替换只是进行简单的字符串替换,那么ADD(i,j)*k相当于i+j*k,并不是想象中的(i+j)*k。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

今天的关于#define用法,C语言#define详解#define在c语言中怎么使用的分享已经结束,谢谢您的关注,如果想了解更多关于2——PHP defined函数 ill defined be defined by already defined、c++中define用法、c/c++中define用法详解及代码示例、C/C++中的typedef和#define详解的相关知识,请在本站进行查询。

本文标签: