C语言学习笔记(一)

预处理器

预处理指令
宏定义(#define, #undef),文件包含(#include),条件编译(#ifdef, #if, #elif,#else,#endif)
预处理指令全部以#开头
在#define中,如果要书写多行,则必须在当前行最后加上**,才可以继续书写下下一行:

#define DISK_CAPACITY (SIDES*               \
                       TRACKS_PER_SIDE*     \
                       SECTORS_PER_TRACK    \   
                       BYTES_PER_SECTOR)

对于带参数的宏定义而言,类似于这样的参数是有副作用的:
i++

#和##运算符

来看一下下面这个神奇的操作:

#define PRINT_INT(n) printf(#n" = %d\n", n)
int main() {
    int g = 3;
    PRINT_INT(g);
    return 0;
}

上面这段代码中的在经过预处理之后是这样的:

printf("g"" = %d\n", n);

在C语言中,两个相邻的字符串会被合并,也就是说,上面的代码段为:

printf("g = %d\n", n);

输出结果为:
这里写图片描述
#运算符会宏将的一个参数转换为字符串字面量,也就是说,n会被替换成g这个字符

再来看一下##运算符

#include<stdio.h>
#define PRINT_INT(n) printf(#n" = %d\n", n)
#define MK_ID(n) i##n=0

int main() {
    int MK_ID(1), MK_ID(2), MK_ID(3);
    PRINT_INT(i1+i2+i3);
    return 0;
}

输出结果:
这里写图片描述
##运算符可以将两个计号(标识符)粘结在一起,可以看到上面代码中的MK_ID(n)宏,会把穿进去的参数和i连接在一起,成为了变量in,使用这个宏,我们就能快速定义并初始化一系列变量

预定义宏

__LINE__    被编译文件的行号
__FILE__    被编译的文件名
__DATE__    编译的日期
__TIME__    编译的时间
__STDC__    如果编译器符合C标准(C89或C98),那么其值为1
#include<stdio.h> 

#define PRINT_INT(n) printf(#n" = %d\n", n)
#define PRINT_CHAR(str) printf(#str" = %s\n", str) 

int main() {
    PRINT_INT(__LINE__);    //  被编译文件的行号
    PRINT_CHAR(__FILE__);   //  被编译的文件名
    PRINT_CHAR(__DATE__);   //  编译的日期
    PRINT_CHAR(__TIME__);   //  编译的时间
    PRINT_INT(__STDC__);    //  如果编译器符合C标准(C89或C98),那么其值为1
    return 0;
}

这里写图片描述

C语言中是允许空的宏参数的

#include<stdio.h> 

#define PRINT_INT(n) printf(#n" = %d\n", n) 
#define ADD(i,j) i+j

int main() {
    int k = 101;
    int i = ADD(,k);
    PRINT_INT(i);
    return 0;
}

这里写图片描述
_fun_标识符

#include <stdio.h>

#define FUNCTION_CALLED() printf("%s called\n", __func__);

void fun() {
    FUNCTION_CALLED(); 
}
int main(void) {
    fun();
    return 0;
}

_fun_表示调用自己的是哪个函数

条件编译

条件编译中的所有关键字:

#if
defined
#ifdef
#elif
#else
#endif

条件编译多在调试的时候会用到:

#include <stdio.h>

#define DEBUG 1

int main(void) {
    printf("%s called\n", __func__);
    #if DEBUG
    printf("HELOO\n"); 
    #endif
    return 0;
}

#include <stdio.h>
*******************************************
#define DEBUG 0

int main(void) {
    printf("%s called\n", __func__);
    #if DEBUG
    printf("HELOO\n"); 
    #endif
    return 0;
}
*******************************************
#include <stdio.h>

#define DEBUG

int main(void) {
    printf("%s called\n", __func__);
    #if defined DEBUG
    //等价于ifdef DEBUG
    printf("HELOO\n"); 
    #endif
    return 0;
}

我们可以通过控制DEBUG宏的定义与否来控制是否输出中间结果
注意使用#if DEBUG的时候,判断结果跟DEBUG是有关的,0的时候为1的时候为
但在使用#if defined DEBUG或者ifedf DEBUG的时候,是不需要对DEBUG作准确的定义的,defined(ifdef)只是检查DEBUG是否被声明为一个Macro

 #ifdef DEBUG = #if defined DEBUG

这两句话是完全等价的,

猜你喜欢

转载自blog.csdn.net/include_heqile/article/details/80258747