嵌入式初学-C语言-二九

news2024/11/24 7:03:30

C语言编译步骤

  1. 预处理
  2. 编译
  3. 汇编
  4. 链接

 

什么是预处理

预处理就是在源文件(如.c文件)编译之前,所进行的一部分预备操作,这部分操作是由预处理程序自动完成,当源文件在编译时,编译器会自动调用预处理指令的解析,预处理指令解析完成才能进入下一步的编译过程

为了能够方便看到编译细节,使用以下命令

 gcc 源文件 -E -o 程序名[.后缀]

预处理的功能

宏定义

作用域
  1. fine命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束。通常,#define命令写在文件开头,函数之前,作为文件一部分,在此文件范围内有效。
  2. 可以用#undef命令终止宏定义的作用域。
  3. 宏定义时,可以引用已定义的宏名,可以层层置换。
  4. 对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。
  5. 宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,不分配内存空间。
不带参数的宏定义
  1. 语法:#define 宏名 常量数据的宏定义
  2. 预处理:此时的预处理制作数据替换,不做类型检查
  3. 注意:
    1. 定义的宏不占内存空间,还没有到编译环节的时候,就已经被替换成了宏中的常量数据
    2. 在预编译时将宏名替换成字符串的过程称为“宏展开”。

 案例:

#include <stdio.h>
#define PI 3.1415926
void main()
{
float l,s,r,v;
printf("input radius:");
scanf("%f",&r);
l=2.0*PI*r;
s=PI*r*r;
v=4.0/3*PI*r*r*r;
printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v);
}
带参数的宏定义
  1. 作用:不是进行简单的字符串替换,还要进行参数替换。
  2. 语法:#define 宏名(参数列表)参数表达式

 例题:

#define multi(a,b) a * b

 

/**
* 宏定义-带参数
*/
#include <stdio.h>
#define MULTI(a,b) a * b
int main()
{
int result = MULTI(7+2,3);
printf("%d\n",result);// 27 9
return 0;
}

  1. 对带参数的宏展开只是将语句中的宏名后面括号内的实参字符串代替#define 命令行中的形参。
  2. 在宏定义时,在宏名与带参数的括弧之间不应加空格,否则将空格以后的字符都作为替代字符串的一部分。
带参数的宏和函数的区别:
  1. 函数调用时,先求出实参表达式的值,然后代入形参。而使用带参的宏只是进行简单的字符替换。
  2. 函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
  3. 对函数中的实参和形参类型要求一致。而宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定义时,字符串可以是任何类型的数据

文件包含

概念:

所谓“文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包含进来。

预处理:

此时的预处理将文件中的内容替换,文件包含指令

包含方式:
  1. 第一种:#include <xxxx.h>
    1. 系统会到标志库头文件目录(Linux下/usr/include)查找包含的文件
  2. 第二种:#include “xxxx.h”
    1. 在当前的工程路径下查找,如果未找到,任然会在标准库头文件目录查找

案例:

algorithm.h 

/**
* 实现数组元素的累加计算
*/
int sum(const int *p,int len)
{
int sum = 0;
register int i = 0;
for(;i < len; i++)
{
sum += *(p+i);
}
return sum;
}

app.c

// #include <stdio.h>
// 引入自定义的头文件
#include "algorithm.h"
// 如果有n多个外部函数,难道都要一个个的使用extern进行声明?
// 引入外部函数声明
// extern int sum(const int*,int);
int main()
{
int arr[5] = {12,33,14,55,34};
int res = sum(arr,5);
printf("数组累和结果是:%d\n",res);
return 0;
}

编译命令:

gcc algorithm.c app.c -o app // 又包含关系的c文件要一起编译

说明:

(1) 一个#include命令只能指定一个被包含文件,如果要包含n个文件,要用n个#include命令。

(2) 在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。

(4) 在#include命令中,文件名可以用双撇号或尖括号括起来。

