达内C语言UnixC(day01)

一.GNU编译器

  1. GCC的基本特点
    1)支持多种硬件架构
    x86-64
    Alpha
    ARM
    Motorola 68000
    MIPS
    PDP-10/11
    PowerPC
    System/370-390
    SPARC
    UAX
    2)支持多种操作系统
    Unix
    Linux
    BSD
    Mac OS X
    iOS
    Windows
    3)支持多种编程语言
    C/C++
    objective-C
    Java
    Fortran
    Pascal
    Ada
    4)查看版本信息
    早期:GCC = GNU C Compiler
    现代:GCC = GNU Compiler Collection
    版本:gcc -v

  2. 构建过程
    从源代码到可执行程序的构建过程:
    源代码 可执行程序
    预编译(编译预处理):头文件扩展,宏扩展
    gcc -E hello.c
    gcc -E hello.c -o hello.i
    汇编:将高级语言代码翻译成汇编语言代码,得到一个汇编语言文件
    gcc -S hello.i ——>hello.s
    编译:将汇编语言代码翻译成机器语言代码,得到目标模块
    gcc -c hello.s ——> hello.o
    链接:将所有目标模块及其所依赖的各种库连接成一个整体,得到可执行程序
    gcc -hello.o <其他目标木块___> -l<其他库> -o hello
    代码:hello1文件夹

  3. 常见文件名后缀
    .h ->C语言代码头文件
    .c ->预处理前的C语言源代码文件
    .i ->预处理后的C语言源代码文件
    .s ->汇编语言文件
    .o ->目标模块
    .a ->静态库文件
    .so ->动态库(共享库)
    习惯上可执行程序不带后缀

  4. 编译选项
    gcc [选项] [参数] 文件
    gcc -E -o hello.i hello.c
    -o:指定输出文件的路径
    -E:预编译,缺省输出到屏幕,用-o选项可以指定输出到文件
    -S:汇编,将高级语言源文件汇编成汇编语言源文件
    -c:编译,将汇编语言源文件编译成机器语言目标模块
    -Wall:报告所有警告
    代码:wall文件夹
    -Werror:将警告视作错误
    代码:werror.c
    -x:显示指明源代码所用编程语言
    代码:cpp.c
    -g:产生调试信息
    -O0/O1/O2/O3:优化策略,
    O0表示不做优化,
    O1表示缺省优化策略,在空间和时间上取选择尽可能折中的优化处理
    O2表示牺牲空间换取时间(追求快)
    O3表示牺牲时间获取时间(追求占用内存小)

  5. 头文件
    1)头文件里放什么?
    A.头文件卫士
    a.h
    /
    b.h c.h -钻石包含
    \ /
    d.c
    在编译d.c的过程中会对a.h中定义的宏或数据类型等报重定向错
    在a.h中加入头文件爱你卫士:
    #ifndef A_H
    #define A_H
    只被编译器处理一次的代码…
    #endif //A_H

    #pragma once
    B.包含其他头文件爱你
    a.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    b.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    c.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>


		common.h
			#include <stdio.h>
			#include <stdlib.h>
			#include <string.h>
			....
		a.c
			#include "common.h"
		b.c
			#include "common.h"
		c.c
			#include "common.h"
	C.宏定义
		geom.h
			#defin	PAI 3.14159
			...

	D.自定义类型
	 	geom.h
			struct Circle {
				double x;
				double y;
				double r;
			}
	E.类型别名
		types.h
			typedef unsigned long long ULL;
			typedef int* (*PFOO)(char*, short const*);
			...
	F.声明外部变量
		glable.c
			double e = 2.71828
			...
		glable.h
			extern double e;
			...
	G.声明函数
		geom.h
			double Circle_area(double r);
			...
		一个头文件(.h)可能不会被多个源文件(.c)包含,写在头文件里的函数定义
		也会因此被预处理器扩展到多个包含该头文件的源文件中
		并在编译阶段被编译到多个不同的目标模块中,这将导致链接错误
		mutiple definition, 多重定义。因此一般情况下,要避免将函数定义写到头文件中。
		a.h
			int foo(int a, int b) {return a + b};

   -----------------------------------
	 	a.c
			int foo(int a, int b) {return a + b};
		a.h
			int foo(int a, int b);
  1. 去哪里找头文件呢?
    / 系统目录:/usr/include等目录
    头文件位于 -当前目录
    \附加目录:通过gcc的-I选项指定
    尖括号包含:如:#include <calc.h>
    附加目录——>系统目录
    双引号包含:如:#include “calc.h”
    附近目录——>当前目录——>系统目录
    头文件的系统目录:
    /usr/include —— 标准库
    /usr/loacl/include —— 第三方库
    /usr/lib/gcc/i686-linux-gun/<版本号>/include —— 编译器相关库
    /usr/include/C++/<版本号> —— 标准C++库
    代码:calc/

