前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >day11嵌入式(2022.1.17)

day11嵌入式(2022.1.17)

作者头像
天天Lotay
发布2022-12-02 14:33:41
1990
发布2022-12-02 14:33:41
举报
文章被收录于专栏:嵌入式音视频嵌入式音视频
  1. gcc编译器有什么用?

将代码文本编译为机器能识别的二进制指令。

  1. 代码最终得到程序,经过了哪4个步骤?

预处理、编译、汇编、链接

  1. 经过哪个步骤之后,代码不能直接阅读了?

汇编。

  1. 对于代码的语法检查(提示错误行号)属于在哪个步骤进行?

编译。

  1. 为什么代码漏写函数,gcc编译时不提示出现错误的行号?

因为函数链接定位在链接的阶段,而不是在编译阶段。

==================1.gcc编译流程==========================

  1. 预处理:(代码文本 ---> 预处理文本)

指令:gcc hello.c -o hello.i -E

作用:处理所有的预处理指令(以#开头,比如头文件包含、宏定义、条件编译)

  1. 编译:(预处理文本 ---> 汇编文件)

指令:gcc hello.i -o hello.s -S

作用:词法、语法分析,根据平台生成最接近机器的语言(汇编)。

  1. 汇编:(汇编文件 ---> ELF可重定位文件)

指令:gcc hello.s -o hello.o –c

作用:将汇编指令文件翻译为可直接运行的二进制指令流。

  1. 链接:(ELF可重定位文件 + 库链接 ---> 最终程序)

指令:gcc hello.o -o hello –lc -lgcc

作用:重定位(函数和全局变量等)、链接库、合并段

备注:

  1. 汇编阶段,是处理汇编文件,生成二进制机器指令。
  2. -lXXX表示链接XXX库(-l: library)
  3. 预处理阶段,不会对代码进行语法词法分析。
  4. 链接阶段会对所有函数、全局变量进行重定位、链接,如果此时出现问题,不会提示出错行号。

================== 2.预处理指令 ==========================

在源码中,以#开头的语句,称为预处理指令,他们不属于C语言语法。

  1. 宏定义
代码语言:javascript
复制
#define PI 3.1415926    // 预处理阶段中,将代码中所有宏进行替换。
  1. 条件编译(有点类似于分支结构)
代码语言:javascript
复制
#if #ifdef #ifndef #elif #else #endif 
  1. 头文件包含
代码语言:javascript
复制
#include <stdio.h>

备注:

  1. 宏名一般使用全大写字母,用以区别普通变量、函数。
  2. 带参宏,也称为宏函数,但是不存在函数调用机制。
  3. 宏定义的作用:
  4. 可使代码更具可读性:字符单词一般比纯数字更容易理解含义。
  5. 使得代码更方便修改:只需修改宏定义,即修改了所有该宏定义表达式。
  6. 提高程序运行效率:函数的调用是需要切换时间的,而宏定义是直接展开,不占用运行时间。
  7. gcc编译指令中,可添加 -D选项,往工程中添加指定的宏。

可添加一些调试语句,通过编译指令去控制调试语句的输出。

gcc demo4_条件编译ifdef-ifndef.c -o demo –DTEST

  1. 条件编译属于预处理指令,在预处理阶段就已经完成了判断,程序运行过程中不会再次判断。
  2. 下列语句可避免头文件中的内容重复加入编译:

demo1_编译过程

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

void hahaha(char *str);

int main()
{
	printf("hello world.\n");

	hahaha("hello world.\n");

	return 0;
}

 demo2_define宏定义

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

// 不带参宏
// #define PI
#define PI 3.1415926	// 预处理阶段中,将代码中所有宏进行替换。

// 带参宏(宏函数)
#define SUM(a,b) (a+b)

// 子函数
float func_sum(float a, float b);

int main()
{
	printf("hello world.\n");

	float r = 5.0;

	printf("面积: %f\n", PI*r*r);
	printf("周长: %f\n", 2*PI*r);

	float var1 = 1.2;

	float sum = func_sum(r, var1)*2;
	printf("sum: %f\n", sum);
	sum = SUM(r, var1)*2;
	printf("sum: %f\n", sum);

	return 0;
}

float func_sum(float a, float b)
{
	return a+b;
}

demo3_条件编译_if-else

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

int main()
{
#if 0
	printf("hello world.\n");
	printf("hello world.\n");
	printf("hello world.\n");
	printf("hello world.\n");
	printf("hello world.\n");
	printf("hello world.\n");
#else
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
#endif


	return 0;
}

demo4_条件编译ifdef-ifndef

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

int main()
{
#ifdef TEST
	printf("[%d]\n", __LINE__);
#endif

	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");
	printf("nihao 123.\n");

#ifdef TEST
	printf("[%d]\n", __LINE__);
#endif


	return 0;
}

demo5_使用自己的头文件

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
	// 包含系统头文件

#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
#include "myhead.h"
	// 包含自定义头文件

int main()
{
	printf("%d\n", ABC);

	return 0;
}

myhead.h

代码语言:javascript
复制
#ifndef _MYHEAD_H
#define _MYHEAD_H

#define ABC 1234

#endif
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档