北京撒网站设计git网站开发

news/2025/10/6 22:39:15/文章来源:
北京撒网站设计,git网站开发,设计师个人作品集模板,一个简单的html网页文章目录 目录1. 程序的翻译环境和执行环境2. 详解编译链接2.1 翻译环境2.2 编译本身也分为几个阶段2.3 运行环境 3. 预处理详解3.1 预定义符号3.2 #define3.2.1 #define 定义标识符3.2.2 #define 定义宏3.2.3 #define 替换规则3.2.4 #和##3.2.5 带副作用的宏参数3.2.6 宏和函数… 文章目录 目录1. 程序的翻译环境和执行环境2. 详解编译链接2.1 翻译环境2.2 编译本身也分为几个阶段2.3 运行环境 3. 预处理详解3.1 预定义符号3.2 #define3.2.1 #define 定义标识符3.2.2 #define 定义宏3.2.3 #define 替换规则3.2.4 #和##3.2.5 带副作用的宏参数3.2.6 宏和函数对比 目录 程序的翻译环境程序的执行环境详解C语言程序的编译链接预定义符号介绍预处理指令 #define宏和函数的对比预处理操作符#和##的介绍命令定义预处理指令 #include预处理指令 #undef条件编译 1. 程序的翻译环境和执行环境 在ANSI C的任何一种实现中存在两个不同的环境。 第1种是翻译环境在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境它用于实际执行代码。 计算机是能够执行二进制指令的但是我们写出的C语言代码是文本信息计算机不能直接理解。 翻译环境C语言代码 — 二进制的指令放在可执行程序中 执行环境执行二进制的代码 2. 详解编译链接 2.1 翻译环境 组成一个程序的每个源文件通过编译过程分别转换成目标代码object code。每个目标文件由链接器linker捆绑在一起形成一个单一而完整的可执行程序。链接器同时也会引入标准C函数库中任何被该程序所用到的函数而且它可以搜索程序员个人的程序库将其需要的函数也链接到程序中。 我们也可以通过代码来观察 //add.cint Add(int x, int y) {return x y; }//test.c#include stdio.hextern int Add(int, int);int main() {int a 10;int b 20;int c Add(a, b);printf(%d\n, c);return 0; }2.2 编译本身也分为几个阶段 预处理阶段 编译阶段 汇编阶段 解释一下符号汇总、符号表 在这个目标文件里确实能看到一些符号都是全局的 接下来我们用两个文件来举例子 这有什么用呢 如果没有定义Add函数那么在链接的时候就定位不到这个函数就会发生链接错误生成不了可执行程序。 2.3 运行环境 程序执行的过程 程序必须载入内存中。在有操作系统的环境中一般这个由操作系统完成在独立的环境中程序的载入必须由手工安排也可能是通过可执行代码置入只读内存来完成。程序的执行便开始接着便调用main函数。开始执行程序代码。这个时候程序将使用一个运行时堆栈stack函数栈帧存储函数的局部变量和返回地址。程序同时也可以使用静态static内存存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。终止程序。正常终止main函数也有可能是意外终止。 3. 预处理详解 3.1 预定义符号 __FILE__ -- 进行编译的源文件 __LINE__ -- 文件当前的行号 __DATE__ -- 文件被编译的日期 __TIME__ -- 文件被编译的时间 __STDC__ -- 如果编译器遵循ANSI C其值为1否则未定义 这些预定义符号都是语言内置的。 举个例子 #include stdio.hint main() {printf(%s\n, __FILE__);printf(%d\n, __LINE__);printf(%s\n, __DATE__);printf(%s\n, __TIME__);//printf(%d\n, __STDC__);//当前VS是不支持ANSI Creturn 0; }对代码进行预处理之后 3.2 #define 3.2.1 #define 定义标识符 语法 #define name stuff #include stdio.h#define M 100 #define STR abc #define FOR for(;;) #define reg register//为 register这个关键字创建一个简短的名字int main() {printf(%d\n, M);printf(%s\n, STR);FOR;//死循环return 0; }预处理之后 int main() {int d 0;switch (d){case 1:break;case 2:break;case 3:break;}return 0; }以上代码还可以这样写 #define CASE break;caseint main() {int d 0;switch (d){case 1:CASE 2:CASE 3:}return 0; }#include stdio.h//如果定义的 stuff 过长可以分成几行写除了最后一行外每行的后面都加一个反斜杠(续行符)。 #define DEBUG_PRINT printf(file:%s\tline:%d\tdate:%s\t\time:%s\n , __FILE__, __LINE__,\__DATE__, __TIME__)int main() {DEBUG_PRINT;return 0; }提问 在define定义标识符的时候要不要在最后加上 ; 比如 #define M 100;int main() {int a M;return 0; }这样的代码看上去是没有问题的但是这样写是非常容易出错的 #define M 100;int main() {int a 0;int b 0;if (a 5)b M;elseb -1;return 0; }if 语句后面默认只能跟一条语句这里再加上一个 ; 就变成了两条语句这就意味着下面的 else 不知道和谁匹配了。 因此建议不要加上 ; ,这样容易导致问题。 3.2.2 #define 定义宏 #define 机制包括了一个规定允许把参数替换到文本中这种实现通常称为宏macro或定义宏define macro。 下面是宏的申明方式 #define name( parament-list ) stuff 其中的 parament-list 是一个由逗号隔开的符号表它们可能出现在stuff中。 注意 参数列表的左括号必须与name紧邻如果两者之间有任何空白存在参数列表就会被解释为stuff的一部分。 #include stdio.h#define MAX(x,y) ((x)(y)?(x):(y)) int main() {int a 2;int b -2;int c MAX(a, b);printf(c%d\n, c);return 0; }预处理之后 提示 所有用于对数值表达式进行求值的宏定义都应该用这种方式加上括号避免在使用宏时由于参数中的操作符或邻近操作符之间操作符的优先级而导致不可预料的相互作用。 应该这样写 #includestdio.h#define SQUARE(x) ((x) * (x))int main() {int a 3;int r SQUARE(a 2);printf(r%d\n, r);return 0; }应该这样写 #includestdio.h#define DOUBLE(x) ((x) (x))int main() {int a 3;int r 10 * DOUBLE(a);printf(r%d\n, r);return 0; }3.2.3 #define 替换规则 在程序中扩展#define定义符号和宏时需要涉及几个步骤。 在调用宏时首先对参数进行检查看看是否包含任何由#define定义的符号。如果是它们首先被替换。替换文本随后被插入到程序中原来文本的位置。对于宏参数名被他们的值所替换。最后再次对结果文件进行扫描看看它是否包含任何由#define定义的符号。如果是就重复上述处理过程。 注意 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏不能出现递归。当预处理器搜索#define定义的符号的时候字符串常量的内容并不被搜索。 #includestdio.h#define M 3int main() {printf(M%d\n, M);//M3return 0; }3.2.4 #和## 如何把参数插入到字符串中 首先我们看看这样的代码 #include stdio.hint main() {printf(hello world\n);//hello worldprintf(hello world\n);//hello worldreturn 0; }我们发现字符串是有自动连接的特点的。 我们想实现这样一个功能 #include stdio.hint main() {int a 20;printf(the value of a is %d\n, a);int b 15;printf(the value of b is %d\n, b);float f 4.5f;printf(the value of f is %f\n, f);return 0; }我们可以用宏来实现函数做不到 #include stdio.h#define PRINT(n, format) printf(the value of #n is format\n, n)int main() {int a 20;//printf(the value of a is %d\n, a);PRINT(a, %d);int b 15;//printf(the value of b is %d\n, b);PRINT(b,%d);float f 4.5f;//printf(the value of f is %f\n, f);PRINT(f, %f);return 0; }代码中的 #n 会预处理为 “n” ##的作用 ##可以把位于它两边的符号合成一个符号它允许宏定义从分离的文本片段创建标识符。 #include stdio.h#define CAT(x,y) x##yint main() {int Class110 2024;printf(%d\n, CAT(Class, 110));//2024printf(%d\n, Class110);//2024return 0; }3.2.5 带副作用的宏参数 当宏参数在宏的定义中出现超过一次的时候如果参数带有副作用那么你在使用这个宏的时候就可能出现危险导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。 int main() {int a 10;//int b a 1;//b11, a10int b a;//b11, a11return 0; }x1;//不带副作用 x;//带有副作用 MAX宏可以证明具有副作用的参数所引起的问题 #include stdio.h#define MAX(x, y) ((x)(y)?(x):(y))int main() {int a 5;int b 6;int c MAX(a, b);//int c ((a) (b) ? (a) : (b));// 5 6 7//c7//b8//a6printf(c %d\n, c);printf(a %d\n, a);printf(b %d\n, b);return 0; }3.2.6 宏和函数对比 #include stdio.h//1 #define MAX(x, y) ((x)(y)?(x):(y))//2 int Max(int x, int y) {return (x y ? x : y); }int main() {int a 5;int b 6;int c MAX(a, b);//int c Max(a, b);printf(c %d\n, c);printf(a %d\n, a);printf(b %d\n, b);return 0; }宏通常被应用于执行简单的运算比如在两个数中找出较大的一个。 那为什么不用函数来完成这个任务 原因有二 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多所以宏比函数在程序的规模和速度方面更胜一筹。 更为重要的是函数的参数必须声明为特定的类型所以函数只能在类型合适的表达式上使用反之这个宏则可以适用于整形、长整型、浮点型等可以用 来比较的类型。宏是类型无关的。 宏的缺点 当然和函数相比宏也有劣势的地方 每次使用宏的时候一份宏定义的代码将插入到程序中。除非宏比较短否则可能大幅度增加程序的长度。(代码如果特别长那么编译的压力就会很大因为在编译的时候会对代码做各种各样的处理如语法分析、词法分析等等)宏是没法调试的。宏由于类型无关也就不够严谨。宏可能会带来运算符优先级的问题导致程容易出现错。 宏有时候可以做函数做不到的事情。比如宏的参数可以出现类型但是函数做不到。 #define MALLOC(num, type) (type*)malloc(num*sizeof(type))int main() {int* p (int*)malloc(126 * sizeof(int));//malloc(126, int);//errint* p MALLOC(126, int);//int* p (int*)malloc(126 * sizeof(int));return 0; }宏和函数的一个对比 对于第三点的一个例子 //1 #define MAX(x, y) ((x)(y)?(x):(y))//2 int Max(int x, int y) { //5 6return (x y ? x : y); }int main() {int c MAX(2 3, 6);//int c ((23)(6)?(23):(6))c Max(2 3, 6);return 0; }补充 宏有自己的优势当然也有劣势 函数也有自己的优势也有劣势 能不能有一个函数既具有函数的好也具有宏的好呢 inline — 内联 内联函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/929778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

