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

专业的响应式网站建设网站开发人员工工资

专业的响应式网站建设,网站开发人员工工资,中国住房和城乡建设部查询网站,哪些网站做任务可以赚钱的目录 一、程序的编译环境 二、运行环境 三、预编译详解 3.1预定义符号 3.2.1 #define 定义标识符 3.2.2 #define 定义宏 3.2.3#define替换规则 3.2.4 #和## 2)##的作用#xff1a; 3.2.5宏和函数的对比 3.2.6宏的命名约定和#undef指令 一、命名约定#xff1a; …目录 一、程序的编译环境 二、运行环境 三、预编译详解 3.1预定义符号 3.2.1 #define 定义标识符 3.2.2  #define 定义宏 3.2.3#define替换规则 3.2.4 #和## 2)##的作用 3.2.5宏和函数的对比 3.2.6宏的命名约定和#undef指令 一、命名约定  二、#undef 3.3条件编译 3.4文件包含 1本地文件包含 2Linux环境的标准头文件的路径 3库文件包含 在学习预编译之前我们有必要先大致了解一下一个程序从开始到结束的过程这样有利于我们加深对程序运行的理解。 一、程序的编译环境 在ANSI C的任意一种实现中存在两个不同的环境。 1.翻译环境  在这个环境中源代码转换为可执行的机器指令。把C语言的代码转化为二进制指令  即可执行程序 2.执行环境  它用于执行实际的代码。执行二进制代码 二、运行环境 1.程序必须载入内存当中再有操作系统的环境中一般这个由操作系统完成。在独立的环境中程序的载入必须由手工安排 也可能是通过可执行代码置入只读内存来完成。 2.程序执行便开始随后调用main函数。 3.开始执行程序代码这时程序员将使用一个运行时堆栈(Stack即函数栈帧)存储函数的局部变量和返回地址。程序同时也可以使用静态static)内存存储与静态内存的变量在程序的整个执行过程中一直保留他们的值。 4.终止程序正常终止main函数也肯能是意外终止。 如图所示多个源文件.c文件单独经过编译器进行编译生成目标文件obj文件这个过程为编译。多个目标文件与库函数中的链接库共同在链接器的作用下生成可执行程序exe文件这个过程为链接过程。 如图所示翻译环境 可以继续细分为编译和链接编译还可以继续细分为预处理编译汇编其中在翻译过程中首先进行的是预处理过程在预处理过程中首先会把test.c源文件中的注释删除以及#include头文件包含和#define 符号的替换在之后就会生成test.i文件为编译阶段做准备。 到了编译阶段会进行对test.i文件的解读包含 语法分析词法分析语义分析符号汇总其中符号汇总为下阶段的符号表做准备最后将test.i文件转化为汇编指令文件即test.s文件。 接下来到了汇编阶段在linux环境下test.s文件会被转化为存放二进制test.o的目标文件文件在win下转化为test.obj文件这些二进制文件是以elflinux环境下文件格式存放的elf文件又把二进制文件分为不同的数据段最后在把前面编译的符号的汇总整理成符号表。 编译阶段结束接下来就是链接阶段了链接阶段首先把不同文件的相同段进行合并形成新的数据段表其次在对不同文件的的相同符号进行合并合并为新的符号表值得注意的是在形成符号表的过程总中有些单独文件的虚拟地址会被分配有效地址重定位加入新的符号表。 以上就是程序从开始到结束的大致过程了如果想了解更多的编译链接过程可以参考《程序员的自我修养》。 三、预编译详解 3.1预定义符号 __FILE__    //进行编译的源文件 __LINE__    //文件当前的行号 __DATE__    //文件被编译的日期 __TIME__    //文件被编译的时间 __STDC__    //如果编译器遵循ANSI C其值为1否则未定义 我们不妨打印出来这些预定义符号 #includestdio.hint main() {printf(%s\n,__FILE__);printf(%d\n,__LINE__);printf(%s\n,__DATE__);printf(%s\n,__TIME__);printf(%d\n,__STDC__);return 0; } 可以发现打印出来的结果跟预期一样由__STDC__的结果看dev C遵循ANSIC。 3.2.1 #define 定义标识符 用法#define name stuff 在有了#define预处理命令后我们可以进一步对上面的预定义符号进行更加方便的表示在main函数外使用#define名字要替换的内容就可以在全局范围内使用这个宏例如下面的代码 #includestdio.h#define DEBUG_PRINT printf(file:%s\tline:%d\tdata:%s\t \time:%s\n,__FILE__, __LINE__, \__DATE__, __TIME__) /*换行加\(转义字符转义了回车)为了消除define的影响*/int main() {DEBUG_PRINT; return 0; } 值得注意的是在C语言中#define预处理指令使用了printf函数只能处理单行内容如果想换行必须在每一行的末尾加上\转义字符才能把换行表示成字符来处理否则会报错。  代码执行结果如下 注意在#define后面最好是不要加上分号因为这样可能会造成歧义。 3.2.2  #define 定义宏 #define 机制包括了了一个规定允许把参数替换到文本当中这种实现通常称为宏(macro) 或者定义宏(define macro)。 宏的申明方式:#define name(parament-list) stuff , 其中parament-list是一个由逗号隔开的符号表他们可能出现在stuff中。         注意1.参数列表的左括号必须与name紧邻。2.如果两者之间有任何空白的存在参数列表就会被解释为stuff中的一部分。 看看下面的例子 #define Add(x,y) (xy)int main() {int a 3;int b 7;int c Add(a,b);printf(“%d”,c);return 0; } 注意:这里替换文本的时候参数x,y要格外注意#define是整体替换不会给你添加括号例如(还是上面的例子只不过c变了):         c a * b * Add的时候其实是c a * b * a b所以在复杂宏当中各个参数最好加上括号。 3.2.3#define替换规则 在程序中扩展#define定义符号和宏时 需要涉及这几个步骤 1.在调用宏时首先对参数进行检查看看是否包含任何由#define定义的符号如果是他们首先被替换。         2.替换文本随后被插入到程序中原来文本的位置。对于宏参数名被他们的值所替换。         3.最后再次对结果文件进行扫描看着他是否包含任何由#define 定义的符号如果是就重复上述处理过程。 注意         1.宏参数和#define定义中可以出现其他的#define定义符号但是对于宏不能出现递归。         2.当预处理器搜索#define定义的符号的时候字符串常量的内容并不被搜索。 3.2.4 #和## 1)#的作用 思考这样一个问题如何把参数插入到字符串当中呢 #includestdio.hint main() {int a 10;printf(The value a is %d\n,a);int b 20;printf(The value b is %d\n,b);return 0;} 例如我想要The value a is ...  The value b is...  The value c is...这样类似的输出如果用printf函数少量的字符串CV一下就行但是 如果需要特别多行类似的语句printf函数是做不到的。那么宏做不做得到呢其实宏有种方法是可以做到的就是符号#。 #includestdio.h#define PRINT(n) printf(The value #n is %d\n,n)int main() {int a 10;PRINT(a);int b 20;PRINT(b);return 0;}  把一个字符串从要替换的字符串的中点分成两个字符串除了想要替换的字符串以外另外两个字符串都需要完整的在要替换的文本前加上#这样就可以轻松替换了。 实质上这个宏其实是PRINT(n) printf(The value n is %d\n,n)相当于在#后面部分的字符串改变后又被重新拼接起来形成一个新的完整的字符串。 我们来思考另一个问题如果两个参数的类型不一样如何能用一条语句实现呢比如我想要一个a为int 型b 为float型这样看来printf函数还是不能实现难道宏还可以吗没错宏就是能一劳永逸我们来看下面代码: #includestdio.h#define PRINT(n,format) printf(The value #n is format \n,n)int main() {int a 10;PRINT(a,%d);float b 10.5f;PRINT(b,%f);return 0; }在前面代码的基础上加上了format类型格式把输出控制符%d,%f...用format代替且format需要单独的一个双引号这样在传参的时候只需要传数据类型和输出控制符就可以实现把不同的输出控制符插入到字符串当中怎么样是不是很方便呢 2)##的作用 ##可以把位于它两边的符号合成一个符号它允许宏定义从分离的文本片段创建标识符。  这句话是什么意思呢我们先来看一下下面的代码 #includestdio.h#define CRT(x,y) x##yint main() {int DataSum 100;printf(%d\n, CRT(Data, Sum));return 0; } 结果为发现了打印的值和DataSum的值相同这也就说明了这个宏能将两个片段合并成一个片段这就是##的作用了。  3.2.5宏和函数的对比 宏通常被应用于执行简单的运算就像计算两个数的加法 #includestdio.h#define Add(x,y) (x y);int Add_Fun(int x, int y) {return x y; }int main() {int x 3, y 2;printf(%d\n, Add_Fun(x, y));int c Add(x, y);printf(%d,c);return 0; } 为什么不用函数来完成这个任务呢 原因有两点 1.用于调用函数和函数返回的代码可能比实际执行这个小型计算机工作所需要的时间更多所以宏比函数在程序的规模和速度方面更胜一筹。 2.更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用反之这个宏可以适用于整形长整型浮点型等可以用于来比较的类型。宏与类型无关。  宏的缺点 1.每次使用宏的时候一份宏定义的代码将插入到程序中。除非宏比较短否则大幅度增加程序长度。 2.宏是没办法调试的。 3.宏由于类型无关也就不够严谨。 4.宏有时候会带来运算符优先级问题导致程序发生错误。 所以根据不同的情况进行选择使用宏还是函数有各自的优势。 宏和函数的对比 属         性                 #define定义宏          函数              代         码         长         度 每次使用时宏代码都会被插入到程序中。除了非常小的宏之外程序长度会大幅组增长。 函数代码只出现于一个地方每 次使用这个函数时都调用那个 地方的同一份代码         执         行         速         度 更快 存在函数的调用和返回的额外开 销所以相对慢一些         操         作         符         优         先         级 宏参数的求值是在所有周围表达式的上下文环境里 除非加上括号否则邻近操作符的优先级可能会产生 不可预料的后果所以建议宏在书写的时候多些括 号。 函数参数只在函数调用的时候求 值一次它的结果值传递给函 数。表达式的求值结果更容易预 测。         带         有         副         作         用         的         参         数 参数可能被替换到宏体中的多个位置所以带有副作 用的参数求值可能会产生不可预料的结果。 函数参数只在传参的时候求值一 次结果更容易控制。         参         数         类         型 宏的参数与类型无关只要对参数的操作是合法的 它就可以使用于任何参数类型。 函数的参数是与类型有关的如 果参数的类型不同就需要不同 的函数即使他们执行的任务是 相同的。         调         试 宏是不方便调试的 函数是可以逐语句调试的。         递         归 宏是不能递归的 函数是可以递归的 3.2.6宏的命名约定和#undef指令 一、命名约定  一般来说函数与宏的使用语法很相似所以语言本身没办法帮我们区分二者大部分的C程序员都遵循一个默认的习惯 1、把宏名全部大写。 2、函数名不要全部大写。 二、#undef 这条语句用于移除一个宏定义。 #includestdio.h#define MAX(x,y) ((x) (y))int main() {int a 5, b 6;printf(%3d,MAX(a, b)); #undef MAX//printf(%3d, MAX(a, b));return 0; } 在使用undef后再次打印时会发现 已经将这个宏给删除了。 3.3条件编译 在编译一条语句的时候我们如果要将一条语句一组语句编译或者放弃是很方便的。因为我们有条件编译指令。 那么条件编译指令有哪些 #if 常量表达式         //...         #elif 常量表达式         //...         #else         //...         #endif         多个分支条件编译也可以只有         #if ...#endif          if defined()         if !defined()         或者         #ifdef ...         #ifndef ...         判断某个宏是否被定义与宏的值         无关只与宏是否被定义有关。 其中条件编译语句在程序中只能存在一次因为在预编译阶段就会进行宏替换所以在程序中只能起一次的作用。 3.4文件包含 我们不论写C语言还是写C语言我们都会用到头文件像stdio.hstdlib.hstring.h等其实#include指令可以使另外一个文件被编译。就像他实际出现于#include指令的地方一样。 这种替换的方式很简单 预处理器先删除这条指令并用包含文件的内容替换。 这样一个源文件被包含10次那就实际被编译10次。 1本地文件包含 #includefilename 查找方式 先在源文件所在目录下查找如果该头文件未找到编译器就像查找库函数头文件一样在标准位置查找头文件。 如果找不到就提示编译错误。 2Linux环境的标准头文件的路径 为/usr/include 3库文件包含 #includefilename.h 查找方法 查找头文件直接去标准路径下去查找如果找不到就提示编译错误。 这样是不是可以说对于库文件也可以使用 “” 的形式包含 答案是肯定的虽然可以。 但是这样做查找的效率就低些当然这样也不容易区分是库文件还是本地文件了。
http://www.zqtcl.cn/news/716237/

