C/C++|物联网开发入门+项目实战|嵌入式C语言高级|简介及GCC参数|define|编译过程-学习笔记(7)

news2024/12/28 18:57:18

课程介绍

参考:麦子学院-嵌入式C语言高级

本套课程的定位

前导课程:掌握简单C语言的基本语法
计算机程序语言的学习思路?
基本程序设计思想+语言工具的特性
基本程序设计思想:
数据类型、运算符、条件分支、循环设计
面向对象的设计
C语言工具的特性:
比如操作底层,尤其是内存地址的寻址及操作,指针的使用
掌掘C语言的设计思路,比普通的语法要重要的多
万变不离其宗,掌掘C语言的核心规律。

本套读程的想法

不是教程,是一种嵌入式C语言思想和设计的交流
什么时候用?
怎么用?
为什么要这样设计?

推荐教程

C语言深度解剖(第2版》 解开程序员面试笔试的秘密
C专家编程
程序员面试宝典《第4版)
C和指针

偏重嵌入式方向的使用

嵌入式课程的特点

2-1 : GCC的使用及其常用选项介绍【重点】

掌握C语言如何变成机器指令的过程
gcc工具的几个常用选项的意义
【难点】
C编译过程中在gcc工具上的体现
【实验考核】
自己编写程序,利用gcc工具集验证每一步的执行效果
举例说明gcc选项的意义:
gcc -I gcc -L
gcc -E gcc -S gcc -c

Gcc概述

c语言的编译过程
可参考:C/C++|物联网开发入门+项目实战|C语言基础|C语言的预处理及编译过程分析-学习笔记(2)

C语言常见错误举例

预处理错误;

include “name” 当前目录
include 系统库(环境变量)

not find

示例
从abc1.h中引入字符char_c

#include <stdio.h>
#include "abc1.h"

int main()
{
    char  c=char_c;
    printf("c(char)=%c,c(int)=%d,c_change(char)=%c,c_change(int)=%d,c_change(HEX)=%#x\n",c,c,c+32,c+32,c+0x20);
    return 0;
}

输出:
E:\temp>cd “e:\temp” && gcc 2.c -o 2 && "e:\temp"2
2.c:2:18: fatal error: abc1.h: No such file or directory
compilation terminated.
显然无此文件(文件名错误),改为include “abc.h”,运行正常。
而一般地,将头文件一般放在inc目录下。
建立inc,并把abc.h移入inc:
在这里插入图片描述

1、方法1:修改inclue为#include “./inc/abc.h”;
2、方法2:gcc -I ./inc 2.c -o 2

编译错误

语法错误,

链接错误

打包出错,原材料不够 undefined reference

寻找标签是否实现了,链接时是否加入一起链接
示例

#include <stdio.h>
#include "abc.h"

void fun(void);
int main()
{
    char  c=char_c;
    printf("c(char)=%c,c(int)=%d,c_change(char)=%c,c_change(int)=%d,c_change(HEX)=%#x\n",c,c,c+32,c+32,c+0x20);

    fun();
    return 0;
}

main函数中引用了一个fun函数,但没有fun函数的实现,故链接器collect2.exe时出错,

提示:
E:\temp>gcc -I ./inc 2.c -o 2 && "e:\temp"2
C:\Users\Vera\AppData\Local\Temp\ccRNGpif.o:2.c:(.text+0x4b): undefined reference to `fun’
collect2.exe: error: ld returned 1 exit status
解决方法1:不声明,删除fun()的定义并直接实现一个空函数:

void fun(void)
{

}

方法2:2.c不变,新建立abc.c存放fun()的函数实现,如:
abc.c

void fun(void)
{

}

执行程序:>gcc -I ./inc -o 2 2.c abc.c #将所有用到的原材料放在输出文件之后
方法3:分别编译再拼接

E:\temp>gcc -c -I./inc -o a.o 2.c
E:\temp>gcc -c  -o b.o abc.c

分别编译完成后的文件都输出在当前目录下:

gcc -o 2 a.o b.o

原材料多了(重复定义) multiple definition

解决思路:多次实现了标签,只保留一个标签实现
在2个文件中都实现fun()函数,并重新编译,链接:

E:\temp>gcc -c -I./inc -o a.o 2.c

E:\temp>gcc -c  -o b.o abc.c

E:\temp>gcc -c -I./inc -o a.o 2.c

E:\temp>gcc -o 2 a.o b.o

提示错误:
E:\temp>gcc -o 2 a.o b.o
b.o:abc.c:(.text+0x0): multiple definition of `fun’
a.o:2.c:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

宏的使用

预处理的使用

#include 包含头文件,并在当前位置展开
#deine 宏(替换),不进行语法检查,编译时才检查
#define 宏名 宏体 加括号
#define ABC (5+3)
#define ABC(x) (5+(x)) //宏函数

预定义宏(方便调试)

(C语言编译器或gcc定义)
前后2个下划线
FUNCTIO
LINE
FILE

示例

#include <stdio.h>

int main()
{

     //本行执行的函数名,所在文件名,本行的行号
    printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);

    return 0;
}