完整教程:Postgresql常规SQL语句操作

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

酷派Cool20/20S/30/40手机安装Play商店-谷歌三件套-GMS方式

酷派Cool20/20S/30/40手机安装Play商店-谷歌三件套-GMS方式pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consol…

拼多多电商网站建设学校网站建设方案设计

使用 services 指令,请先安装 brew tap gapple/services 安装完成后使用 brew services start mysql

关于网络编辑作业做网站栏目新闻的ppt免费网站软件大全

今年有哪些成功的发行版发布呢? 让我重点介绍最好的几个。 这些发行版在 2023 年引起了人们的关注! 每年我们都会推出一些令人兴奋的新发行版,它们尝试以不同的方式工作,或者提供一些有意义的东西,而不仅仅是“又一个发…

【sa-token】 sa-token非 web 上下文无法获取 HttpServletRequest - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Cloudflare洛杉矶数据中心维护通知:技术架构与影响解析

本文详细介绍了Cloudflare将于2025年10月8日在洛杉矶数据中心进行的计划性维护,包括维护时间窗口、流量重路由机制、潜在延迟影响,以及针对PNI/CNI客户的重要技术建议和通知订阅方式。维护概览 计划维护时间:2025年…

正规的手机网站建设小程序官方平台

等到花都谢了,你怎么还不开机?这电脑开机真是离奇的慢,有心将它换了,奈何兜里空空。凑合着用又无法忍受这种煎熬。其实你只需要用鼠标点几下就可以不用等待这漫长的开机过程了。高铁,飞机,网络,…

