第22天笔记

devtools/2024/9/20 9:21:30/ 标签: 笔记

C语言编译步骤

预处理

编译

汇编

链接

什么是预处理

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

我们为了能够方便的看到这个编译细节,我们可以使用下面命令:

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

预处理的功能

宏定义

不带参数的宏定义

语法:

#define 宏名 常量数据

预处理:此时的预处理只做数据替换,不做类型检查

注意:我们定义的宏是不会占用内存空间,还没有到编译环节,就已经被替换成了我们宏中的 常量数据。

宏展开:在预编译时将宏名替换成字符串的过程称为“宏展开”

案例:

#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);
}

带参数的宏定义

语法:

#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;
}

宏定义的作用域

#define 命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束。通 常,#define命令写在文件开头,函数之前,作为文件一部分,在此文件范围内有效。

可以用 #undef 命令终止宏定义的作用域

案例:

/**
* 宏定义的作用域
*/
#define PI 3.14
#define DAY 20
void fun()
{
float r = 4;
float s = PI * r * r;
int day = DAY;
}
#undef PI // 结束PI的作用范围
#define PI 3.1415926
void fun1()
{
float r1 = 4;
float s1 = PI * r1 * r1;
int day = DAY;
}
void main()
{
fun();
fun1();
}

在宏定义中引用已定义的宏名

案例:

#include <stdio.h>
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define S PI*R*R
void main()
{
printf("L=%f\nS=%f\n",L,S);
}

文件包含

概念

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

预处理

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

包含方式

第1种: #include<xxxx.h>

系统会到标准库头文件目录(Linux下 /usr/include )查找包含的文件

第2种: #include "xxxx.h"

在当前工程路径下查找,如果未找到,任然会到标准库头文件目录查找

案例:

algorithm.h

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

algorithm.c

/**
* 实现数组元素的累加计算
*/
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文件要一起编译

条件编译

概念

根据设定的条件选择待编译的语句代码。

预处理

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

语法

语法一:

#ifdef 标识 -- 判断标识符定义与否
..
#else
..
#endif

语法二:

#ifndef 标识 -- 判断标识符定义与否
..
#else
..
#endif

语法三:

#if 表达式 -- 根据表达式返回的结果:0-不成立,1-成立
..
#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.ppmy.cn/devtools/97201.html

相关文章

[游戏开发] LuaTable转string存读二进制文件

UE5和Unity通用此方案&#xff0c;只不过读写文件的接口略有不同&#xff0c;lua代码的处理是相同的。 下面两个方法是 LuaTable和字符串互相转换的代码 function XUtils.luaTableToString(tab, sp)sp sp or ""local s ""for k,v in pairs(tab) doif t…

【网络安全】P2:访问控制失效

未经许可&#xff0c;不得转载。 文章目录 正文 正文 该漏洞允许我绕过电子邮件验证步骤&#xff0c;无需我点击发送到我的收件箱的链接。 某应用程序提示我&#xff0c;只有验证我的帐户才能使用网站上的一项功能。当我点击“开始验证”并拦截请求时&#xff0c;请求体如下&am…

关于鸿蒙开发中装饰器@Extend、@Styles、@Builder的介绍

总结 名称适合是否可以参数Extend抽取 特定组件 样式、事件√Styles抽取 公共 样式、事件Builder抽取 结构、样式、事件√ Extend 语法&#xff1a; Extend(要扩展的组件&#xff0c;例如Text、Column、Row等) function functionName { ... } 使用规则&#xff1a; 1、Ex…

WebMagic:强大的Java爬虫框架解析与实战

文章目录 引言官网链接WebMagic原理概述基础使用1. 添加依赖2. 编写PageProcessor 高级使用1. 自定义Pipeline2. 分布式抓取 优点结论 引言 在大数据时代&#xff0c;网络爬虫作为数据收集的重要工具&#xff0c;扮演着不可或缺的角色。Java作为一门广泛使用的编程语言&#x…

【分布式系统】关于主流的几款分布式链路追踪工具

Jaeger 标准化与兼容性&#xff1a; Jaeger 支持 OpenTracing 和 OpenTelemetry 标准&#xff0c;这意味着它可以与各种微服务架构和应用框架无缝集成&#xff0c;提供了广泛的兼容性和灵活性。 数据存储选项&#xff1a; Jaeger 支持多种数据存储后端&#xff0c;如 Cassandra…

内存泄漏之如何使用Visual Studio的调试工具跟踪内存泄漏?

使用Visual Studio的调试工具跟踪内存泄漏是一个系统性的过程&#xff0c;主要包括启用内存泄漏检测、运行程序、分析内存使用情况以及定位泄漏源等步骤。 Visual Studio提供了多种方式来检测内存泄漏&#xff0c;你可以根据自己的需求选择合适的方法。 注意&#xff1a;下面…

引领企业全球化发展 极光亮相华为亚太ICT峰会2024·泰国

近日&#xff0c;华为亚太ICT峰会2024泰国正式开幕&#xff0c;极光&#xff08;Aurora Mobile&#xff0c;纳斯达克股票代码&#xff1a;JG&#xff09;凭借其创新的技术实力与前瞻性的产品布局&#xff0c;受邀出席本次活动。会上&#xff0c;极光展示了其全域消息通知解决方…