(5) 被包含文件(file2.h)与其所在的文件(即用#include命令的源文件file2.c),在预编译后已成为同一个文件(而不是两个文件)。因此,如果file2.h中有全局静态变量,它也在file1.h文件中有效,不必用extern声明。

注意:

  在编译时并不是分别对两个文件分别进行编译,然后再将它们的目标程序连接的,而是在经过编译预处理后将头文件format.h包含到主文件中,得到一个新的源程序,然后对这个文件进行编译,得到一个目标(.obj)文件。被包含的文件成为新的源文件的一部分,而单独生成目标文件。

 

条件编译

概念:

所谓“条件编译”,是对部分内容指定编译的条件,使其只在满足一定条件才进行编译。(根据设定定的条件选择待编译的语句代码)

预处理:

将满足条件的语句进行保留,不满足条件的语句进行删除,交给下一步编译

语法:

判断标识符定义或者未定义

  1. 语法一:

#ifdef 标识

        …

#else

        …

#endif

判断标识符定义或者未定义

  1. 语法二:

#ifndef 标识

        …

#else

        …

#endif

根据表达式返回的结果:0不成立,1成立

  1. 语法三:

#if 表达式

        …

#else

        …

#endif

 案例:

/**
* 预处理-条件编译
*/
#define MINUS 1
int main(void)
{
#ifndef MINUS // 判断标准是:标识有没有被定义
int a = 7 - 4;
#else
int a = 7 * 4;
#endif
printf("计算结果:%d\n",a);
return 0;
}
/**
* 预处理-条件编译:输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输
出。
*/
#include <stdio.h>
// 定义一个标识
#define LETTER 0
void main()
{
// 测试用的字母字符数组
char str[20] = "C Language";
char c;
int i;
i = 0;
while((c=str[i])!='\0')
{
i++;
#if LETTER
if(c >='a' && c <='z')
{
c -= 32;
}
#else
if(c >='A' && c <='Z')
{
c += 32;
}
#endif
printf("%c",c);
}
printf("\n");
}

避免头文件重复包含的方法

语法:

#ifndef __XXXX_H
#define __XXXX_H
...
#endif

案例:

algorithm.h

/**
* 自定义头文件,专门用于存放被外部访问的函数的声明
*/
#ifndef __ALGORITHM_H
#define __ALGORITHM_H
// 数组的累加和计算
extern int sum(const int *p,int len);
#endif

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

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

相关文章

2024年大厂裁员严重,软件测试行业真的饱和了吗?

这短时间以来后台有很多小伙伴说找工作难&#xff0c;并且说软件测试行业饱和了&#xff1f;竟然登上了热榜 那么我今天带大家看看真实的市场行情&#xff0c;往下看 这个是公司联合某厂的HR招聘真实情况&#xff0c;很明显【软件测试】投简历竟然高达9999沟通才1千多&#xf…

【学术会议征稿】第七届土木建筑、水电与工程管理国际学术会议(CAHEM 2024)

第七届土木建筑、水电与工程管理国际学术会议&#xff08;CAHEM 2024&#xff09; 2024 7th International Conference on Civil Architecture, Hydropower and Engineering Management (CAHEM 2024) 第七届土木建筑、水电与工程管理国际学术会议&#xff08;CAHEM 2024&…

【蓝桥杯冲刺省一,省一看这些就够了-C++版本】蓝桥杯STL模板及相关练习题

蓝桥杯历年省赛真题 点击链接免费加入题单 STL map及其函数 map<key,value> 提供一对一的数据处理能力&#xff0c;由于这个特性&#xff0c;它完成有可能在我们处理一对一数据的时候&#xff0c;在编程上提供快速通道。map 中的第一个值称为关键字(key)&#xff0c;…

河南萌新联赛2024第(六)场:郑州大学(ABCDFGHIL)

文章目录 写在前面A 装备二选一&#xff08;一&#xff09;思路code B 百变吗喽思路code C 16进制世界思路code D 四散而逃思路code F 追寻光的方向思路code G 等公交车思路code H 24点思路code I 正义从不打背身思路code L koala的程序思路code 河南萌新联赛2024第&#xff08…

Transformer总结(二):架构介绍(从seq2seq谈到Transformer架构)

文章目录 一、seq2seq应用介绍二、编码器解码器架构2.1 流程介绍2.2 原理说明 三、Transformer整体结构和处理流程3.1 Attention机制在seq2seq中的引入3.2 比较RNN与自注意力3.3 Transformer架构介绍3.4 处理流程3.4.1 编码器中处理流程3.4.2 解码器在训练阶段和预测阶段的差异…

Linux平台x86_64|aarch64架构RTMP推送|轻量级RTSP服务模块集成说明

系统要求 支持x64_64架构、aarch64架构&#xff08;需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需要GLib–2.0, 需安装 libstdc.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9&#xff09;。 功能支持 Linux平台x64_64架构|aarch64架构RTMP直播推送SDK 音频编码&a…

UDP服务端、TCP的c/s模式

一、UDP服务端 socket bind //绑定 recvfrom ssize_t recvfrom(int sockfd, socket的fd void *buf, 保存数据的一块空间的地址 …

网络编程TCP与UDP

TCP与UDP UDP头&#xff1a; 包括源端口、目的地端口、用户数据包长度&#xff0c;检验和 数据。 typedef struct _UDP_HEADER {unsigned short m_usSourPort;    // 源端口号16bitunsigned short m_usDestPort;    // 目的端口号16bitunsigned short m_usLen…

一款B to B Connector的仿真结果与开发样品实测的结果对比

下面是一款B to B 连接器开发初期的CST仿真结果: 回波损耗 插入损耗 时域阻抗 开发样品出来后第三方测试机构的实测结果

Auto CAD 常用指令汇总 [持续更新]

简介 AutoCAD是由美国Autodesk公司开发的一款自动计算机辅助设计软件&#xff0c;广泛应用于建筑、工程、城市规划等多个领域。自1982年发布以来&#xff0c;AutoCAD不断进化&#xff0c;成为行业标准之一。它支持二维绘图和三维建模功能&#xff0c;用户可以精确绘制各种图形&…

BSCI(Business Social Compliance Initiative)验厂

在当今全球化的经济环境中&#xff0c;企业社会责任&#xff08;Corporate Social Responsibility, CSR&#xff09;已成为衡量企业成功与否的重要标尺之一。而BSCI&#xff08;Business Social Compliance Initiative&#xff09;验厂&#xff0c;作为国际间广泛认可的社会责任…

服务器Ubuntu22.04系统 使用dcocker部署安装ollama和搭配open_webui使用

服务器Ubuntu22.04系统 使用dcocker部署安装ollama和搭配open_webui使用 一、ubuntu和docker基本环境配置 1.更新包列表&#xff1a; 打开终端&#xff0c;输入以下命令&#xff1a; sudo apt-get updatesudo apt upgrade更新时间较长&#xff0c;请耐心等待 2. 安装docke…

[MOCO] Momentum Contrast for Unsupervised Visual Representation Learning

1、目的 无监督表示学习在自然图像领域已经很成功&#xff0c;因为语言任务有离散的信号空间&#xff08;words, sub-word units等&#xff09;&#xff0c;便于构建tokenized字典 现有的无监督视觉表示学习方法可以看作是构建动态字典&#xff0c;字典的“keys”则是从数据&am…

测评了几百款素材管理软件,新手设计师如何进行高效的素材管理?附教程

设计师朋友们&#xff0c;大家在日常工作中肯定积累了各种各样的素材&#xff0c;大家都保存在哪里呢&#xff1f;是散落在电脑磁盘里&#xff0c;还是用一个专门的素材管家管理呢&#xff1f;作为新手设计师&#xff0c;目前是在使用一款经典好用的素材管理软件—Eagle&#x…

Java学习_17_集合综合练习(待更新)

文章目录 前言一、自动点名器二、斗地主小游戏1、准备牌2、洗牌3、发牌4、理牌 总结 前言 博客仅记录个人学习进度和一些查缺补漏。 学习内容&#xff1a;BV17F411T7Ao 部分内容因没有学到&#xff0c;等待后续更新 一、自动点名器 /**** 点名器1&#xff0c;N个学生随机点名…

Edge-TTS:微软推出的,免费、开源、支持多种中文语音语色的AI工具[工具版]

Edge-TTS&#xff0c;由微软推出的这款免费、开源的AI工具&#xff0c;为用户带来了丰富多样的中文语音体验。它不仅支持多种中文语音语色&#xff0c;还能实现流畅自然的语音合成。Edge-TTS凭借其高度可定制化的特点&#xff0c;广泛应用于智能助手、语音播报、教育培训等领域…

商业软件许可证介绍|简单原理探究

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 引入话题 既然是商业软件&#xff0c;涉及到商业&#xff0c;那目的就是赚钱。 就拿IDEA举例&#x…

Linux系统中的常见操作命令

目录 命令总结&#xff1a; 一、目录处理命令 二、文件处理命令 三、权限管理命令 四、其它实用命令 命令总结&#xff1a; &#xff08;目录&#xff09; ls [参数] 目录、&#xff08;查看目录&#xff09;pwd、&#xff08;切换目录&#xff09;cd [目录路径]、&…

4.1栈和队列基本概念+经典OJ题

本篇博客来梳理栈和队列基本概念以及一道经典OJ题&#xff0c;题目已插入超链接&#xff0c;点击即可跳转~ 一、栈的相关概念 1&#xff0e;栈 一种特殊的线性表&#xff0c;只允许在固定的一端插入和删除元素&#xff0c;栈中的数据遵循后进先出原则 &#xff08;1&#x…

Pytorch添加自定义算子之(12)-开闭原则设计tensorrt和onnxruntime推理语义分割模型

一、开闭原则 开闭原则是SOLID原则中的一个,指的是尽量使用开放扩展,关闭修改的设计原则。 在C++中如何使用开闭原则导出动态库,可以按照以下步骤进行: 定义抽象基类:定义动态库中的抽象基类,该基类应该封装可扩展的接口。 实现派生类:实现基类的派生类,这些派生类将封…