当前位置: 首页 > news >正文

cms做门户网站怎么做网站广告联盟

cms做门户网站,怎么做网站广告联盟,开发公司施工管理事业部领导如何同下属协调沟通,wordpress编辑器经典绪论 大家好#xff0c;欢迎来到【程序员的自我修养】专栏。正如其专栏名#xff0c;本专栏主要分享学习《程序员的自我修养——链接、装载与库》的知识点以及结合自己的工作经验以及思考。编译原理相关知识本身就比较有难度#xff0c;我会尽自己最大的努力#xff0c;争取…绪论 大家好欢迎来到【程序员的自我修养】专栏。正如其专栏名本专栏主要分享学习《程序员的自我修养——链接、装载与库》的知识点以及结合自己的工作经验以及思考。编译原理相关知识本身就比较有难度我会尽自己最大的努力争取深入浅出。若你希望与一群志同道合的朋友一起学习也希望加入到我们的学习群中。文末有加入方式。 简介 本文主要介绍我们熟悉的编译四大流程预处理编译汇编链接。因为是我们经常会讨论的话题因此会尽可能详细讨论一下其中的细节。不会太难大家要跟上脚步哦。 本文讨论的示例代码如下 //helloworld.h extern int printf(const char *format, ...);#if 1#define HELLOWORLD hello world 1\n #else#define HELLOWORLD hello world 2\n #endif//helloworld.c #includehelloworld.h int main() {printf(HELLOWORLD);return 0; } 预处理 命令gcc -E helloworld.c -I. -o helloworld.i。其中-I.表示头文件搜索路径。 预处理主要处理哪些源代码文件中的以#开始的预编译指令。比如#define、#include等。主要的规则有 处理所有条件预编译指令比如#if、#ifdef、#elif、#else、#endif等。 将所有的#define删除并展开所有的宏定义。 处理#include预编译指令将被包含的文件插入到该预编译指令的位置可以代码中利用这个特性。注意这个过程是递归进行的。 删除所有的注释//和/* */。这也就是说明详细的代码注释并不会造成目标文件变大。 添加行号和文件名标识比如#2 “hello world.c” 2以便于编译时编译器产生调试用的行号信息、编译错误或编译警告时显示行号。 保留所有的#pragma 编译器指令因为编译器需要使用它们。 helleworld.i 内容如下,请根据上面规则仔细对比一下。 # 1 helloworld.c # 1 built-in # 1 command-line # 31 command-line # 1 /usr/include/stdc-predef.h 1 3 4 # 32 command-line 2 # 1 helloworld.c # 1 ./helloworld.h 1 extern int printf(const char *format, ...); # 2 helloworld.c 2int main() {printf(hello world 1\n);return 0; } 注工作中经常会遇到类似fatal error: xxxxxx.h: No such file or directory错误就是在预编译阶段体现的。 但是预编译阶段不会进行语法校验类似如下的编码并不会提示错误。 编译 编译阶段是整个程序构建的核心部分也是最复杂的部分。它主要对文件进行词法分析、语法分析、语义分析及优化生成的汇编代码文件。 命令gcc -S helloworld.i -o helloworld.s 或者 /usr/lib/gcc/x86_64-linux-gnu/9/cc1 helloworld.i。其中cc1文件的路径不同的操作系统可能不一致。我的虚拟机是ubunt 18.04 版本。 helloworld.s 内容如下 .file helloworld.i.text.section .rodata .LC0:.string hello world 1.text.globl main.type main, function main: .LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6leaq .LC0(%rip), %rdicall putsPLTmovl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc .LFE0:.size main, .-main.ident GCC: (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0.section .note.GNU-stack,,progbits 因为我不是从事自然语言研究方向编译阶段的词法分析、语法分析、语义分析就不再进一步展开。但是其中的优化还是需要略微深入一下。因为编译器优化其中也存在一些坑。 编译器优化 编译器优化的目的优化程序的性能和减少代码的生成。因此有时候提高编译优化等级可以稍微提高程序的执行效率。常见的方式有以下几种 1. 常量传播。能够直接计算出结果的变量将被编译器由直接结果来替代。例如: {int x 10;printf(x %d\n,x); } 优化后 {printf(x %d\n,10); } 2. 常量折叠。如果有可能多个变量的计算可以最终替换成为一个变量的计算。例如 {int a 1;int b 2;int c a b;printf(c %d\n,c); } 优化后 {int c 1 2;printf(c %d\n,c); } 再结合 1.优化方式得 {printf(c %d\n,3); } 3. 复写传播。用一个变量替换两个或多个相同的变量。例如 {int a 1;int b a;printf(b %d\n,b); } 优化后 {int b 1;printf(b %d\n,b); } 4. 公共表达式消除。如果一个表达式已经计算过了并且从先前的计算到现在的E中的变量都没有发生变化那么E的此次出现就成为了公共表达式编译器不需要再次进行计算浪费性能。例如 {int a 1;int b 2;int c (ab) * 2 (ba) * 6; } 优化后: {int a 1;int b 2;int E a b;int c E * 2 E * 6; } 5. 无用代码消除。将永远不能执行到的代码或没有任何意义的代码清除。比如return 之后的代码、未使用的变量、变量给自己赋值等。 6. 数组范围检查消除。Java这种动态类型安全型的那在访问数组时比如array[ ]时Java不会像C/C那样只是纯粹的裸指针访问而是会在运行时访问数组元素前进行一次是否越界检查这将会带来许多开销如果即时编译器能根据数据流分析出变量的取值范围在[0,array.length]之间那么在循环期间就可以把数组的上下边界检查消除以减少不必要的性能损耗。 7. 方法内联。将比较简短的函数或方法直接粘贴到其调用者中以减少函数调用时的开销。例如 int test() {printf(im test\n); } {int a 1;test();int b 2; } 优化后 {int a 1;printf(im test\n);int b 2 } 8. 逃逸分析。逃逸分析的基本原理就是分析对象动态作用域。如果确定一个方法不会逃逸出方法之外那让整个对象在栈上分配内存将会是一个很不错的主意对象所占用的内存空间就可以随栈帧而销毁。在一般应用中不会逃逸的局部对象所占用的比例很大如果能在编译器优化时为其在栈上分配内存空间那大量的对象就会随着方法结束而自动销毁了不用依赖前面讲的GC或者记忆力系统的压力将会小很多。 编译器优化的坑 编译器优化带来的问题有很多场景在网上搜索的话应该有很多实际案例。可以参看这两个案例 不同优化选项对ARM下C语言编译的影响 - 守夜者 - 博客园 关于O2编译选项的一个过优化问题及其解决方法_o2优化-CSDN博客 汇编 汇编过程就是将汇编文件转换为机器可以执行的指令。因此它的内部逻辑比较单一仅需要将汇编语句对照表格一一翻译即可。 命令gcc -c helloworld.s -o helloworld.o或 as helloworld.s -o helloworld.o亦或gcc -c helloworld.c -o helloworld.o。 问题x86环境的虚拟机为什么想反汇编objdump -d *.soarm 平台的动态库失败呢 答我们在工作中经常会遇到一些问题需要查看动态库的信息比如查看依赖库反汇编甚至是gdb调试。但是嵌入式平台的资源有限一般是不会集成相关工具的。常见的方式就是将目标文件copy到本地虚拟环境中进行调试。但是我们往往用objdump,gdb等工具时提示如下失败 其原因.o、.so、可执行程序都已经是二进制文件是对应机器可识别的指令。而嵌入式平台一般都是arm架构开发电脑是x86两套架构识别的指令不一致所以不能解析对方的机器码。若想在虚拟机中调试其他平台的动态库或可执行程序需要使用交叉编译工具链中的对应工具。 链接 链接才是我们整个过程中最为复杂的过程这个阶段做了很多很多事情。因此出现异常的概率也高。大致可以分为两个范围。 静态链接过程。主要指生成动态库或可执行文件的过程。比如工作中我们经常遇到工程编译提示错误大部分都是在链接阶段提示的。 动态链接过程。就是程序运行过程。我们知道若程序依赖动态库那么程序在真正运行前需要找到对应的动态库并加载。常见的问题就是找不到对应动态库或对应符号找不到有时会出现匪夷所思的现象。有兴趣的可以了解我遇到的一个案例坑惨啦!!!——符号冲突案例分析-CSDN博客 为了不打击大家的信心本篇文章不会再进一步展开讨论。后续我会慢慢揭开链接过程的面纱其实也就那么一回事。 不过大家可以先思考以下几个问题尝试猜测链接做了哪些事情。 一、helloworld.o 中引用了printf方法程序运行时它是怎么知道符号地址的呢该跳转到哪里继续执行程序呢 二、程序正真运行前需要做哪些事情呢动态库加载、符号重定位其大致逻辑如何呢 技巧分享 本章节主要和大家分享一下我工作中用到的小技巧也欢迎大家在评论区补充我会更新到文章中。 一、利用#include更好的维护代码。 我们知道#include是预处理过程中将文件内容加载到对应位置的操作。那么我们可以将一些可变的信息保存在文件中那么就不会更改我们的.c 源文件。 比如做过单片机LCD显示的朋友肯定知道每一张照片信息其实就是一个超大的整型数组。常见的方式如下 //picture.c int picture_data[] {*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*, } 每当图片信息变化时则需要更新picture_data数组里面的信息也就要更改picture.c源文件。我觉得这样并不友好。优化如下 //picture_data.h {*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*, }//picture_data.c int picture_data[] #includepicture.h ; 这样每次图片更新仅需要替换picture_data.h文件即可。 二、如何快速确认#if、#ifdef、#elif、#else、#endif 的实际分支。 在大型的工程项目中随着需求的迭代代码分支也比较多经常会用到类似if、#ifdef、#elif、#else、#endif 等分支控制方式。这就导致我们有时不知道实际代码编译的是哪一部分。我的快速定位的方式就是在对应的分支中加上乱码。比如 亦或者加上错误提示 再多问一下大家知道上面两种方式的不同吗提示一下不同的阶段。 总结 以上便是本文的内容我们回顾了编译的四大过程预处理编译汇编链接。以及每个过程大致做了哪些事可能会遇到的问题也知道了编译器优化带来的可能弊端因此编译器的优化选项我们要慎重如果对效率要求不高建议开启O1即可链接阶段是一大难点本文没有展开叙述但是通过案例和抛出的问题我相信大家对链接肯定产生了莫大的兴趣。请别着急关注专栏后续一定会娓娓道来。 有任何相关问题欢迎留言讨论我会尽快回复。 若您正遇到相关问题苦于没有一群志同道合的朋友交流探讨。也欢迎加入我们的讨论组群。可通过私聊我我会尽快拉你进群。
http://www.dnsts.com.cn/news/69976.html

