嵌入式linux学习笔记:07_C语言_终

一、 Linux GCC编译器编译过程

1、一步到位:编译命令: gcc *** .c -o ***

                 GCC编译器
  高级语言     --------------->   二进制文件
   ***.c                            ***

2、细分每个编译过程,可以分为4个步骤

 高级语言       预处理              编译           汇编            链接      二进制文件

   ***.c        ------>     ***.i   ----->  ***.s   ----->  ***.o   ------>      ***

1)这些步骤如何处理?
其实这些步骤都是gcc编译器的参数来的,我们只需要查询ubuntu即可,–> man 1 gcc
-E Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output. //在预处理阶段之后就停止了,输出的文件***.i还是C语言文件。

-S Stop after the stage of compilation proper; do not assemble. The output is in the form of an assembler code file for each non-assembler input file specified. //在编译阶段之后就停止,不进行汇编,输出的文件***.s是汇编文件。

-c Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file. //在汇编阶段之后就停止了,但是不进行链接,输出的文件***.o是二进制文件。

2)举实例。

准备高级C语言: hello.c

预处理: 把程序中头文件、条件编译、宏定义处理。

  gcc hello.c -o hello.i -E       hello.i: C语言文件

编译:检查程序中语法是否正确

gcc hello.i -o hello.s -S         hello.s: 汇编文件

汇编: 将程序地址重新排列

   gcc hello.s -o hello.o -c        hello.o: 二进制文件

链接: 链接某些特定的库文件(标准C库、线程库…)

   gcc hello.o -o hello             hello:  二进制文件(可执行)  

二、自定义头文件

1、自定义头文件中可以写什么内容?
包含系统的头文件:#include <stdio.h>
进一步系列函数声明:int fun (int x, int y);
宏定义:#define
结构体声明:

struct mydata{
	xxx;
	yyy;
}

2、自定义头文件格式
1)文件后缀:****.h
2) 将.c文件中系统的头文件、函数声明、宏定义、结构体声明等全部写入头文件head.h

#ifndef _HEAD_H_   --> 如果没有定义_HEAD_H_
#define _HEAD_H_  --> 那么就定义_HEAD_H_
/* 系统头文件 */
#include <stdio.h>
/* 结构体声明 */
struct mydata{
       int a;
       char b;
};
/* 函数声明 */
int fun(int x,int y);
/* 宏定义 */
#endif   -> 结束定义

三、宏定义

1、宏定义是什么? -> 就是一个简单的替换
其实宏定义与枚举类型非常相似,都是可以使用某些常量变得有意义,宏定义除了可以替换int类型,还可以是字符/字符串…
2、宏定义处理的时间?
发生在编译的预处理阶段,而不是在运行时间。
3、宏定义如何写?
1)无参宏
#define OK 0 -> OK 等价于 0
#define ERROR -1
#define MUSIC “xxx.mp3”
实例:

#include <stdio.h>
#define OK 0
int main()
{
	int a = 0;
	if(a == OK)
		printf("helloworld\n");
	return 0;
}
预处理阶段之后:
stdio.h已经展开
int main()
{
	int a = 0;
	if( a == 0)
		printf("helloworld\n");
	return 0;
}

2)带参宏
#define XYZ(a,b) ab
int ret = XYZ(10,20);
ret = 10
20 =200;
int ret = XYZ(10+10,20);
ret = 10+10*20 = 210;

4、注意的事项
1)宏定义只是发生了预处理阶段,占用预处理时间,不占用运行时间。
2)宏定义既可以使用大写字母组成,也可以使用小写字母组成。

四、条件编译?

1、什么是条件编译?
根据条件的真假来编译代码,与注释类似的!

#if 1   -> 代表在endif之前的代码都需要编译!
       printf("appletree!\n");
#endif

2、实例

#include <stdio.h>
int main()
{
	#if 1
		printf("appletree!\n");//大家好才是真的好
	#endif

	#if 0
		printf("helloworld!\n");
	#endif
}
以下那内容会在预处理阶段全部删除!
#if 0
	printf("helloworld!\n");
#endif
//大家好才是真的好

五、关于预处理阶段细节问题

1、由于头文件中有函数声明,所以头文件必须在函数调用之前必须声明。
2、宏定义#define 头文件#include 条件编译#if 都是以#开头。
3、如果在同一行出现多个预处理语句,只会执行第一个预处理语句。
警告:warning: extra tokens at end of #include directive

六、多个.c文件的拆分

实例:
1、头文件:包含系统头文件、宏定义、函数声明、结构体声明

#ifndef _HEAD_H_
#define _HEAD_H_
#include <stdio.h>
typedef struct mydata{
	int a;
	int b;
}mydata;
int fun(int x);
#endif

2、包含main函数在内的.c -> 一般main.c里面只有main函数

#include "head.h"
int main(int argc, char *argv[])
{
	int a = 100;
	mydata A;
	A.a = 10;
	A.B = 20;
	int x = fun(a);
	if(x == OK)
		printf("helloworld!\n");
	my_fun(A);
#if 1
	printf("appletree!\n");
#endif
	return 0;
}

3、功能函数1

#include "head.h" -->每一个功能函数都需要包含头文件,因为功能函数也是用printf()函数!
int fun(int x)
{
	printf("x = %d\n",x)
	return x;
}

4、功能函数2

#include <stdio.h>
int my_fun(mydata B) //B = A
{
	printf("B.a = %d\n",B.a);
	printf("B.b = %d\n",B.b);
	retrun 0;
}

ok
C语言复习到此告一段落先

下一阶段 --> 进入linux 基础

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章