友点企业网站管理系统模板保定市清苑区网站建设

看看如果设定了Rollover中某个状态的效果,则 CA.在动画面板上制作的动画适用于所有的Rollover状态B.动画不能应用在Rollover状态上C.在动画面板上制作的动画仅适用于当前的Rollover状态D.同一动画不能赋予多个Rollover…

沧州建设银行招聘网站电子商务网站建设中

参考 一个叫做Version,一个叫做Build,(version是版本号,build是打正式包每次Archive时的都增加的值)这两个值都可以在Xcode中选中target,点击“Summary”后看到。 Version在plist文件中的key是“CFBundleSh…

住房和城乡建设部官方网站已前程无忧招聘网

需求:项目中需要使用netty,本地测试的时候使用的是ws,然后要部署到服务器上,使用https连接,https下就不能用ws了,必须升级到wss 1.阿里云申请免费证书 2.保存证书到本地目录 3.修改代码 SslUtil 工具类…

Windows+VSCode搭建小智(xiaozhi)开发环境 - 教程

Windows+VSCode搭建小智(xiaozhi)开发环境 - 教程2025-10-06 22:21 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; disp…

StarTree支持Apache Iceberg扩展湖仓用例

StarTree宣布其云服务全面支持Apache Iceberg,实现直接查询Iceberg表而无需移动或转换底层数据,解决了高并发实时查询的挑战,同时避免了数据重复存储和复杂管道构建。StarTree支持Apache Iceberg以扩展湖仓用例 基于…

