zoukankan      html  css  js  c++  java
  • 第25课

    第25课 - # 和 ## 操作符使用分析

    1. # 运算符

    (1)# 运算符用于在预处理期将宏参数转换为字符串,即加上双引号       (# 运算符的操作对象是宏参数)

    (2)# 的转换作用是在预处理期完成的,因此只在宏定义中有效;编译器并不知道 的转换作用

    (3)在有参宏中,# 只能和宏参数连用,不能和其它东西连用,比如 #define  INC(i)  {i++; #hhh  // 这个预处理器会报错,error: '#' is not followed by a macro parameter

     1 #include <stdio.h>
     2 
     3 #define STRING(x)  #x    // 将宏参数x转换为字符串
     4 
     5 int main()
     6 {
     7     printf("%s
    ", STRING(Hello World!));   // "Hello World!"
     8     printf("%s
    ", STRING(100));            // "100"
     9     printf("%s
    ", STRING(while));          // "while"
    10     printf("%s
    ", STRING(return));         // "return"
    11    
    12     return 0;
    13 }

    gcc -E 25-1.c 查看预处理结果,可以看到宏参数转变为了字符串格式

    scott@scott-ubuntu:~/c_course/ch_25$ gcc -E 25-1.c 
    # 1 "25-1.c"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 1 "<command-line>" 2
    # 1 "25-1.c"
    
    int main()
    {
        printf("%s
    ", "Hello World!");
        printf("%s
    ", "100");
        printf("%s
    ", "while");
        printf("%s
    ", "return");
    
        return 0;
    }

    【# 运算符的妙用】

     1 #include <stdio.h>
     2 
     3 // 打印被调用的函数的函数名,然后调用该函数
     4 #define CALL(f,p) (printf("Call function %s
    ",#f),f(p))
     5 
     6 int square(int n)
     7 {
     8     printf("Call function %s
    ", __func__)
     9     return n*n;
    10 }
    11 
    12 int func(int x)
    13 {
    14     return x;
    15 }
    16 
    17 int main()
    18 {
    19     int iRet = 0;
    20 
    21     iRet = CALL(square, 4);  // Call function square
    22     printf("result = %d
    ", iRet);  // result = 16
    23     
    24     iRet = CALL(func, 10);   // Call function func
    25     printf("result = %d
    ", iRet);  // result = 10
    26  
    27     return 0;
    28 }

    2. ## 运算符

    (1)## 运算符用于在预处理期粘连两个标识符        (## 运算符的操作对象是标识符)

    (2)## 的连接作用是在预处理器完成的,因此只在宏定义中有效;编译器并不知道 ## 的连接作用

    【## 运算符的基本用法】

     1 #include <stdio.h>
     2 
     3 #define NAME(n) name##n
     4 
     5 int main()
     6 {
     7     int NAME(1); // name1;
     8     int NAME(2); // name2;
     9     
    10     NAME(1) = 1;
    11     NAME(2) = 2;
    12     printf("%d
    ", NAME(1));  // 1
    13     printf("%d
    ", NAME(2));  // 2
    14     
    15     return 0;
    16 }

    【## 运算符的工程应用】

     1 #include <stdio.h>
     2 
     3 /*
     4 typedef struct _tag_Student Student;
     5 struct _tag_Student {
     6     int id;
     7     char *name;
     8 };
     9 */
    10 
    11 // 当工程中有很多结构体时,这样可以提高代码编写效率
    12 #define Struct(arg) typedef struct _tag_##arg arg;
    13                             struct _tag_##arg
    14 
    15 Struct(Student) {
    16     int id;
    17     char *name;
    18 };
    19 
    20 int main()
    21 {
    22     Student s1;
    23     Student s2;
    24 
    25     s1.id = 0;
    26     s1.name = "Scott";
    27 
    28     s2.id = 0;
    29     s2.name = "Fugui";
    30 
    31     printf("s1.id = %d
    ", s1.id);
    32     printf("s1.name = %s
    ", s1.name);
    33 
    34     printf("s2.id = %d
    ", s2.id);
    35     printf("s2.name = %s
    ", s2.name);
    36 
    37    return 0;
    38 }
  • 相关阅读:
    C# 多线程总结 异常处理 线程取消 锁(lock)
    C# sync/async 同步/异步
    C# Parallel 多线程并发
    C# Task TaskFactory 异步线程/异步任务
    C# ThreadPool 线程池
    Nginx基础配置
    Nginx配置通用语法
    Nginx进程间的关系
    Nginx命令行控制
    Flask框架02(路由)
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11853957.html
Copyright © 2011-2022 走看看