C语言-编译和链接

目录

    • 1.前言
    • 2.编译
      • 2.1预处理(预编译)
        • 2.1.1 #define 定义常量
        • 2.1.2 #define 定义宏
        • 2.1.3带有副作用的宏参数
        • 2.1.4宏替换规则
        • 2.1.5 #和##
          • 2.1.5.1 #运算符
            • 2.1.5.2 ## 运算符
        • 2.1.6 命名约定
        • 2.1.7 #undef
        • 2.1.8 条件编译
        • 2.1.9 头文件的包含
          • 2.1.9.1 本地文件包含
          • 2.1.9.2 库文件包含
        • 2.1.10 嵌套文件包含
    • 3.编译
    • 4.汇编
    • 5.链接

1.前言

在这里插入图片描述
一个C语言项目中可能有多个.c文件一起构建

  • 多个.c文件单独经过编译器,编译处理生成对应的目标文件
  • 多个目标文件和链接库一起经过链接器处理生成最终的可执行程序

2.编译

2.1预处理(预编译)

预处理阶段主要处理那些源文件中#开始的预编译指令。比如:#include,处理规则如下:

  • 将所有的#define删除,并展开所有的宏定义
  • 处理所有的条件编译指令
  • 删除所有的注释
  • 添加行号和文件名标识符,方便后续编译器生成调试信息
  • 处理#include预编译指令,将所包含的头文件的内容插入到该预编译指令的位置
2.1.1 #define 定义常量
#define MAX 100

在用#define定义标识符的时候,不用在最后加上;
如果加上,很容易导致一些问题

#define MAX 100;int main()
{int a=0;if(1)a=MAX;//这里其实是  a=100;;  这里有两个分号,编译器会通不过,因为if只能管一条语句,两个分号就是两条语句elsea=-1;
}
2.1.2 #define 定义宏

#define机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏
宏的声明方式:

#define name( parament-list ) stuff

注意:
参数列表的左括号必须与name紧邻!!!

举例:

#define SQUARE(x) ((x)*(x))int a=4;
printf("%d\n",SQUARE(a+1));//25

提示:
用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏定义时由于参数中的操作符或邻近操作符之间不可预料的相互作用

#define SQUARE(x) x*xint a=4;
printf("%d\n",SQUARE(a+1));//9
//a+1*a+1=4+4+1=9
2.1.3带有副作用的宏参数

当宏参数在宏定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果

x+1;//不带副作用的
x++;//带副作用的

举例:

#include <stdio.h>
#define MAX(a,b)  ((a++)>(b++)?(a++):(b++))
int main()
{int x=3;int y=4;printf("%d\n",MAX(x,y));//?printf("%d\n",x);//?printf("%d\n",y);//?return 0;
}
//((x++)>(y++)?(x++):(y++))
//MAX(x,y)=5
//x=4
//y=6
2.1.4宏替换规则
  • 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换
  • 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换
  • 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。

注意:
1.宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
2.当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

2.1.5 #和##
2.1.5.1 #运算符

#运算符将宏的一个参数转换成字符串字面量。它仅允许出现在带参数的宏的替换列表中
#运算符所执行的操作可以理解为“字符串化
比如:

//当我们有一个变量a=10;的时候,我们向打印出:the value of a is 10;
#define G(n) printf("the value of "#n " is %d",n);//n=10
//代码会转换成:
printf("the value od ""a" " is %d",a);
2.1.5.2 ## 运算符

##被称为记号粘合符
比如:
我们想写一个函数求两个数的较大值的时候,不同类型就得写不同的函数

int int_max(int x,int y)
{return x>y?x:y;
}double double_max(double x,double y)
{return x>y?x:y;
}

这样写就比较繁琐

