• C/C++基础


    gcc

    编译与链接

    编译:通过编译器,识别源文件中的语句,将其转换成计算机能够识别的二进制形式

    编译后,生成的是目标文件,不是最终的可执行文件
    目标文件(中间文件),是二进制形式(.o.obj
    编译只能编译单个源文件,多个源文件就需要多次编译

    链接:通过链接器,链接生成可执行文件。编译只是对自己编写的源文件进行编译,链接是将源文件的目标文件和标准库、动态链接库等结合起来,组成最终的可执行文件
    即,将所有二进制形式的目标文件和系统组件组合成一个可执行文件

    嵌入式编译器:CCS (DSP)

    多文件编译

    gcc test.c test2.c -o main.out
    file.out 是可执行文件

    头文件/库文件

    头文件

    头文件包含若干函数
    使用外部函数,要引入对应的头文件
    通常,头文件只包含函数的说明,即函数怎么用;而函数本身保存在其他文件,在链接时会找到
    #include#include的作用就是将头文件中的文本赋值到当前文件,然后一起被编译器编译
    在头文件中,必须:只能包含变量和函数声明,不能包含定义,否则在多次引入时会引起重复定义的错误

    ‘#’-预处理

    #开头的命令为预处理命令
    预处理:对源文件进行简单加工的过程
    预处理不等于编译,编译之前要先做预处理

    预处理包括:宏定义、文件包含、条件编译
    #if #elif #endif预处理命令,在编译之前由预处理程序来执行

    #include 
    
    // 对不同的平台引入不同的头文件
    #if _WIN32 // 识别windows平台,_WIN32是专有宏
    #include 
    #elif __linux__ // 识别linux平台 __linux__是专有宏
    #include 
    #endif
    
    it main(){
    	#if _WIN32
    	Sleep(10);
    	#elif __linux__
    	sleep(5);
    	#endif
    
    	// code...
    	puts('hello world')
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    ‘#’-文件包含

    #include文件包含
    其实也是预处理命令
    就是将头文件的内容插入到该命令所在的位置,从而将头文件、当前源文件连接成一个源文件

    # 在系统路径下查找头文件
    # "xxx.h"在当前目录下找头文件,如果没有找到,则从系统路径下查找

    ‘#’-宏定义

    宏定义:用一个标识符来表示一个字符串(这里的字符串指的不是数据类型字符串,而可以是数字、表达式、if语句,函数等),即后面的代码中用该标识符表示字符串
    在预处理阶段,对程序中所有出现的宏名,预处理器都会用宏定义中的字符串去代替,即“宏替换”
    #undef表示结束作用域
    代码中的宏如果被引号包围,则预处理程序不进行宏替换
    宏定义仅仅是字符串替换,不会对表达式进行计算

    #define N 100;
    printf("%d",N);
    
    #define M (n*n+3*n)
    
    • 1
    • 2
    • 3
    • 4

    带参宏定义

    带参宏定义中,不会为形式参数分配内存,因此不必指明数据类型,但是实参变量或返回值必须指明数据类型
    带参数宏定义,不是值传递

    #define FUNC(x) (x*2) // 注意要加括号
    int a;
    a=FUNC(10); // a=20
    
    • 1
    • 2
    • 3
    ‘#’ -条件编译

    条件编译:根据不同情况编译不同代码,产生不同目标文件的机制
    条件编译是预处理程序的功能,不是编译器的功能
    整型常量表达式:表达式中不能包含变量,且结果必须是整数
    目的:允许值编译源程序中满足条件的程序段

    #if 整型常量表达式
    	...
    #elif 整型常量表达式
    	...
    #else 整型常量表达式
    	...
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    ifdef

    如果当前宏已经被定义过,则对 对应的coding进行编译,否则

    #ifdef 宏名
    	// coding...
    #else
    	// coding...
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    ifndef/define/endif

    https://blog.csdn.net/m0_48990191/article/details/115007141 – 没看完

    ifdef相反,如果当前的宏未被定义,则对 对应的coding进行编译

    防止头文件被重复引用(一个头文件在同一个c/cpp文件中被include多次 <-- include嵌套),防止被重复编译

    被重复引用:有些被重复引用只是增加了编译工作的工作量,只会引起编译效率低下,有些则会引起错误(如在头文件中定义全局变量)

    • #ifndef

    条件编译,即预处理功能(宏定义、文件包含、条件编译)中的一种
    #ifndef作用

    如果.h文件中定义了全局变量,一个c文件包含了.h文件多次,如果不加#ifndef宏定义,会出现变量重复定义的错误

    • #define
    • #endif
    #ifndef FILE_H // if not define FILE.h 如果不存在file.h (作用:防止file.h被重复引用)
    #define FILE_H // 就引入file.h
    ... 
    #endif //否则不需要引入 
    
    • 1
    • 2
    • 3
    • 4
    #ifndef FILE_H
    #define FILE_H
    
    #include  // 引入标准库头文件
    #include "header.h" // 引入非标准库的头文件
    
    void function(...) //全局函数声明
    
    class C{}; // 类结构声明
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    if/ifdef/ifndef
    #if 只能是整型常量表达式
    #ifdef 只能是一个宏名
    #ifndef 只能是一个宏名
    
    • 1
    • 2
    • 3

    库文件

    区别
  • 相关阅读:
    l8-d6 socket套接字及TCP的实现框架
    新鲜出炉:appium2.0+ 单点触控和多点触控新的解决方案
    MySQL第五讲·关于外键和连接, 如何做到关联查询?
    图书管理系统【java】
    阐述 Git 命令 reset 和 revert
    CRM软件系统价格不同的原因
    Python实现随机森林RF并对比自变量的重要性
    Linux网络编程杂谈(聊聊网络编程背后的故事)
    Activity生命周期
    使用函数计算自定义运行时快速部署一个 SpringBoot 项目 | 文末有礼
  • 原文地址:https://blog.csdn.net/L_fengzifei/article/details/126432804