如何理解 函数 和 数组之间的关系(映射)
函数和数组都是一种映射,可参考数学基础f(x) 来理解,数组的映射为角标对应位置元素中的值,可理解前者为程序计算概念,后者为空间概念
c++ 编译 链接过程
g++ xxx.cpp (编译+链接)
a)如何得到.cpp 的对象文件
g++ -c xxx.cpp
b)怎么查看编译生成的对象文件
ll (linux 查看文件 类 ls 指令,但能查看 执行/权限/文件名/时间/大小)
c)查看对象文件内容
nm -C xxx.o (查看对象文件中申明的函数指令)
总结:函数前有数字则表明当前函数的定义是存在当前对象文件中的编译 (语法检查)+ 链接(符号链接,定义查找)
QA:
x.c / xx.cc 和 xxx.cpp 的关系
(.c 为c的源程序,.cpp为c++的源程序)
而 .cpp 和 .cc 的关系 [android 中c++ 为 .cc]
OS | 后缀名 |
---|---|
非UNIX 系统中 | .cpp |
Unix 系统中常用 | .cc |
xx.cc 中存在 xxx.cpp 中申明函数的函数定义,则xxx.cpp 文件在编译后执行链接时需要依赖前者实现最终的链接,否则链接失败
(可重复查看对应对象文件中的 函数声明)nm -C xx.o / xxx.o
编译源文件生成对象文件
g++ -c xxx.cpp
g++ -c xx.cc
编译完成后将xx.o文件链接到xxx.o文件(xxx.o依赖xx.o文件)
g++ xxx.o xx.o
执行程序
./a.out (默认产生的文件名)
(… 得到代码执行和结果)
链接中出现的问题和错误说明:
Note:【对于include 的系统库 ,系统会帮助完成链接工作,自申明的方法需要按照上面的流程完成补充定义并关联链接成为整体】
Nm -C /.a.out (除了可以看 .o 对象文件中的方法之外,还可以看可执行程序中的内容)
【未申明的函数 在文件编译过程中就会报错 undeclared identifier ‘xxx’】
链接两个文件中如果存在相同的函数定义,则会出现 符号重定义
duplicate symbol in:
xxx.o
xx.o 【如果申明后在链接时没有找到方法的定义以及 有定义但多对象文件出现重复方法定义均会在链接时期报错】
通过上述内容以上弄清了 什么是定义,什么是申明,此外为什么要 将 定义和申明分开?
定义是作用在链接阶段,申明是作用在编译阶段,申明是为了帮助程序通过编译阶段的语法检查,定义是为了帮助程序在链接时能够正确找到对应的语法匹配程序,
在具体程序里,会存在头文件和源文件的分开实现,这里会将定义放在源文件(.c/.cc/.cpp)中,申明放在头文件(.h)中,分开是因为两者作用的阶段不一样,头文件是辅助其他源文件通过编译阶段,如果将定义写在头文件中,再通过include到其他源文件后在链接时会产生duplicate symbol 符号重定义 的链接报错
如何理解自定义的c 源码在使用三方框架时的运行原理?
自定义的c源码要想生成最终的可执行程序需要通过前面描述的 编译 + 链接 两个阶段,使用三方框架提供的功能要想我们自定义的源代码通过编译阶段,则需要单独依赖一套三方框架提供功能的头文件申明功能api
当自定义的源代码通过编译生成目标文件在执行链接时,因为使用了三方框架提供的功能,需要将三方模块的功能(定义模块)整合进来,这个整合进来的功能模块通常是以通过链接或通过对象文件的压缩打包可以生成库文件[这里指静态库文件(.a)],最终和我们源码生成的中间文件链接才能生成最终的 可执行程序
整合三方库过程:
1.根据三方库的cmake文件 make 定义库文件提供给依赖方使用
举例下载google 的 gtest 库代码来操作,
库中会有CmakeLists.txt(前提是当前os中安装有 cmake的运行环境)
进入目录cd build/
在当前目录结构下执行 cmake ../ (会在上一级目录中找到 CMakeLists.txt 文件执行)
重点会生成Makefile
执行 make (会在lib中生成三方库的定义库文件 链接生成.a库文件)
2.结合自定义的源码文件完成编译+链接过程阶段
在 include文件夹中会有依赖三方库的 头文件(即申明部分)
将前面的静态库文件和 头文件 cp 到 自身定义的源文件目录中
2.1 include 对应目录下的 头文件到源文件中,使用三方库中定义的功能
2.2 终端 g++ -I ./include -c xxx.cpp (再执行编译) 【路径匹配查找操作完成编译】
(终端如果存在报错,可能需要声明当前的c++版本,完整指令为:g++ -std=c++11-I ./include -L ./lib xxx.cpp -lgtest)
2.3 包含依赖的三方库的库文件(.a api定义的方法功能) , g++ -L ./lib xxx.o -lgtest 【g++ xxx.o (链接) , 会报错】
这里会去链接 lgtest 对应在 lib 目录下 的libgtest.a 文件
流程图:
Printf 输出带色实现和使用说明:
样式;前景色;背景色(0用于重置属性,高亮/加粗 ;黄色; 红色)
格式: 配置(\033[ 0;x;xx;xxx;m)+属性代码(1;33;41)=> \033[0;1;33;41mHello world\n
如果只对当前这段内容进行配置修改属性不连累之后print的文案则需要 在 文案Hello world后 添加 \033[0m
printf(“ \033[1;33;41mHello world/n”)
其他指令说明:
Linux 指令学习: rm -rf xxx/ (删除 xxx 对应的目录文件夹)
生成文件夹 mkdir xxx
展示文件夹中文件内容详情 ll
如何理解 c++ 的编程函数理念,推荐书籍:《C++ 对象模型 》