相关文章:

  • 手机站是什么意思免费建论坛
  • 网站开发学习路线专用车网站建设哪家好
  • 贵阳网站建设端觉wordpress gif 点击播放
  • 苏州产品推广公司厦门关键词seo
  • 建设内网网站流程凡客诚品现在还有吗
  • 西安网站公司免费云手机无限时间版
  • 网站建设与管理案例教程ipad可以做网站吗
  • 济南网站建设模板python网站开发用什么软件
  • 北京品牌网站建设阿里巴巴logo图片
  • 做宣传册从哪个网站找素材中文在线っと好きだっ
  • 国际物流东莞网站建设wap是什么意思的缩写
  • 传奇官网百度seo营销网站
  • 如何在导航网站上做链接上海建筑设计研究院
  • 微信营销软件网站建设推广链接
  • 美的集团网站建设方案书广汉做网站
  • 个人博客网站实验报告商标购买网站
  • 2020给个免费网站好人有好报做购物微信网站
  • 做淘宝客网站挣钱济南百度竞价代运营
  • 国外网站404错误页网站地址搜索
  • 做 暧视频在线观看网站北京安卓app开发公司
  • h5哪个网站可以做惠州+企业网站建设
  • 网站运营知识哪个网站可以做免费商业推广
  • 电脑做网站怎么解析域名河南郑州静默管理
  • 项目网站制作冯提莫斗鱼前在哪个网站做直播
  • 网站建设 思路wordpress 访问记录插件
  • 网站建设diyseo课程培训班费用
  • 舞蹈培训东莞网站建设做直播网站
  • app建设网站公司网站制作预算
  • 移动端网站如何开发市辖区郑州网站建设
  • 山东省双体系建设网站wordpress 帮助 主题