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

六安网站推广人力资源公司注册条件

六安网站推广,人力资源公司注册条件,fantastico wordpress,小程序开发问题目录 一、程序的翻译环境和执行环境 二、编译和链接 1.翻译环境 2.编译本身也分为几个阶段 3.运行环境 三、预处理 1.预定义符号 2.#define 1.#define定义标识符 2.#define定义宏 3.#define 替换规则 4.#和## 5.带副作用的宏参数 6.宏和函数的对比 7.命名约定 …目录 一、程序的翻译环境和执行环境 二、编译和链接 1.翻译环境 2.编译本身也分为几个阶段 3.运行环境 三、预处理 1.预定义符号 2.#define 1.#define定义标识符 2.#define定义宏 3.#define 替换规则 4.#和## 5.带副作用的宏参数 6.宏和函数的对比 7.命名约定 3.#undef 4.命令行定义 5.条件编译 6.文件包含 1.头文件被包含的方式 2.嵌套文件包含 四、其他预处理指令 五、模拟实现offsetof宏 六、写一个宏可以将一个数的二进制数的奇数位和偶数位交换 总结 一、程序的翻译环境和执行环境 在ANSI C的任何一种实现中存在两个不同的环境。 第1种是翻译环境在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境它用于实际执行代码。 这里我们需要注意的是计算机只能识别二进制指令而这个机器指令就是二进制指令也就是说我们的源代码也就是test.c文件需要先经过翻译环境转变为机器指令。而vs2022就充当了这个翻译环境 当我们点击这个的时候注意应该是生成解决方案而非重新生成这里有误 我们就已经翻译完成生成了可执行程序 而这个翻译环境又可以进行细分细分为编译和链接 而这个编译阶段又可以继续细分分为预编译编译和汇编 二、编译和链接 1.翻译环境 如下图所示在我们写代码的时候每一个.c文件都会单独经过编译器生成.obj的目标文件然后目标文件和链接库加上连接器就会变成可执行程序 我们可以详细看一下这个过程假如说我们已经写好了两个.c文件。那么我们先清理掉解决方案然后点击生成解决方案。就会看到目标文件了 2.编译本身也分为几个阶段 在上面我们也刚刚说过编译也其实分为三个阶段预编译预处理、编译、汇编 我们还是使用上面的代码 对于预编译阶段需要做三件事情如下所示同样对于编译阶段需要将C语言代码翻译成汇编代码其中包括语法分析词法分析语义分析符号汇总。编译最终形成的文件后缀是.s 在汇编阶段又会生成test.o这个目标文件其实就是将汇编指令翻译成了二进制指令并且形成了符号表。  注意我们在编译阶段是会有一个符号汇总的功能这个符号汇总其实就是将所有的全局变量都汇总起来比如g_valmainAdd.......等等 然后形成符号表就是将这些全局变量的符号都对应一个地址 然后就是链接阶段会发生两件事情合并段表和符号表的合并和重定位 首先是合并段表。 合并段表是因为每一个test.o目标文件都有一个自己的段表他们都是一个一个的段但是他们最后只需要生成一个可执行程序也就是一个段表。所以最终就会将这些段表给合并 然后是符号表的合并和重定位如下图所示在会汇编阶段会生成两个符号表在链接阶段会将这些符号表给合并成一个符号表。要使用有效的地址去合并 我们在看一下这个代码 这段代码的主要问题是将函数名给写错了。这样的话就导致编译器在合成符号表的时候Add这个符号的地址还是0x0000,是一个无效的地址从而导致了无法解析的外部符号这个报错  当然其实我们将这个声明外部符号的这个代码给去掉其实也是正确的只是会报一个警告 因为最终形成的符号表还是一样的。 但是如果是声明一个外部的全局变量给去掉的话就不可以了 3.运行环境 程序执行的过程 1. 程序必须载入内存中。在有操作系统的环境中一般这个由操作系统完成。在独立的环境中程序的载入必须由手工安排也可能是通过可执行代码置入只读内存来完成。 2. 程序的执行便开始。接着便调用main函数。 3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈stack存储函数的局部变量和返回地址。程序同时也可以使用静态static内存存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。 4. 终止程序。正常终止main函数也有可能是意外终止 三、预处理 1.预定义符号 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C其值为1否则未定义 __FUNCTION__//打印当前所在函数的函数名 #includestdio.h int main() {printf(%s\n, __FILE__);printf(%d\n, __LINE__);printf(%s\n, __DATE__);printf(%s\n, __TIME__);return 0; } 运行结果为 并且由于__STDC__报错我们可以得知vs2022不遵循ANSI C标准 2.#define 1.#define定义标识符 语法 #define name stuff 例子 #define MAX 100#define reg register为 register这个关键字创建一个简短的名字#define do_forever for(;;)用更形象的符号来替换一种实现#define CASE break;case在写case语句的时候自动把 break写上。#define DEBUG_PRINT printf(file:%s\tline:%d\t \         date:%s\ttime:%s\n ,\         __FILE__,__LINE__ , \         __DATE__,__TIME__ )如果定义的 stuff过长可以分成几行写除了最后一行外每行的后面都加一个反斜杠(续行符)define用于死循环 #includestdio.h #define do_foever for(;;) int main() {do_foever;return 0; } #includestdio.h #define CASE break;case int main() {int n 0;switch (n){case 1:CASE 2:CASE 3:CASE 4:}return 0; } 注意在define定义标识符的时候最好不要加上 2.#define定义宏 #define 机制包括了一个规定允许把参数替换到文本中这种实现通常称为宏macro或定义宏define macro。 下面是宏的申明方式 #define name( parament-list ) stuff 其中的 parament-list 是一个由逗号隔开的符号表它们可能出现在stuff中。 注意 参数列表的左括号必须与name紧邻。 如果两者之间有任何空白存在参数列表就会被解释为stuff的一部分。 如下所示就是一个简单的宏 #includestdio.h #define SQUARE(X) X*X int main() {printf(%d\n, SQUARE(3));return 0; } 但是这样的宏存在一个潜在的问题因为宏只是一个替换在下面的代码中宏被替换为31*31所以结果为7 所以在使用宏的时候不要吝啬括号下面的才是最正确的写法 下面的写法也是正确的 宏也可以传多个参数但是他仅仅只是一个替换 3.#define 替换规则 在程序中扩展#define定义符号和宏时需要涉及几个步骤。 1. 在调用宏时首先对参数进行检查看看是否包含任何由#define定义的符号。如果是它们首先被替换。 2. 替换文本随后被插入到程序中原来文本的位置。对于宏参数名被他们的值所替换。 3. 最后再次对结果文件进行扫描看看它是否包含任何由#define定义的符号。如果是就重复上述处理过程。 注意 1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏不能出现递归。 2. 当预处理器搜索#define定义的符号的时候字符串常量的内容并不被搜索 4.#和## 如何把参数插入到字符串中#和##可以做到这一点 首先我们需要知道这一点 #includestdio.h int main() {printf(hello world\n);printf(hello world\n);return 0; } 对于这个代码运行结果为 也就是说将一个字符串分割成两个一块打印效果也是一样的编译器会自动拼接起来 我们有时候需要写这样的代码 我们发现有大量重复性的东西。因此我们迫不及待的想要将他封装成一个宏 于是我们写成了这样的但是这个代码中的x是字符串里面的是无法被宏识别的 为了达成这个目标我们可以将宏改造一下将原来的字符串给分隔开将x前面加入#这时候#x的作用就是将x转化为x这个字符串这样一来就是printf里面有三个字符串就可以很顺利的拼接起来了  但是呢我们有时候还会去打印浮点数的数据所以我们可以继续改造一下宏 了解了#的作用我们在来了解一下##的作用 ##可以把位于它两边的符号合成一个符号。 它允许宏定义从分离的文本片段创建标识符。 如下代码所示 #includestdio.h #define CAT(x,y) x##y int main() {int helloworld 2023;printf(%d\n, CAT(hello, world));return 0; } 5.带副作用的宏参数 当宏参数在宏的定义中出现超过一次的时候如果参数带有副作用那么你在使用这个宏的时候就可能出现危险导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。 例如 x1        //不带副作用 x        //带副作用 我们来看这样一个例子 #define MAX(x,y) ((x)(y)?(x):(y)) #includestdio.h int main() {int a 4;int b 6;int m MAX(a, b);printf(%d\n, m);printf(%d %d\n, a, b);return 0; } 最终的运行结果是 这是因为MAX这个宏只是一个替换而不是像函数一样先引用在带入 所以这个宏被预处理阶段处理后变为了 int m ((a)(b)?(a):(b)) a一开始是4b一开始是6先引用后也就是结果为b但此时a已经变为了5b已经变为了7然后继续先引用后最终m就是7。a是5b是8 而如果是一个函数的话就不是发生替换而是直接的先引用a和b的值在让a和b都加1 所以结果为m为6a为5b为7 6.宏和函数的对比 宏通常被应用于执行简单的运算 比如在两个数中找出较大的一个#define MAX(a, b) ((a)(b)?(a):(b)) 那为什么不用函数来完成这个任务 原因有二 1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹。 2. 更为重要的是函数的参数必须声明为特定的类型。 所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以用于来比较的类型。宏是类型无关的 宏的缺点当然和函数相比宏也有劣势的地方 1. 每次使用宏的时候一份宏定义的代码将插入到程序中。除非宏比较短否则可能大幅度增加程序的长度。 2. 宏是没法调试的。 3. 宏由于类型无关也就不够严谨。 4. 宏可能会带来运算符优先级的问题导致程容易出现错。 但是宏有时候可以做函数做不到的事情。比如宏的参数可以出现类型但是函数做不到。 如下代码 #includestdio.h #define MALLOC(num,type) (type*)malloc(num*sizeof(type)) int main() {int* p1 (int*)malloc(10 * sizeof(int));int* p2 MALLOC(10, int);return 0; } 宏和函数的对比属性#define定义宏函数代码长度每次使用宏后宏代码都会被插入到程序中。除了非常小的宏之外程序的长度会大幅度增长函数代码只出现于一个地方每次使用这个函数时都调用那个地方的同一份代码执行速度更快存在函数调用和返回的额外开销所以相对慢一些操作符优先级宏参数的求值是在所有周围表达式的上下文环境里除非加上括号否则邻近操作符的优先级可能会产生不可预料的后果所以建议宏在书写的时候多些括号函数参数只在函数调用的时候求值一次它的结果值传递给函数。表达式的求值结果更容易预测带有副作用的参数参数可能被替换到宏体中的多个位置所以带有副作用的参数求值可能会产生不可预料的结果函数参数只在传参的时候求值一次结果更容易控制。参数类型宏的参数与类型无关只要对参数的操作是合法的它就可以使用于任何参数类型函数的参数是与类型有关的如果参数的类型不同就需要不同的函数即使他们执行的任务是相同的调试宏是不方便调试的函数是可以逐语句调试的递归宏是不能递归的 函数是可以递归的 7.命名约定 一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。 那我们平时的一个习惯是把宏名全部大写 函数名不要全部大写 3.#undef 这条指令用于移除一个宏定义   4.命令行定义 许多C 的编译器提供了一种能力允许在命令行中定义符号。用于启动编译过程。 例如当我们根据同一个源文件要编译出一个程序的不同版本的时候这个特性有点用处。假定某个程序中声明了一个某个长度的数组如果机器内存有限我们需要一个很小的数组但是另外一个机器内存大些我们需要一个数组能够大些。 比如说在下面的这段代码中 #include stdio.h int main() {int array[ARRAY_SIZE];int i 0;for (i 0; i ARRAY_SIZE; i){array[i] i;}for (i 0; i ARRAY_SIZE; i){printf(%d , array[i]);}printf(\n);return 0; } linux环境可以使用这个命令行 gcc -D ARRAY_SIZE10 programe.c 5.条件编译 在编译一个程序的时候我们如果要将一条语句一组语句编译或者放弃是很方便的。因为我们有条件编译指令。 比如下面代码意思就是如果定义了PRINT就可以编译printf(hehe)无论PRINT是多少都是可以的如果没有定义PRINT就不可编译printf(hehe) #includestdio.h #define PRINT int main() { #ifdef PRINTprintf(hehe\n); #endifreturn 0; } 下面是常见的条件编译指令 1. #if 常量表达式 #endif //常量表达式由预处理器求值。 如 #define __DEBUG__ 1 #if __DEBUG__ //.. #endif  关于这个指令需要注意的是如果常量表达式的值为0则为假不编译如果为真则编译   2.多分支的条件编译指令 #if 常量表达式 //... #elif 常量表达式 //... #else //... #endif 常量表达式为真则参与编译为假则不编译   3.判断是否被定义的指令 #if defined(symbol) #ifdef symbol #if !defined(symbol) #ifndef symbol     4.嵌套指令 6.文件包含 1.头文件被包含的方式 1#include filename 查找策略先在源文件所在目录下查找如果该头文件未找到编译器就像查找库函数头文件一样在标准位置查找头文件。 如果找不到就提示编译错误 2#include filename.h 查找头文件直接去标准路径下去查找如果找不到就提示编译错误。 这样是不是可以说对于库文件也可以使用 “” 的形式包含 答案是肯定的可以。 但是这样做查找的效率就低些当然这样也不容易区分是库文件还是本地文件了 2.嵌套文件包含 这样最终程序中就会出现两份comm.h的内容。这样就造成了文件内容的重复 我们可以使用条件编译去解决这个问题 #ifndef TEST_1_H #define TEST_1_H int Add(int x, int y); #endif 或者使用这个指令 #pragma once 四、其他预处理指令 #error #pragma #line ...... 这里不再赘述 五、模拟实现offsetof宏 在计算结构体的大小的时候我们常常使用到偏移量而我们正好可以使用一个offsetof这个宏去计算结构体的某个成员的偏移量 如下代码所示 我们其实也是可以模拟实现一下这个宏的。我们的思路是这样的因为结构体的第一个成员的偏移量是0,所以我们可以计算某个结构体成员的地址减去第一个成员的地址就可以得到偏移量了。 为了简单我们可以让结构体的地址就在0地址处然后这样我们只需要计算某个成员的地址就可以得到这个成员的偏移量了 #includestdio.h #includestddef.h #define OFFSETOF(type,member) (size_t)(((type*)0)-member) struct S {char c1;int i;char c2; };int main() {printf(%d\n, OFFSETOF(struct S, c1));printf(%d\n, OFFSETOF(struct S, i));printf(%d\n, OFFSETOF(struct S, c2));}   六、写一个宏可以将一个数的二进制数的奇数位和偶数位交换 我们的思路是按位与和移位操作符结合完成的 首先对于任意一个二进制数如果他按位与1则为原来的数如果按位与0则为0 我们假定二进制数的位数是1--32。 所以我们可以先对一个二进制数的偶数位按位与1奇数位按位与0。即提取处了偶数位然后将他右移就将全部的偶数位移动到了奇数位 然后对一个二进制的奇数位按位与1偶数位按位与0即提取出了全部的奇数位然后将他左移就将全部的奇数位移动到了偶数位置 #includestdio.h #define SWAP(x) (((x0xaaaaaaaa)1)((x0x55555555)1)) int main() {int a 10;a SWAP(a);printf(%d\n, a);return 0; }   总结 本节主要讲解了程序环境和预处理指令 如果对你有帮助的话不要忘记点赞加收藏哦 像获得更多优质内容一定要关注我哦
http://www.w-s-a.com/news/190509/

