C语言#define的用法(2)

如题所述

第1个回答  2022-07-19
  例如:如果x是一个宏参量,那么#x可以把参数名转化为相应的字符串。该过程称为字符串化。

  #include

  #define PSQR(x) printf ("The square of " #x" is %d\n", ((x)*(x)))

  int main (void)

  {

  int y = 2;

  PSQR (y);

  PSQR (2 + 4);

  return 0;

  }

  输出结果:

  The square of y is 4

  The square of 2 + 4 is 36

  #include

  #include

  #define VEG(n) #n

  int main()

  {

  char str[20];

  strcpy(str,VEG(num));//num

  printf("%s\n",str);//拷贝

  return 0;

  }

  输出结果:

  num

  预处理器的粘合剂:##运算符

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

  #include

  #define XNAME(n) x##n

  #define PRINT_XN(n) printf ("x"#n" = %d\n", x##n)

  int main (void)

  {

  int XNAME (1) = 14; //变为 int x1 = 14;

  int XNAME (2) = 20; //变为 int x2 = 20;

  PRINT_XN (1); //变为 printf ("x1 = %d\n", x1);

  PRINT_XN (2); //变为 printf ("x2 = %d\n", x2);

  return 0;

  }

  输出结果:

  x1 = 14

  x2 = 20

  宏用于简单函数:

  #include

  #define MAX(x,y) ((x)>(y) ? (x) : (y)) /*比较大小*/

  #define ABS(x) ((x) < 0 ? -(x) : (x)) /*绝对值*/

  #define ISSIGN(x) ((x) == '+' || (x) == '-' ? 1 : 0) /*正负号*/

  int main()

  {

  printf ("较大的为: %d\n", MAX(5,3));

  printf ("绝对值为: %d\n", ABS (-2));

  printf ("正负号为: %d\n", ISSIGN ('+'));

  return 0;

  }

  输出结果:

  较大的为: 5

  绝对值为: 2

  正负号为: 1

  下面是需要注意的几点:

  1、宏的名字中不能有空格,但是在替代字符串中可以使用空格。ANSI C 允许在参数列表中使用空格。

  2、用圆括号括住每个参数,并括住宏的整体定义。

  3、用大写字母表示宏函数名,便于与变量区分。

  4、有些编译器限制宏只能定义一行。即使你的编译器没有这个限制,也应遵守这个限制。

  5、宏的一个优点是它不检查其中的变量类型,这是因为宏处理字符型字符串,而不是实际值。

  面试:用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)

  #define SEC (60*60*24*365)UL

  考察内容:

  1、懂得预处理器将为你计算常量表达式的值,因此,可直接写出你是如何计算一年中有多少秒而不是计算出实际的值,这样更清晰而没有代价。

  2、意识到这个表达式将使一个16 位机的整形数溢出,因此要用到长整形符号 L ,告诉编译器这个常数是长整形数。

  3、如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的`起点。

  面试:写一个“标准”宏MIN ,这个宏输入两个参数并返回较小的一个

  #define MIN(A,B) ((A) <= (B) ? (A) : (B))

  考察内容:

  1、三目表达式的使用

  2、使用必须的足够多的圆括号来保证以正确的顺序进行运行和结合

  3、进一步讨论,在宏中不要使用增量或减量运算符

  参看:宏名必须用大写字母吗?

  研究:C语言中用宏定义(define)表示数据类型和用typedef定义数据类型有什么区别?

  宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,它不是作简单的代换,而是对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。

  请看下面的例子:

  #define P1 int *

  typedef (int *) P2

  从形式上看这两者相似,但在实际使用中却不相同。

  下面用P1、P2说明变量时就可以看出它们的区别:

  P1 a, b; 在宏代换后变成: int *a, b; 表示 a 是指向整型的指针变量,而 b 是整型变量。

  P2 a, b; 表示a,b都是指向整型的指针变量。因为PIN2是一个类型说明符。

  由这个例子可见,宏定义虽然也可表示数据类型, 但毕竟是作字符代换。在使用时要分外小心,以避出错。

  总结,typedef和#define的不同之处:

  1、与#define不同,typedef 给出的符号名称仅限于对类型,而不是对值。

  2、typedef 的解释由编译器,而不是是处理器执行。

  3、虽然它的范围有限,但在其受限范围内,typedef 比 #define 更灵活。

  用于定义字符串,尤其是路径

  A),#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3

  B),#define ENG_PATH_2 “ E:\English\listen_to_this\listen_to_this_3”

  A 为 定义路径, B 为定义字符串

  C), #define ENG_PATH_3 E:\English\listen_to_this\listen\

  _to_this_3

  还没发现问题?这里用了 4 个反斜杠,到底哪个是接续符?回去看看接续符反斜杠。反斜杠作为接续符时,

  在本行其后面不能再有任何字符,空格都不行。所以,只有最后一那给 ENG_PATH_1 加上双引号不就成了:“ENG_PATH_1”。但是请注意:有的系统里规定路径的要用双反斜杠“ \\” ,比如:

  #define ENG_PATH_4 E:\\English\\listen_to_this\\listen_to_this_3
相似回答