<pre id="lq0nf"><label id="lq0nf"></label></pre>
<td id="lq0nf"><strike id="lq0nf"></strike></td>
  • <object id="lq0nf"><meter id="lq0nf"></meter></object>
    <object id="lq0nf"><nav id="lq0nf"><noframes id="lq0nf">
  • <pre id="lq0nf"><label id="lq0nf"></label></pre>
    1. 侵权投诉

      四个方面全面解析Linux 下 C++ 编译&amp;链接

      开关电源芯片 ? 2021-08-27 09:36 ? 次阅读

      【导读】:编译与链接对C++&C++程序员既熟悉又陌生,熟悉在于每份代码都要经历编译与链接过程,陌生在于大部分人并不会刻意关注编译与链接的原理。本文通过开发过程中碰到的四个典型问题来探索64位linux下C++编译&链接的那些事。

      以下是正文

      编译原理

      将如下最简单的C++程序(main.cpp)编译成可执行目标程序,实际上可以分为四个步骤:预处理、编译、汇编、链接,可以通过

      g++ main.cpp –v看到详细的过程,不过现在编译器已经把预处理和编译过程合并。

      预处理:g++ -E main.cpp -o main.ii,-E表示只进行预处理。预处理主要是处理各种宏展开;添加行号和文件标识符,为编译器产生调试信息提供便利;删除注释;保留编译器用到的编译器指令等。

      编译:g++ -S main.ii –o main.s,-S表示只编译。编译是在预处理文件基础上经过一系列词法分析、语法分析及优化后生成汇编代码。

      汇编:g++ -c main.s –o main.o?;惚嗍墙惚啻胱骺梢灾葱械闹噶?。

      链接:g++ main.o。链接生成可执行程序,之所以需要链接是因为我们代码不可能像main.cpp这么简单,现代软件动则成百上千万行,如果写在一个main.cpp既不利于分工合作,也无法维护,因此通常是由一堆cpp文件组成,编译器分别编译每个cpp,这些cpp里会引用别的??橹械暮蛉直淞?,在编译单个cpp的时候是没法知道它们的准确地址,因此在编译结束后,需要链接器将各种还没有准确地址的符号(函数、变量等)设置为正确的值,这样组装在一起就可以形成一个完整的可执行程序。

      问题一:头文件遮挡

      在编译过程中最诡异的问题莫过于头文件遮挡,如下代码中main.cpp包含头文件common.h,真正想用的头文件是图中最右边那个包含name

      c984c19a-f62b-11eb-9bcf-12bb97331649.png

      成员的文件(所在目录为。/include),但在编译过程中中间的common.h(所在目录为。/include1)抢先被发现,导致编译器报错:Test结构没有name成员,对程序员来讲,自己明明定义了name成员,居然说没有name这个成员,如果第一次碰到这种情况可能会怀疑人生。应对这种诡异的问题,我们可以用-E参数看下编译器预处理后的输出,如下图。

      c9b0d500-f62b-11eb-9bcf-12bb97331649.jpg

      预处理文件格式如下:# linenum filename flag,表示之后的内容是从文件名为filaname的文件中第linenum行展开的,flag的取值可以是1,2,3,4,可以是用空格分开的多值,1表示接下来要展开一个新文件;2表示一个文件展开完毕;3表示接下来内容来自一个系统头文件;4表示接下来的内容应该看做是extern C形式引入的。

      从展开后的输出我们可以清楚地看到Test结构确实没有定义name这个成员,并且Test这个结构是在。/include1中的common.h中定义的,到此真相大白,编译器压根就没用我们定义的Test结构,而是被别的同名头文件截胡了。我们可以通过调整-I或者在头文件中带上部分路径更详细制定头文件位置来解决。

      目标文件:

      编译链接最终会生成各种目标文件,Linux下目标文件格式为ELF(Executable Linkable Format),详细定义见/usr/include/elf.h头文件,常见的目标文件有:可重定位目标文件,也即.o结尾的目标文件,当然静态库也归为此类;可执行文件,比如默认编译出的a.out文件;共享目标文件.so;核心转储文件,也就是core dump后产出的文件。Linux文件格式可以通过file命令查看。

      一个典型的ELF文件格式如下图所示,文件有两种视角:编译视角,以section头部表为核心组织程序;运行视角,程序头部表以segment为核心组织程序。这么做主要是为了节约存储,很多细碎的section在运行时由于对齐要求会导致很大的内存浪费,运行时通?;峤ㄏ蘩嗨频膕ection组织成segment一起加载。

      通过命令objdump和readelf可以查看ELF文件的内容。

      对可重定位目标文件常见的section有:

      ca2e1600-f62b-11eb-9bcf-12bb97331649.png

      符号解析:

      链接器会为对外部符号的引用修改为正确的被引用符号的地址,当无法为引用的外部符号找到对应的定义时,链接器会报undefined reference to XXXX的错误。另外一种情况是,找到了多个符号的定义,这种情况链接器有一套规则。在描述规则前需要了解强符号和弱符号的概念,简单讲函数和已初始化的全局变量是强符号,未初始化的全局变量是弱符号。

      针对符号的多重定义链接器处理规则如下(作者在gcc 7.3.0上貌似规则2,3都按1处理):

      1. 不允许多个强符号定义,链接器会报告重复定义貌似的错误

      2. 如果一个强符号和多个弱符号同名,则选择强符号

      3. 如果符号在所有目标文件中都为弱符号,那么选择占用空间最大的一个

      有了这些基础,我们先来看一下静态链接过程:

      1. 链接器从左到右按照命令行出现顺序扫描目标文件和静态库

      2. 链接器维护一个目标文件的集合E,一个未解析符号集合U,以及E中已定义的符号集合D,初始状态E、U、D都为空

      3. 对命令行上每个文件f,链接器会判断f是否是一个目标文件还是静态库,如果是目标文件,则f加入到E,f中未定义的符号加入到U中,已定义符号加入到D中,继续下一文件

      4. 如果是静态库,链接器尝试到静态库目标文件中匹配U中未定义的符号,如果m中匹配U中的一个符号,那么m就和上步中文件f一样处理,对每个成员文件都依次处理,直到U、D无变化,不包含在E中的成员文件简单丢弃

      5. 所有输入文件处理完后,如果U中还有符号,则出错,否则链接正常,输出可执行文件

      问题二:静态库顺序

      如下图所示,main.cpp依赖liba.a,liba.a又依赖libb.a,根据静态链接算法,如果用g++ main.cpp liba.a libb.a的顺序能正常链接,因为解析liba.a时未定义符号FunB会加入到上述算法的U中,然后在libb.a中找到定义。

      如果用g++ main.cpp libb.a liba.a的顺序编译,则无法找到FunB的定义,因为根据静态链接算法,在解析libb.a的时候U为空,所以不需要做任何解析,简单抛弃libb.a,但在解析liba.a的时候又发现FunB没有定义,导致U最终不为空,链接错误。

      因此在做静态链接时,需要特别注意库的顺序安排,引用别的库的静态库需要放在前面,碰到链接很多库的时候,可能需要做一些库的调整,从而使依赖关系更清晰。

      ca48b7c6-f62b-11eb-9bcf-12bb97331649.png

      动态链接:

      之前大部分内容都是静态链接相关,但静态链接有很多不足:不利于更新,只要有一个库有变动,都需要重新编译;不利于共享,每个可执行程序都单独保留一份,对内存和磁盘是极大的浪费。

      要生成动态链接库需要用到参数“-shared -fPIC”表示要生成位置无关PIC(Position Independent Code)的共享目标文件。对静态链接,在生成可执行目标文件时整个链接过程就完成了,但要想实现动态链接的效果,就需要把程序按照??椴鸱殖上喽远懒⒌牟糠?。

      在程序运行时将他们链接成一个完整的程序,同时为了实现代码在不同程序间共享要保证代码是和位置无关的(因为共享目标文件在每个程序中被加载的虚拟地址都不一样,要保证它不管被加载在哪都能工作),而为了实现位置无关又依赖一个前提:数据段和代码段的距离总是保持不变。

      由于不管在内存中如何加载一个目标???,数据段和代码段间的距离是不变的,编译器在数据段前面引入了一个全局偏移表GOT(Global Offset Table),被引用的全局变量或者函数在GOT中都有一条记录,同时编译器为GOT中每个条目生成一个重定位记录,因为数据段是可以修改的,动态链接器在加载时会重定位GOT中的每个条目,这样就实现了PIC。

      大体原理基本就这样,但具体实现时,对函数的处理和全局变量有所不同。由于大型程序函数成千上万,而程序很可能只会用到其中的一小部分,因此没必要加载的时候把所有的函数都做重定位,只有在用到的时候才对地址做修订。

      为此编译器引入了过程链接表PLT(Procedure Linkage Table)来实现延时绑定。PLT在代码段中,它指向了GOT中函数对应的地址,第一次调用时候,GOT存放的不是函数的实际地址,而是PLT跳转到GOT代码的后一条指令地址。

      这样第一次通过PLT跳转到GOT,然后通过GOT又调回到PLT的下一条指令,相当于什么也没做,紧接着PLT后面的代码会将动态链接需要的参数入栈,然后调用动态链接器修正GOT中的地址,从这以后,PLT中代码跳转到GOT的地址就是函数真正的地址,从而实现了所谓的延时绑定。

      对共享目标文件而言,有几个需要关注的section:

      ca5aa10c-f62b-11eb-9bcf-12bb97331649.png

      有了以上基础后,我们看一下动态链接的过程:

      1. 装载过程中程序执行会跳转到动态链接器

      2. 动态链接器自举通过GOT、.dynamic信息完成自身的重定位工作

      3. 装载共享目标文件:将可执行文件和链接器本身符号合并入全局符号表,依次广度优先遍历共享目标文件,它们的符号表会不断合并到全局符号表中,如果多个共享对象有相同的符号,则优先载入的共享目标文件会屏蔽掉后面的符号

      4. 重定位和初始化

      问题三:全局符号介入

      动态链接过程中最关键的第3步可以看到,当多个共享目标文件中包含一个相同的符号,那么会导致先被加载的符号占住全局符号表,后续共享目标文件中相同符号被忽略。当我们代码中没有很好的处理命名的话,会导致非常奇怪的错误,幸运的话立刻core dump,不幸的话直到程序运行很久以后才莫名其妙的core dump,甚至永远不会core dump但是结果不正确。

      如下图所示,main.cpp中会用到两个动态库libadd.so,libadd1.so的符号,我们把重点

      ca741d12-f62b-11eb-9bcf-12bb97331649.png

      放在Add函数的处理上,当我们以g++ main.cpp libadd.so libadd1.so编译时,程序输出“Add in add lib”说明Add是用的libadd.so中的符号(add.cpp),当我们以g++ main.cpp libadd1.so libadd.so编译时。

      程序输出“Add in add1 lib”说明Add是用的libadd1.so中的符号,这时候问题就大了,调用方main.cpp中认为Add只有两个参数,而add1.cpp中认为Add有三个参数,程序中如果有这样的代码,可以预见很可能造成巨大的混乱。

      具体符号解析我们可以通过LD_DEBUG=all 。/a.out来观察Add的解析过程,如下图所示:左边是对应libadd.so在编译时放在前面的情况,Add绑定在libadd.so中,右边对应libadd1.so放前面的情况,Add绑定在libadd1.so中。

      caa41b20-f62b-11eb-9bcf-12bb97331649.png

      运行时加载动态库:

      有了动态链接和共享目标文件的加持,Linux提供了一种更加灵活的??榧釉胤绞剑和ü峁ヾlopen,dlsym,dlclose,dlerror几个API,可以实现在运行的时候动态加载???,从而实现插件的功能。

      如下代码演示了动态加载Add函数的过程,add.cpp按照正常编译“g++ -fPIC –shared –o libadd.so add.cpp”成libadd.so,main.cpp通过“g++ main.cpp -ldl”编译为a.out。main.cpp中首先通过dlopen接口取得一个句柄void *handle。

      然后通过dlsym从句柄中查找符号Add,找到后将其转化为Add函数,然后就可以按照正常的函数使用,最后dlclose关闭句柄,期间有任何错误可以通过dlerror来获取。

      caef8b32-f62b-11eb-9bcf-12bb97331649.jpg

      问题四:静态全局变量与动态库导致double free

      在全面了解了动态链接相关知识后,我们来看一个静态全局变量和动态库纠结在一起引发的问题,代码如下,foo.cpp中有一个静态全局对象foo_,foo.cpp会编译成一个libfoo.a,bar.cpp依赖libfoo.a库,它本身会编译成libbar.so,main.cpp既依赖于libfoo.a又依赖libbar.so。

      caf98eac-f62b-11eb-9bcf-12bb97331649.jpg

      编译的makefile如下:

      cb1d0724-f62b-11eb-9bcf-12bb97331649.png

      运行a.out会导致double free的错误。这是由于在一个位置上调用了两次析构函数造成的。之所以会这样是因为链接的时候先链接的静态库,将foo_的符号解析为静态库中的全局变量,当动态链接libbar.so时,由于全局已经有符号foo_,因此根据全局符号介入,动态库中对foo_的引用会指向静态库中版本,导致最后在同一个对象上析构了两次。

      cb2b9a28-f62b-11eb-9bcf-12bb97331649.png

      解决办法如下:

      1. 不使用全局对象

      2. 编译时候调换库的顺序,动态库放在前面,这样全局只会有一个foo_对象

      3. 全部使用动态库

      4. 通过编译器参数来控制符号的可见性。

      总结:

      通过四个编译链接中碰到的问题,基本把编译链接的这些事覆盖了一遍,有了这些基础,在日常工作中应对一般的编译链接问题应该可以做到游刃有余。由于篇幅有限,文章省略了大量的细节,主要集中在大的框架原理性梳理,如果想进一步深挖相关的细节,可参与相关参考文献,以及阅读elf.h相关的头文件。

      转自:https://my.oschina.net/u/4526289/blog/4651990

      编辑:jq

      原文标题:从四个问题透析 Linux 下 C++ 编译&链接

      文章出处:【微信号:gh_3980db2283cd,微信公众号:开关电源芯片】欢迎添加关注!文章转载请注明出处。

      收藏 人收藏
      分享:

      评论

      相关推荐

      英特尔OpenVINO?将全力助力极视角AI推理加速

      在模型开发和部署方面,极市平台集成了最新版本的OpenVINO工具,助力开发者在最小化代码修改的条件....
      的头像 英特尔物联网 发表于 09-22 16:19 ? 155次 阅读
      英特尔OpenVINO?将全力助力极视角AI推理加速

      OpenHarmony HDF HDI的IPC模式具体实现方法和驱动框架能力

      HDI接口概述 回顾之前的文章,HDF 驱动框架的一个重要功能是为系统提供稳定的统一的硬件接口,这样....
      的头像 HarmonyOS官方合作社区 发表于 09-22 14:55 ? 75次 阅读
      OpenHarmony HDF HDI的IPC模式具体实现方法和驱动框架能力

      浅述OpenHarmony HDF 配置管理分析及使用

      HDF配置管理概述 HCS(HDF Configuration Source)是 HDF 驱动框架的....
      的头像 HarmonyOS官方合作社区 发表于 09-22 14:45 ? 42次 阅读
      浅述OpenHarmony HDF 配置管理分析及使用

      如何在在RISCV中使用DSP指令

      1.概述 DSP有相关的专业芯片,能够专门实现计算功能,相比于通用处理器,DSP芯片专门用于计算,可....
      的头像 嵌入式IoT 发表于 09-22 14:28 ? 634次 阅读

      OpenCV新增描述子BEBLID

      在前不久发布的OpenCV4.5中更新了很多新特性: 从4.5版本开始,OpenCV将正式使用Apa....
      的头像 新机器视觉 发表于 09-22 14:16 ? 520次 阅读
      OpenCV新增描述子BEBLID

      浅析离散时间信号与系统

      理论必须结合实际!因此在2018年就有了第六部分的讲解,目的就是让同学们看到学到的理论知识怎么在计算....
      的头像 通信工程师专辑 发表于 09-22 11:30 ? 183次 阅读
      浅析离散时间信号与系统

      51单片机的启动代码究竟里面写了什么

      在我们使用kei c51创建一个51单片机项目时,会有如下图所示的提示: ? keil创建新项目时,....
      的头像 strongerHuang 发表于 09-22 10:15 ? 112次 阅读
      51单片机的启动代码究竟里面写了什么

      程序员如何自己new一个对象

      https://www.ciphermagic.cn/java8-builder.html 程序员经....
      的头像 Android编程精选 发表于 09-22 09:37 ? 429次 阅读

      如何去C++实现接口呢

      接口分为哪几种?分别有什么作用? 如何去C++实现接口呢?...
      发表于 09-22 08:49 ? 0次 阅读

      如何去编写Adafruit_NeoPixel库函数的程序代码

      如何对Adafruit_NeoPixel常用库函数进行初始化? 如何去编写Adafruit_NeoPixel库函数的程序代码?...
      发表于 09-22 08:10 ? 0次 阅读

      如何去编写霍尔开环模式的代码

      霍尔和uvw的对应关系是怎样的? 如何去编写霍尔开环模式的代码? ...
      发表于 09-22 07:40 ? 0次 阅读

      MSK调制解调器的matlab仿真

      继续讲解程序!MSK也能进行相干解调?是的!同样是采用锁相环!先来看看MSK的优点,这是由于下面的这....
      的头像 通信工程师专辑 发表于 09-18 11:43 ? 131次 阅读
      MSK调制解调器的matlab仿真

      介绍3种方法跨时钟域处理方法

      跨时钟域处理是FPGA设计中经常遇到的问题,而如何处理好跨时钟域间的数据,可以说是每个FPGA初学者....
      的头像 FPGA设计论坛 发表于 09-18 11:33 ? 1183次 阅读
      介绍3种方法跨时钟域处理方法

      机智云追踪外卖骑手保温箱硬件开发和项目演示

      01 本章实现功能介绍 追踪外卖骑手的保温箱的GPS定位信息以及外卖箱是否被人打开,以防止骑手在送餐....
      的头像 机智云开发者 发表于 09-18 11:03 ? 133次 阅读

      深入探究Linux系统噪音统计(osnoise tracer)

      在Linux系统中作为一个普通线程是非??啾频?。不仅NMI 、硬中断、软中断可以打断它,甚至其它普通....
      的头像 Linux阅码场 发表于 09-18 10:53 ? 195次 阅读
      深入探究Linux系统噪音统计(osnoise tracer)

      浅析Arduino之看门狗

      如何去编写Arduino看门狗的代码程序?有哪位大神可以分享一下吗...
      发表于 09-18 08:48 ? 0次 阅读

      8031/8051/8751单片机的特点是什么?

      8031/8051/8751单片机的特点是什么? 89S51与89C51的区别是什么? 89S51相对于89C51增加的新功能包括哪些? ...
      发表于 09-18 08:12 ? 0次 阅读

      avr单片机INT0是如何去模拟代码的

      avr单片机INT0是如何去模拟代码的?怎样去编写其代码?...
      发表于 09-18 06:49 ? 0次 阅读

      怎样去配置STM32的独立看门狗

      怎样去配置STM32的独立看门狗?如何去编写其设置代码?...
      发表于 09-18 06:00 ? 0次 阅读

      Solid Sands任命中国核心经销商

      编译器和库测试及认证技术的全球领导者 Solid Sands 宣布在中国任命新的战略供应商。
      的头像 西西 发表于 09-17 14:42 ? 165次 阅读
      Solid Sands任命中国核心经销商

      SDCC编译器和FreeRTOS在C8051F上的开发应用

      SDCC编译器和FreeRTOS在C8051F上的开发应用(肇庆理士电源技术有限公司怎么样)-引言M....
      发表于 09-17 12:53 ? 8次 阅读
      SDCC编译器和FreeRTOS在C8051F上的开发应用

      三菱交流伺服系统伺服故障和报警代码

      伺服故障和报警代码大全,超实用!使用三菱交流伺服系统主要由三个系列:MR-ES、MR-J2S、MR-J3。通常故障情况可由伺服...
      发表于 09-17 08:54 ? 0次 阅读

      如何利用51单片机制作从左至右再从右制作的流水灯呢

      如何利用51单片机制作从左至右再从右制作的流水灯呢?如何编写其代码程序?...
      发表于 09-17 06:52 ? 0次 阅读

      松下伺服报警代码?;すδ?/a>

      《松下伺服故障报警代码分析及处理》由会员分享,可在线阅读,更多相关《松下伺服故障报警代码分析及处理(2页珍藏版)》请在人人文...
      发表于 09-17 06:20 ? 0次 阅读

      ?开发板上玩GTA RISC-V多项移植项目成功运作中

      电子发烧友网报道(文/周凯扬)RISC-V近期再度掀起了不小的热度,苹果招募RISC-V程序员负责其....
      的头像 电子发烧友网 发表于 09-16 11:59 ? 168次 阅读
      ?开发板上玩GTA RISC-V多项移植项目成功运作中

      嵌入式开发中实用的宏打印函数

      宏打印函数在我们的嵌入式开发中,使用printf打印一些信息是一种常用的调试手段。但是,在打印的信息....
      的头像 FPGA之家 发表于 09-16 10:05 ? 135次 阅读
      嵌入式开发中实用的宏打印函数

      使用Kotlin替代Java重构AOSP应用

      两年前,Android 开源项目 (AOSP) 应用团队开始使用 Kotlin 替代 Java 重构....
      的头像 谷歌开发者 发表于 09-16 09:26 ? 128次 阅读
      使用Kotlin替代Java重构AOSP应用

      魔方网表,无代码开发平台NCDP的无冕之王

      NCDP也就是No-code development platform,无代码开发平台,我第一次听到....
      的头像 话说科技 发表于 09-15 14:34 ? 119次 阅读

      C语言中struct的用法有哪些

      定义结构体变量 ? ????下面举一个例子来说明怎样定义结构体变量。 ? ? ? ? ? ? ? ?....
      的头像 STM32嵌入式开发 发表于 09-15 09:41 ? 817次 阅读

      51单片机的启动文件作用是什么

      在我们使用kei c51创建一个51单片机项目时,会有如下图所示的提示: 一般情况下,需要选择“是”....
      的头像 嵌入式ARM 发表于 09-15 09:12 ? 202次 阅读
      51单片机的启动文件作用是什么

      FastThreadLocal快在哪里

      blog.csdn.net/mycs2012/article/details/90898128 1 ....
      的头像 Android编程精选 发表于 09-13 09:17 ? 148次 阅读

      C++基础语法友元类和友元函数

      本期是C++基础语法分享的第五节,今天给大家来分享一下: (1)explicit(显式)关键字; (....
      的头像 C语言编程学习基地 发表于 09-12 09:52 ? 204次 阅读

      一条SQL语句是怎么被执行的

      一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一....
      的头像 Linux爱好者 发表于 09-12 09:44 ? 186次 阅读
      一条SQL语句是怎么被执行的

      如何通过Python脚本实现WIFI密码的暴力破解

      前言 本文将记录学习下如何通过 Python 脚本实现 WIFI 密码的暴力破解,从而实现免费蹭网。....
      的头像 马哥Linux运维 发表于 09-10 17:09 ? 354次 阅读
      如何通过Python脚本实现WIFI密码的暴力破解

      软件工程师为什么要写文档

      在大多数软件工程师对编写、使用和维护代码的抱怨中,一个常见的问题是缺乏高质量的文档。缺乏文档有什么副....
      的头像 Linux阅码场 发表于 09-09 11:26 ? 261次 阅读

      使用deepstream-test的范例代码修改车牌识别与遮盖

      前一篇文章提到使用deepstream-test的范例代码,修改成“车牌识别”与“遮盖(redact....
      的头像 NVIDIA英伟达企业解决方案 发表于 09-09 10:04 ? 203次 阅读
      使用deepstream-test的范例代码修改车牌识别与遮盖

      在STM32G4片内不同存储空间运行的速度差异

      最近有人问起程序在STM32G4片内不同存储空间运行的速度差异。说实在的,这个很难说死或说出个绝对的....
      的头像 茶话MCU 发表于 09-09 09:57 ? 249次 阅读
      在STM32G4片内不同存储空间运行的速度差异

      C++基础语法之volatile、assert()和sizeof()

      volatile volatile int i = 10; volatile 关键字是一种类型修饰符....
      的头像 C语言编程学习基地 发表于 09-09 09:48 ? 185次 阅读

      C++基础语法之inline 内联函数

      上节我们分析了C++基础语法的const,static以及 this 指针,那么这节内容我们来看一下....
      的头像 C语言编程学习基地 发表于 09-09 09:38 ? 162次 阅读

      如何使用C++语法中的volatile

      volatile volatile int i = 10; volatile 关键字是一种类型修饰符....
      的头像 C语言编程学习基地 发表于 09-09 09:38 ? 230次 阅读

      C++语法中的inline内联函数详解

      上节我们分析了C++基础语法的const,static以及 this 指针,那么这节内容我们来看一下....
      的头像 C语言编程学习基地 发表于 09-09 09:33 ? 1065次 阅读

      骑手保温箱追踪及温湿度监测4G设备接入机智云教程

      01 前言 利用机智云提供的通用版App即使不懂云和App开发,也可以在不用写任何代码的情况下,轻松....
      的头像 机智云开发者 发表于 09-09 09:16 ? 159次 阅读
      骑手保温箱追踪及温湿度监测4G设备接入机智云教程

      Kitronik ARCADE游戏手柄实现连连看

      连连看相信大家都玩过,但这个用Kitronik AR CADE游戏手柄来玩连连看的项目你相信是一个高....
      的头像 电子森林 发表于 09-08 11:47 ? 237次 阅读
      Kitronik ARCADE游戏手柄实现连连看

      函数信号发生器的功能及优势

      函数信号发生器是一种信号发生装置,能产生某些特定的周期性时间函数波形 ( 正弦波、方波、三角波、锯齿....
      发表于 09-08 11:35 ? 116次 阅读

      如何把Docker Registry迁移到Harbor

      “要如何将 docker registry 中的镜像迁移至 harbor?本文介绍了四种具体的思路和....
      的头像 马哥Linux运维 发表于 09-07 16:29 ? 311次 阅读
      如何把Docker Registry迁移到Harbor

      最为精简的一个Linux Fork炸弹解析

      转自:http://blog.saymagic.cn/2015/03/25/fork-bomb.ht....
      的头像 Linux爱好者 发表于 09-07 16:12 ? 127次 阅读

      使用Intellij IDEA的一些小技巧

      https://blog.csdn.net/linsongbin1/article/details/....
      的头像 Android编程精选 发表于 09-05 15:03 ? 328次 阅读

      内联汇编代码中的关键语法规则讲解

      一、基本 asm 格式 1. 语法规则 2. test1.c 插入空指令 3. test2.c 操作....
      的头像 硬件攻城狮 发表于 09-05 09:46 ? 235次 阅读

      Spark SQL的概念及查询方式

      一、Spark SQL的概念理解 Spark SQL是spark套件中一个模板,它将数据的计算任务通....
      的头像 数据分析与开发 发表于 09-02 15:44 ? 186次 阅读
      Spark SQL的概念及查询方式

      C语言代码中的extern

      在你的C语言代码中,不知能否看到类似下面的代码: 这好像没有什么问题,你应该还会想:“嗯?是啊,我们....
      的头像 STM32嵌入式开发 发表于 09-02 15:13 ? 223次 阅读
      C语言代码中的extern

      如何比较两种截然不同的编程语言的性能

      自从编程语言诞生以来,人们常常就哪种语言速度最快的问题争论不休。无论是严肃的科学研究,还是深夜酒吧的....
      的头像 嵌入式ARM 发表于 09-02 14:55 ? 221次 阅读

      你们知道指针和引用正确的使用场景吗

      先解决两个疑问 ◆ 指针和引用的不同之处是什么? ◆ 何时用用指针?何时用引用? 指针和引用的不同之....
      的头像 STM32嵌入式开发 发表于 09-02 14:37 ? 188次 阅读
      你们知道指针和引用正确的使用场景吗

      鲲鹏GCC编译器具有代表性的三方面优化特性

      编译器作为重要的基础软件之一,在各个领域都有着非常广泛的应用。比如在嵌入式领域,如何在有限的空间内丰....
      的头像 华为计算 发表于 09-02 10:48 ? 1122次 阅读
      鲲鹏GCC编译器具有代表性的三方面优化特性

      Vivado调用Questa Sim或ModelSim仿真小技巧

      Vivado调用Questa Sim或ModelSim仿真中存在的一些自动化问题的解决方案。 Viv....
      的头像 FPGA之家 发表于 09-02 10:12 ? 219次 阅读
      Vivado调用Questa Sim或ModelSim仿真小技巧
      亚洲色欧美图另类综合_亚洲 自拍 色综合图区av网站_亚洲人成伊人成综合网 乐至县| 广东省| 天水市| 类乌齐县| 胶州市| 五指山市| 开江县| 临猗县| 银川市| 浦江县| 荣昌县| 绥芬河市| 南宁市| 花莲县| 天镇县| 景谷| 高尔夫| 浙江省| 东至县| 新丰县| 凤山市| 密山市| 瑞丽市| 临漳县| 黄山市| 广宗县| 长兴县| 康平县| 宜春市| 岳池县| 北流市| 嘉禾县| 兴城市| 辽中县| 宁阳县| 廊坊市| 长海县| 左云县| 灵璧县| 芦山县| 阳曲县| http://444 http://444 http://444 http://444 http://444 http://444