2024年【维生素C语言】第十七章 - C语言预处理(下)_总程序自定义comm,2024年最新我把所有C C++框架整理成了PDF

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

📚 介绍:许多C的编译器提供的一种能力,允许在命令行中定义符号。用于启动编译过程。当我们根据同一个源文件要编译出不同的一个程序的不同版本的时,可以用到这种特性,增加灵活性。

💬 例子:假如某个程序中声明了一个某个长度的数组,假如机器甲内存有限,我们需要一个很小的数据,但是机器丙的内存较大,我们需要一个大点的数组。

#include <stdio.h>

int main() {
    int arr[ARR_SIZE];
    int i = 0;
    for (i = 0; i < ARR_SIZE; i++) {
        arr[i] = i;
    }
    for (i = 0; i < ARR_SIZE; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}

🚩 gcc 环境下测试:(VS 里面不太好演示)

gcc test.c -D ARR_SIZE=5

ls

a.out  test.c

./a.out

0 1 2 3 4 5

gcc test.c -D ARR_SIZE=20

./a.out

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

二、条件编译

0x00 介绍

📚 在编译一个程序时,通过条件编译指令将一条语句(一组语句)编译或者放弃是很方便的。

💬 调试用的代码删除了可惜,保留了又碍事。我们就可以使用条件编译来选择性地编译:

#include <stdio.h>

#define __DEBUG__ // 就像一个开关一样

int main(void)
{
    int arr[10] = {0};
    int i = 0;
    for (i = 0; i < 10; i++) {
        arr[i] = i;
        #ifdef __DEBUG__ // 因为__DEBUG__被定义了,所以为真
        printf("%d ", arr[i]); // 就打印数组    
        #endif // 包尾
    }

    return 0;
}

🚩 运行结果:1 2 3 4 5 6 7 8 9 10

❗  如果不想用了,就把 #define __DEBUG__ 注释掉:

#include <stdio.h>

// #define __DEBUG__ // 关

int main(void)
{
    int arr[10] = {0};
    int i = 0;
    for (i = 0; i < 10; i++) {
        arr[i] = i;
        #ifdef __DEBUG__ // 此时ifdef为假
        printf("%d ", arr[i]);      
        #endif
    }

    return 0;
}

🚩 (代码成功运行)

0x01 条件编译之常量表达式

📚 介绍:如果常量表达式为真,参加编译。反之如果为假,则不参加编译。

💬 代码演示:常量表达式为真

#include <stdio.h>

int main(void) {
#if 1
    printf("Hello,World!\n");
#endif

    return 0;
}

🚩 运行结果:Hello,World!

💬 代码演示:常量表达式为假

#include <stdio.h>

int main(void) {
#if 0
    printf("Hello,World!\n");
#endif

    return 0;
}

🚩 (代码成功运行)

💬 当然也可以用宏替换,可以表示地更清楚:

#include <stdio.h>

#define PRINT 1
#define DONT_PINRT 0

int main(void) {
#if PRINT
    printf("Hello,World!\n");
#endif

    return 0;
}

0x02 多分支的条件编译

📚 介绍:多分支的条件编译,直到常量表达式为真时才执行。

💬 代码演示:

#include <stdio.h>

int main(void) {
#if 1 == 2 // 假
    printf("rose\n");
#elif 2 == 2 // 真
    printf("you jump\n");
#else 
    printf("i jump\n")
#endif

    return 0;
}

🚩 代码运行结果:you jump

0x03 条件编译判断是否被定义

📚 定义:ifdef 和 if defined() ,ifndef 和 if !defined() 效果是一样的,用来判断是否被定义。

💬 代码演示:

#include <stdio.h>

#define TEST 0
// #define TEST2 // 不定义

int main(void) {
/* 如果TEST定义了,下面参与编译 */
// 1
#ifdef TEST
    printf("1\n");
#endif

// 2
#if defined(TEST)
    printf("2\n");
#endif


/* 如果TEST2不定义,下面参与编译 */
// 1
#ifndef TEST2
    printf("3\n");
#endif

// 2
#if !defined(TEST2)
    printf("4\n");
#endif

    return 0;
}

0x04 条件编译的嵌套

📚 和 if 语句一样,是可以嵌套的:

#if defined(OS_UNIX)
    #ifdef OPTION1
        unix_version_option1();
    #endif
    #ifdef OPTION2
        unix_version_option2();
    #endif
#elif defined(OS_MSDOS)
    #ifdef OPTION2
        msdos_version_option2();
    #endif
#endif

三、文件包含

我们已经知道,#include 指令可以使另外一个文件被编译。就像它实际出现于 #include 指令的地方一样。替换方式为,预处理器先删除这条指令,并用包含文件的内容替换。这样一个源文件被包含10次,那就实际被编译10次。

0x00 头文件被包含的方式

📚  < > 和 " " 包含头文件的本质区别:查找的策略的区别

① " " 的查找策略:先在源文件所在的目录下查找。如果该头文件未找到,则在库函数的头文件目录下查找。(如果仍然找不到,就提示编译错误)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

① " " 的查找策略:先在源文件所在的目录下查找。如果该头文件未找到,则在库函数的头文件目录下查找。(如果仍然找不到,就提示编译错误)

[外链图片转存中…(img-BmBfnNGu-1715592080428)]
[外链图片转存中…(img-XY9jFKbm-1715592080428)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值