输出:
E:\temp>cd “e:\temp” && gcc 2.c -o 2 && "e:\temp"2
the main,2.c,7

改示例为

#include <stdio.h>

int fun()
{
    int a;

     //本行执行的函数名,所在文件名,本行的行号
    printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);

    return 0;
}

int main()
{
    fun();

    return 0;
}

输出(实际调用的函数名称和所在行号):
E:\temp>cd “e:\temp” && gcc 2.c -o 2 && "e:\temp"2
the fun,2.c,8

条件预处理

#ifdef #else #endif
调试版本

发行版本
示例
原始代码:

#include <stdio.h>

int main()
{
    printf("=========================\n",__FILE__);

    printf("hello world!\n");

    return 0;
}

debug期间允许__FILE__行显示,但发行版本中不显示,怎么实现:

#include <stdio.h>

int main()
{
#ifdef  ABC

    printf("=========================\n",__FILE__);

#endif

    printf("hello world!\n");

    return 0;
}

未定义ABC时,不打印:

E:\temp>cd “e:\temp” && gcc 003.c -o 003 && "e:\temp"003
hello world!

需要显示调试信息时,只要在#ifdef ABC之前定义ABC即可。
在这里插入图片描述
但是该方法还是要修改源文件,不是很方便,故引入gcc -D:cpp之前增加define
如:gcc -DABC -o build 003.c 相当于编译前引入: #define ABC。

宏展开下的#、##

# 字符串化
## 连接符号
#define ABC(x) #x
#define ABC(x) day##x //day和x进行连接

示例

#include <stdio.h>
#define ABC(x)    #x //字符串化
#define DAY(x)    myday##x //字符串在当前位置展开,可以执行调用前,后缀
int main()
{
    int a;
    int myday1 = 10;
    int myday2 = 20;
     //本行执行的函数名,所在文件名,本行的行号
    // printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);
    printf(ABC(ab\n));   //相当于:"ab\n"
    printf("the day is %d\n",DAY(1)); //前缀或者后缀以隐藏方式调用。
    printf("the day is %d\n",DAY(2));
    return 0;
}

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

数据库系统笔记CH5(初)

计组的知识 虚拟存储 IEEE754标准 5.1存储层级 二级存储器磁盘和固态硬盘 红色部分是磁道&#xff0c;蓝色部分是扇区&#xff0c;绿色指示部分是数据库中的一个块/页 块/页是我们用来存储介质的一个物理单元,数据写入磁盘以块位单位写入内存,一个块的大小一般是4KB或者8KB&…

项目管理中,这些思维误区一定要避开

项目需要在限定的时间要求完成的事情&#xff0c;可控的关键把握是&#xff1a;人、时、事。 但是&#xff0c;项目实施时间一般较长&#xff0c;总有很多项目实施结果不尽人意。那么&#xff0c;IT项目管理过程中&#xff0c;容易出现哪些思维误区呢&#xff1f; 1、忘记项…

react性能优化之shouldComponentUpdate的原理剖析

shouldComponentUpdate原理讲解shouldComponentUpdate是干什么的怎么使state更新而render函数不执行呢&#xff1f;使用shouldComponentUpdate完成性能优化当组件的state没有变化&#xff0c;props也没有变化&#xff0c;render函数可能执行吗&#xff1f;pureComponent的基本用…

北京小厂Java实习面经

目录1.数据库的三大范式2.事务四个特性3.知道多少种索引&#xff0c;分别讲讲4.主键索引和唯一索引的区别5.索引失效的场景6.数据库的日志知道哪些&#xff0c;分别讲讲7.redis的数据结构和应用场景8.缓存击穿是怎么产生的&#xff0c;解决方案9.redis中key的过期策略10.redis内…

达梦数据库支持GB18030-2022中文编码字符集证明方法

既然是证明就要做到有图有真相。 证明途径1&#xff1a;系统概览法 查看达梦数据库“管理工具”->“对象导航”->“管理服务器”-“系统概览”->“字符集编码”->”GB18030”. 看见”GB18030”字样就是证据之一。如果你没有看见这个字样&#xff0c;而是UTF8等其…

1. 大端法和小端法

int32_t num 0x01020304;一个int32_t是4个字节&#xff0c;在内存中的存储是高位字节在低地址&#xff0c;低位字节在高地址。 &#xff08;数字&#xff09;前者的高低是数字位数的高低&#xff0c;左边是高位数&#xff0c;右边是低位数&#xff1b; &#xff08;地址&…

git代码使用空格缩进

1、idea设置缩进符为空格 Java 代码 golang 代码 2、设置提交仓库时的空格处理&#xff0c;否则 golang 代码为了减少文件大小&#xff0c;可能会把空格缩进改为制表符。 设置当前仓库配置 git config core.whitespace "-trailing-space,space-before-tab" 设置当前…

Pytorch深度学习实战3-7:详解数据加载DataLoader与模型处理

目录1 数据集Dataset2 数据加载DataLoader3 常用预处理方法4 模型处理5 实例&#xff1a;MNIST数据集处理1 数据集Dataset Dataset类是Pytorch中图像数据集操作的核心类&#xff0c;Pytorch中所有数据集加载类都继承自Dataset父类。当我们自定义数据集处理时&#xff0c;必须实…