6.预处理指令
#include:将指定的文件内容插至此指令处
#define:定义宏
#under:删除宏
#if:如果
#ifdef:如果宏已定义
#idndef:如果宏未定义
#else:否则,与#if/#ifdef/#ifndef配合使用
#elif:否则如果,与#if/#ifdef/#ifndef配合使用
#endif:结束判定,与#if/#ifdef/#ifndef配合使用
#error:产生错误,提前终止预处理过程
代码:error/
#warning:产生警告,不会终止预处理过程
代码:error/
#line:显式指定下一行行号
代码:line/
#pragma:设置编译器的状态或者指示编译器的操作
#pragma once ——> 一次性编译
#pragma GCC dependency <被依赖文件> ——> 指定文件依赖
作用:如果被依赖文件比包含该预处理指令的文件新,则产生警告
#pragma GCC posion <语言禁忌>
作用:如果在代码中出现语言禁忌,则产生编译错误
#pragma pack(1/2/4/8—) ——> 字节对齐
代码:once/

  1. 预定义宏
    BASE_FILE :表示正在被编译的文件名
    FILE :所在文件的文件名
    a.h
    BASE_FILE ——> b.c
    FILE ——> a.h
    b.c
    #include “a.h”
    gcc -c b.c
    LINE :所在行号(受#line影响)
    FUNCTION :所在函数的函数名
    func :等价于__FUNCTION__
    DATE :编译日期
    TIME :编译时间
    INCLUDE_LEVEL :包含的层数,从0开始
    a.h
    INCLUDE_LEVEL ——> 2
    b.h
    INCLUDE_LEVEL ——> 1
    #include “a.h”
    c.c
    INCLUDE_LEVEL ——> 0
    #include “b.h”
    gcc -c c.c
    __cplusplus :C++有定义,C无定义
    代码:predef/
  2. 环境变量
    C_INCLUDE_PATH(C_PATH):指定C语言头文件的附加目录,相当于gcc命令的-I选项
    CPLUS_INCLUDE_PATH:指定C++语言头文件的附加目录,相当于g++命令的-I选项
    LIBRARY_PATH:指定链接时查找库的目录
    LD_LIBRARY_PATH:在运行的时候查找动态库的目录
    export 环境变量名=环境变量值 \ _____
    export 环境变量名=KaTeX parse error: Expected 'EOF', got '#' at position 67: …hrc 定义头文件的三种方式 #̲include "/home/…C_INCLUDE_PATH:/home/tarena/include
    export C_PATH=$C_INCLUDE_PATH:/home/tarena/include
    同时构建多个项目,容易发生版本冲突
    gcc … -I/home/tarena/include
    既不需要修改源程序,也不会发生版本冲突,推荐使用此方法

二:静态库和动态库

1.库
big.c ——> big.o ——> big

text.c ——> text.o \ 实现功能 使用功能
image.c ——> image.o | 库 + main.o <—— main.c
video.c ——> vedio.o / \ /
main.c ——> main.o exe

2.静态库

  1. 静态库本质就是将多个目标文件(.o)打包成为一个文件。链接静态库就是将库中被调用的代码复制到调用模块中
    静态库占用空间比较大,库中代码一旦修改,必须重修链接。使用静态库的代码在运行时无需依赖库,且执行效率高
  2. 静态库的形式:libxxx.a
  3. 构建静态库
    ar -r libxx.a xxx.o yyy.o zzz.o … 把后边所有.o文件房贷.a文件
  4. 链接静态库
    gcc … -lxxx -L<库路径> -o …
    gcc … -lxxx … <—— LIBRARY_PATH
  5. 调用静态库:运行时完全不调用静态库中代码。
    代码:static/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值