相关文章:

  • 北京网站建设公司黄页济南招聘网最新招聘
  • 做游戏网站用什么系统做海门城乡建设管理局网站
  • 网站建设专业平台排名软件
  • 网站开发与怎么做带数据库的网站
  • 贵州网站设计邢台专业做网站推广
  • 网站免费正能量直播怎么做有声小说网站播音员
  • 中文建网站邢台网约车
  • 徐州云龙区建设局网站温州做模具的网站
  • 中型企业网站建设什么网站可以免费做兼职
  • 国外wordpress主题站房地产信息查询网
  • 适合权重小的网站做的专题图片制作怎么弄
  • 网站建设网页设计服务wordpress 获取tag
  • 秦皇岛建设网站官网个体户怎么注册商标
  • 地方o2o同城网站源码四川网站设计
  • 网站开发德菁电脑软件开发工具
  • 山西建设集团网站自己如何开网店
  • 网站不备案可以么宝塔window怎么做网站
  • 福州市住房和城乡建设网站网站推广的作用是什么
  • 网站开发 保修期大象影视传媒制作公司
  • 网站开发完以后交付源代码比分网站仿站建设
  • 规划网站需要几个步骤网站主页设计代码
  • 网站显示危险网站要怎么做苏州网站建设布局
  • 本地用织梦做网站广州企业网站制作
  • 品牌排行榜哪个网站更权威申请域名费用
  • 公司网站现状成都网站建设外包业务
  • 做神马网站快速网站怎么开通微信支付
  • 网站无搜索结果页面怎么做网络工程师考试时间
  • 南通网站定制搭建自己网站建设的流程是什么
  • 都有什么公司需要网站建设做盗链电影网站怎么样
  • 信阳建设监理协会网站机关网站源码