从TOP25榜单,看半导体之变

据SIA报告显示&#xff0c;2022年全球半导体销售额创历史新高达到5740亿美元。尽管2022年下半年&#xff0c;半导体市场出现了周期性的低迷&#xff0c;但其全年的销售额相较2021年增长了3.3%。 近日&#xff0c;市调机构Gartner发布了全球以及中国大陆TOP25名半导体厂商的排名…

js数组API的时间复杂度大全

一句话总结&#xff1a; 数组为连续且有序的数据结构, 所以若根据下标查找则很快&#xff0c;index[i]一步到位就可实现查询&#xff0c;若遍历查找则很慢(相对而言)。而插入和删除&#xff0c;除了数组末尾的增删很快&#xff0c;其它处则很慢&#xff0c;因为若数组某处要插入…

【服务器数据恢复】 重装系统导致xfs文件系统分区丢失的数据恢复案例

服务器数据恢复环境&#xff1a; EMC某型号存储&#xff0c;20块磁盘组建raid5磁盘阵列&#xff0c;划分2个lun。 服务器故障&#xff1a; 管理员执行重装系统操作后发现分区发生改变&#xff0c;原先的sdc3分区丢失&#xff0c;该分区采用xfs文件系统&#xff0c;存储了公司重…

开放式耳机好用吗,推荐几款不错的开放式耳机

​开放式耳机是一种新型的耳机&#xff0c;相比于传统的耳机&#xff0c;开放式耳机听歌时不需要将耳朵堵上&#xff0c;不会因为长时间佩戴而对听力造成损害。它不需要入耳也能听到声音&#xff0c;在户外运动时能够及时听到环境音&#xff0c;避免安全隐患。现在在骨传导市面…

nodejs+vue 沃健身房管理系统

3)系统分析 本章主要是对系统可行性、系统性能、还有系统功能需求进行分析。 (4)系统设计 对系统系统功能和数据库等进行详细讲解。 (5)系统的实现 主要对个人中心、课程分类管理、用户管理、健身器材管理、健身教练管理、预约教练管理、健身课程管理、课程订单管理、健身视频管…

ESP32学习笔记08-adc单通道数据采集

8. adc单通道数据采集 8.1RTC SAR ADC 控制器 8.2ADC相关的api 8.2.1 配置adc的位宽 esp_err_t adc1_config_width(adc_bits_width_t width_bit);width_bit :位宽 返回值 ESP_OK 配置成功 ESP_ERR_INVALID_ARG 参数错误 esp32最大的宽度的12位typedef enum {

STM8S208MB -> 寄存器方式实现对Flash的连续读写操作(IAR)

代码 File: STM8S208MB_Flash_Op.c /*file: STM8S208MB_Flash_Op.cbrief: 读写Flashdata: 2023-04-14author: ArcherQAQ */#include "STM8S208MB_Flash_Op.h" #include "stdio.h"u8 dataBuf[] {0xFF, 0xFF}; // 写入Flash的数据 u8 Rec_Buf[100] {0x00…

天猫数据分析:2023年速食品(方便面)市场数据分析

我国的方便面市场是一个比较活跃的市场&#xff0c;其市场规模也比较庞大。近年来&#xff0c;随着中国经济的发展&#xff0c;消费者对方便面的需求量和要求也在不断变化&#xff0c;因此&#xff0c;我国方便面市场的规模和消费者的需求环境也正在不断改变。 根据鲸参谋电商数…

Excel技能之排名,小函数很强大

你还在熬夜加班搞Excel吗&#xff1f; 你还在用手指&#xff0c;指着电脑屏幕&#xff0c;一行一行核对数据吗&#xff1f; 你还在害怕被笑而不敢问同事吗&#xff1f; 赶紧来学Excel&#xff0c;收藏加关注&#xff0c;偷偷地进步&#xff01;日积月累&#xff0c;必成大器&am…

12-python内存地址

1.查看内存地址 a1 print(id(a)) # 24319294835042.数据类型 &#xff08;1&#xff09;不可变数据类型&#xff1a;数值、字符串、布尔值、元组 数据存储在计算机中的某个位置&#xff0c;不管赋值给谁&#xff0c;内存地址都相同 a"jack" b"jack" prin…

常见分布式锁3:Redis setNx

Redis实现分布式锁的核心便在于SETNX命令&#xff0c;它是SET if Not eXists的缩写&#xff0c;如果键不存在&#xff0c;则将键设置为给定值&#xff0c;在这种情况下&#xff0c;它等于SET&#xff1b;当键已存在时&#xff0c;不执行任何操作&#xff1b;成功时返回1&#x…

【python游戏】努力制造阳光,让植物有力量对抗僵尸吧~

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 晃着脑袋生产阳光的向日葵&#xff0c;突突突吐着子弹的豌豆射手&#xff01;​ 行动迟缓种类丰富的僵尸…… 印象最深的是“僵尸吃掉了你的脑子&#xff01;” 还有疯狂的戴夫&#xff0c;无一不唤醒着我们的童年记忆​ 山…