相关文章:

  • 个人又什么办法做企业网站唐山哪里建轻轨和地铁
  • 手机网站404页面室内设计公司排名前100
  • 做民宿需要和多家网站合作吗创建软件的步骤
  • 网站导航栏设计要求辽宁省住房和城乡建设厅
  • 海外网站平台腾讯营销平台
  • 东道网站建设良品铺子网络营销案例
  • 免费企业查询软件优化模型
  • 兰亭集势的网站平台建设凡科网站免费版怎么做
  • 在网站做推广要钱吗网站根目录是哪个文件夹
  • 网站建设如何弄链接海外vps一键配置WordPress
  • 1个ip可以做几个网站吗动画制作可以自学吗
  • 顺德建设局网站如何搭建网站
  • 精品网站建设费用 干净磐石网络网页制作简单作业
  • 网站建设需要用软件群晖怎样做网站
  • 网站建设公司有哪博客网站建设方案书
  • 服装商城的网站建设宿迁论坛
  • 网站建设服务市场趋势淮南市网站开发的方式
  • 交互设计包含网站设计wordpress和discuz共存
  • 淮阳城乡建设局网站在线网页翻译软件
  • 什么是电商视觉设计郑州seo服务
  • google网站设计原则青海网站建设与管理
  • 简述网站的创建流程广西网站建设定制
  • 唐河网站制作汉中建设工程招标新闻中心
  • 网站过期就可以抢注PHP框架和wordpress
  • 天津做网站得公司克隆网站到wordpress修改
  • 郫县网站建设网站建设报价单及项目收费明细表
  • 商标做网站logo建网站作业
  • 网站顶部展出的大幅广告中建八局第二建设有限公司
  • 公众微信绑定网站帐号优秀中文网页设计
  • 如何做漫画赚钱的网站企业网站管理系统c