MySQL——单表查询(二)按条件查询(11)OR 和 AND 关键字一起使用的情况

OR 关键字和 AND 关键字可以一起使用&#xff0c;需要注意的是&#xff0c;AND 的优先级高于 OR。因此当两者在一起使用时&#xff0c;应该先运算 AND 两边的条件表达式&#xff0c;再运算 OR两边的条件表达式。 例如&#xff0c;查询 student 表中 gender 字段值为 “ 女 ” 或…

C语言:链表删除

链表删除分为头删除和中间删除&#xff08;包含尾删除&#xff09;。 同时注意单向链表原则&#xff1a;先连后断。 具体方法如下&#xff1a; #include<stdio.h> #include<stdlib.h>typedef struct node {int s;struct node* pnext; }list;list* addnode(list*…

UART通信实现与验证(RS485)

前言 UART是一种常用的串行通信协议&#xff0c;RS485则是一种用于长距离和抗干扰的物理层标准。结合UART和RS485可以实现可靠的数据传输&#xff0c;特别是在多点通信和长距离应用中。通过合适的硬件连接、软件配置和验证测试&#xff0c;可以确保这一通信系统的稳定性和数据完…

thinkphp8 定时任务

在ThinkPHP8中创建定时任务通常涉及到Cron作业调度或者操作系统的定时任务功能&#xff08;如cronjob&#xff09;。以下是一个使用操作系统的cronjob的例子。 创建一个命令&#xff1a; // app/Command/ExampleCommand.php namespace app\Command;use think\console\Command; …

Vue 和 React 各自的背景和特点

Vue 的背景和特点 背景&#xff1a; Vue.js 由尤雨溪于2014年创建&#xff0c;并于同年发布第一个版本。Vue 的设计目标是简单、灵活&#xff0c;易于上手&#xff0c;具有响应式数据绑定和组件化开发的特性。 解决的问题&#xff1a; Vue 解决了构建交互式前端界面的问题&…

论文解读:LONGWRITER: UNLEASHING 10,000+ WORD GENERATION FROM LONG CONTEXT LLMS

摘要 现象&#xff1a;当前的大预言模型可以接受超过100,000个tokens的输入&#xff0c;但是却难以生成超过2000个token的输出。 原因&#xff1a;监督微调过程(SFT)中看到的样本没有足够长的样本。 解决方法&#xff1a; Agent Write&#xff0c;可以将长任务分解为子任务&a…

去抖音视频水印的软件免费推荐,精选四款实用工具助你轻松去除水印

随着抖音等短视频平台的流行&#xff0c;我们常常会遇到想要保存某些视频但不想保留水印的情况。本文将为您推荐四款去抖音视频水印的实用工具&#xff0c;帮助您轻松去除视频中的水印&#xff0c;保存清晰的内容。 工具一&#xff1a;奈斯水印助手(小程序) 推荐指数&#xf…

C语言——文件

文件操作 概念 文件是指存储在外存储器上&#xff08;一般代指磁盘&#xff0c;也可以是U盘&#xff0c;移动硬盘等&#xff09;的数据的集合。 文件操作体现在哪几个方面 1.文件内容的读取 2.文件内容的写入 数据的读取和写入可被视为针对文件进行输入和输出的操作&#xf…

Java中的安全编程实践:加密、解密与数字签名

在现代软件开发中&#xff0c;安全性是一个至关重要的方面。无论是保护用户数据&#xff0c;还是确保通信安全&#xff0c;了解和实施有效的安全措施都是开发者的必修课。本文将详细探讨Java中实现安全性的方法&#xff0c;主要包括加密、解密和数字签名&#xff0c;并提供相应…

快速理解 Node.js 版本差异:3 分钟指南

Node.js 是一个广泛使用的 JavaScript 运行时环境&#xff0c;允许开发者在服务器端运行 JavaScript 代码。随着技术的发展&#xff0c;Node.js 不断推出新版本&#xff0c;引入新特性和改进。了解不同版本之间的差异对于开发者来说至关重要。以下是一个快速指南&#xff0c;帮…

内网拓扑可视化及管控技术

内网安全面临严峻威胁和管理挑战 在当今数字化时代&#xff0c;企业面临着日益复杂和多样化的网络安全威胁。云计算和移动设备的普及增加了网络边界的复杂性和模糊性&#xff0c;使传统的边界防护措施疲于应对更复杂的安全攻击手段。比如边界防护难以防止内部员工或恶意攻击者通…

Redis7基础篇(一)

redis十大数据类型 目录 redis十大数据类型 redis键key 数据类型命令 redis字符串string 分布式锁 ​编辑 ​编辑​编辑应用场景 ​编辑​编辑 reids列表list 应用场景 redis哈希hash 应用场景 redis集合set 应用场景 redis有序集合zset&#xff08;sorted set集…

二叉树(三)

一、二叉树的遍历 二叉树遍历是按照某种特定的规则&#xff0c;依次对二叉树中的结点进行相应的操作&#xff0c;并且每个结点只操作一次。 1.前序遍历&#xff08;先根遍历&#xff09; 前序遍历&#xff08;Preorder Traversal也叫先序遍历&#xff09;——根、左子树、右…