//宏定义
#define G_MAX(type)\
type type##_max(type x,type y)\
{\return x>y?x:y;\
}G_MAX(int)//定义函数
G_MAX(double)//定义函数int main()
{//调⽤函数int m = int_max(2, 3);printf("%d\n", m);//3double fm = double_max(3.5, 4.5);printf("%f\n", fm);//4.500000return 0;}
2.1.6 命名约定

把宏名全部大写
函数名不要全部大写

2.1.7 #undef

这条指令用于移除一个宏定义

#undef MAX
//如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除
2.1.8 条件编译

在编译一个程序的时候我们如果要将一条语句编译或者放弃是很方便的。因为我们有条件编译指令
比如:

#include <stdio.h>
#define __DEBUG__
int main()
{int a = 1;int b = 2;int x = 3;
#ifdef __DEBUG__printf("%d\n", a);
#endifprintf("%d\n", b);printf("%d\n", x);return 0;
}

条件编译指令有很多,这里就不一一列举了

2.1.9 头文件的包含
2.1.9.1 本地文件包含
#include "filename"

查找策略:
先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。如果找不到据提示编译错误

2.1.9.2 库文件包含
#include <filename>

查找头文件直接去标准路径下查找,找不到就提示编译错误

2.1.10 嵌套文件包含

如何解决头文件被重复引入的问题?
条件编译

#ifndef __TEST_H__
#define __TEST_H__
//头⽂件的内容
#endif //__TEST_H__

或者

 #pragma once

3.编译

编译过程就是将预处理后的文件进行一系列的:词法分析,语法分析,语义分析及优化,生成相应的汇编代码

4.汇编

汇编器是将汇编代码转转变成机器可执行的指令,每⼀个汇编语句几乎都对应⼀条机器指令。就是根
据汇编指令和机器指令的对照表⼀⼀的进行翻译,也不做指令优化。

5.链接

链接是⼀个复杂的过程,链接的时候需要把⼀堆⽂件链接在⼀起才生成可执行程序
链接过程包括:地址和空间分配,符号决议和重定位等步骤

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

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

相关文章

ubuntu+clangd+vscode 实现项目代码快速跳转(如: Linux 内核源码)

1. 准备工作 虚拟机 ubuntu 环境&#xff0c;笔者用的是 ubuntu20.04。windows 安装好 vscode 软件。 2. 配置过程 2.1 vscode远程连接 ubuntu ubuntu 虚拟机开启 ssh 服务 sudo apt install openssh-server sudo service ssh startvscode 安装 remote-ssh 插件 vscode 远…

awesome-cheatsheets:超级速查表 - 编程语言、框架和开发工具的速查表

awesome-cheatsheets&#xff1a;超级速查表 - 编程语言、框架和开发工具的速查表&#xff0c;单个文件包含一切你需要知道的东西 官网&#xff1a;GitHub - skywind3000/awesome-cheatsheets: 超级速查表 - 编程语言、框架和开发工具的速查表&#xff0c;单个文件包含一切你需…

java Web 疫苗预约管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 疫苗预约管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使…

小狐狸ChatGPT付费AI创作系统V2.8.0独立版 + H5端 + 小程序前端

狐狸GPT付费体验系统的开发基于国外很火的ChatGPT&#xff0c;这是一种基于人工智能技术的问答系统&#xff0c;可以实现智能回答用户提出的问题。相比传统的问答系统&#xff0c;ChatGPT可以更加准确地理解用户的意图&#xff0c;提供更加精准的答案。同时&#xff0c;小狐狸G…

【jenkins+cmake+svn管理c++项目】jenkins回传文件到svn(windows)

书接上文&#xff1a;创建一个项目 在经过cmakemsbuild顺利生成动态库之后&#xff0c;考虑到我一个项目可能会生成多个动态库&#xff0c;它们分散在build内的不同文件夹&#xff0c;我希望能将它们收拢到一个文件夹下&#xff0c;并将其回传到svn。 一、动态库移位—cmake实…

H5抓包——Android 使用电脑浏览器 DevTools调试WebView

H5抓包——Android 使用电脑浏览器 DevTools调试WebView 一、使用步骤 1、电脑通过数据线连接手机&#xff0c;开启USB调试&#xff08;打开手机开发者选项&#xff09; 2、打开待调试的H5 App&#xff0c;进入H5界面 3、打开电脑浏览器&#xff0c;调试界面入口 如果用ed…

linux命令之tput

1.tput介绍 linux命令tput是可以在终端中进行文本和颜色的控制和格式化&#xff0c;其是一个非常有用的命令 2.tput用法 命令&#xff1a; man tput 3.样例 3.1.清除屏幕 命令&#xff1a; tput clear [rootelasticsearch ~]# tput clear [rootelasticsearch ~]# 3.2.…

C#/BS手麻系统源码 手术麻醉管理系统源码 商业项目源码

C#/BS手麻系统源码 手术麻醉管理系统源码 商业项目源码 手麻系统从麻醉医生实际工作环境和流程需求方面设计&#xff0c;与HIS&#xff0c;LIS&#xff0c;PACS&#xff0c;EMR无缝连接&#xff0c;方便查看患者的信息;实现术前、术中、术后手术麻醉信息全记录;减少麻醉医师在…

AI时代-普通人的AI绘画工具对比(Midjouney与Stable Diffusion)

AI时代-普通人的AI绘画工具对比&#xff08;Midjouney与Stable Diffusion&#xff09; 前言1、基础对比Stable Diffusion&#xff08;SD&#xff09;SD界面安装与使用SD Midjouney&#xff08;MJ&#xff09; 2、硬件与运行要求对比Stable Diffusion硬件要求内存硬盘显卡 Midjo…

MySQL开窗函数

测试环境&#xff1a;mysql8.0.18 官方文档&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/window-functions.html 一、窗口函数介绍二、语法结构三、自定义窗口1.rows&#xff08;重点&#xff09;2.range3.默认窗口 四、常用窗口函数示例1.row_number & rank &…

开源推荐榜【Taichi 专为高性能计算机图形学设计的编程语言】

Taichi是一个高性能的并行编程语言&#xff0c;它被嵌入在Python中&#xff0c;使得开发者能够轻松编写可移植的、高性能的并行程序。这个库的核心优势在于它能够将计算密集型的Python代码在运行时通过即时编译器(Just-In-Time, JIT)转换成快速的机器代码&#xff0c;从而加速P…

吴恩达2022机器学习专项课程(一) 4.1 梯度下降

问题预览 梯度下降算法的作用是&#xff1f;梯度下降的过程&#xff1f;梯度下降和最小化成本函数的联系&#xff1f;所有的成本函数都是一个形状吗&#xff1f;在非凸形状中&#xff0c;梯度下降的更新过程是&#xff1f;在非凸形状中&#xff0c;不同的初值对最小化成本函数…

使用itext-core生成PDF

1、添加引用依赖包 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-core</artifactId><version>8.0.3</version><type>pom</type></dependency> 2、上代码 package com.student.demo.pdf;impor…

011_string_and_cell_in_Matlab中的字符串与元胞数组

Matlab中的字符串与元胞数组 1. 字符串 1.1 为什么 这两个东西拉在一起讲&#xff0c;是因为在2016a之前的Matlab中&#xff0c;要表示一个字符串的数组&#xff0c;只能用元胞数组。 最初的字符串在Matlab中的类型是字符&#xff0c;在Matlab中&#xff0c;一个字符就是一…

Sentinel原理及实践

Sentinel 是什么 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 为什么使用sentinel&…

解决前后端通信跨域问题

因为浏览器具有同源策略的效应。 同源策略是一个重要的网络安全机制&#xff0c;用于Web浏览器中&#xff0c;以防止一个网页文档或脚本来自一个源&#xff08;域、协议和端口&#xff09;&#xff0c;获取另一个源的数据。同源策略的目的是保护用户的隐私和安全&#xff0c;防…

基于Spring Boot的在线学习系统的设计与实现

基于Spring Boot的在线学习系统的设计与实现 摘 要 在线学习系统是以大学传统线下教学方式不适应信息技术的迅速发展为背景&#xff0c;提高学习效率&#xff0c;解决传统教学问题&#xff0c;并且高效的实现教学信息化的一款软件系统。为了更好的实现对于教学和学生的管理&a…

FL Studio21.2.3中文版软件新功能介绍及下载安装步骤教程

FL Studio21.2中文版的适用人群非常广泛&#xff0c;主要包括以下几类&#xff1a; FL Studio 21 Win-安装包下载如下: https://wm.makeding.com/iclk/?zoneid55981 FL Studio 21 Mac-安装包下载如下: https://wm.makeding.com/iclk/?zoneid55982 音乐制作人&#xff1a…

记录关于智能家居的路程的一个bug___Segmentation fault(段错误)

前言 其实发生段错误的情况有很多&#xff1a; 其实在项目的开发中最有可能的错误就是①和②&#xff0c;考虑到本项目数组用的比较少&#xff0c;所以主要是考虑错误①指针的误用。 有时候错误就是那么离谱&#xff0c;声音也算是一种设备&#xff1f;&#xff1f;&#xff…

【安全用电管理系统的应用如何保证用电安全】Acrel-6000安科瑞智慧安全用电解决方案

政策背景 国家部委 ※2017年5月3日国务院安委会召开电气火灾综合治理工作视频会议&#xff0c;决定在全国范围内组织开展为期3年的电气火灾综合治理工作。 公安部领导 ※公安部副部长李伟强调&#xff1a;向科技要战斗力&#xff0c;加快推进“智慧消防”建设不断提升火灾防控…