偏微分方程的解

偏微分方程的解求未知函数。

如何在 HTML 中添加按钮 - 实践

如何在 HTML 中添加按钮 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&quo…

网站备案的链接如何创建电商平台

前言 这篇文章用于记录阿里天池 NLP 入门赛,详细讲解了整个数据处理流程,以及如何从零构建一个模型,适合新手入门。 赛题以新闻数据为赛题数据,数据集报名后可见并可下载。赛题数据为新闻文本,并按照字符级别进行匿名…

jsp网站开发视频教程关键词网站排名软件

来源:中国科学报去年,当一颗美式足球场大小的雪茄形天体Oumuamua进入太阳系时,它并非仅仅让人们第一次看到了一块星际岩石。根据一项新的研究,这也支持了太空岩石通过在遥远的恒星系统之间运送微生物,从而在星际间传播…

Road Trip of the National Day holiday

During the National Day holiday, I went on a road trip with my wife to western Sichuan. We started from Chengdu and passed through Yaan and Luding. On the first day, we visted the "Red Army Flying…

selenium基础 - 教程

selenium基础 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "…

贵阳网站建设公企业型网站

前言 在之前的博客中: 1.Surface Web —> Deep Web —> Dark Web,我们解释了表层网络、深层网络等的相关概念; 2.Tor浏览器——层层剥开洋葱,我们阐述了Tor的历史和基本工作原理; 3.Tor浏览器…

详细介绍:20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s

详细介绍:20250602在荣品的PRO-RK3566开发板的Android13下的uboot启动阶段配置BOOTDELAY为10s2025-10-06 22:08 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !impo…