Linux后台开发系列之「07.gcc 编译基础」

Linux 的GCC的编译过程及方式 Linux下GCC越详细越好的啦 阅读详情

gcc

版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处!

本文摘要

这篇文章主要介绍 gcc 相关的技术,包括以下 8 个方面:

  1. gcc 简介
  2. gcc 参数
  3. gcc 编译 C 程序 4 个过程
  4. 实验一:编译多个 C 程序
  5. 实验二:打包静态库并调用
  6. 实验三:打包动态库并调用
  7. g++ 简介
  8. 结语

我是一个比较强调实践的人,我写的技术文章也是,还希望看完有兴趣一定要实践,出错不可怕,害怕出错才可怕呢。

gcc 简介

GCC(GNU Compiler Collection) GNU 编译器套件,它是 GNU 项目中符合 ANSI C 标准的编译系统,能够编译用 C,C++,Object - C 等语言编写的程序,同时 gcc 也是一个交叉编译器,特别适用于不同平台的嵌入式开发,例如可以在 x86 下编译 ARM 程序。

gcc 规定的部分文件名

gcc 官方规定了下面的一些文件名,有必要了解一下:

  • c: C 源程序
  • cc/cxx: C++ 源程序
  • m: Objective-C 源程序
  • i: 预处理的 C 源程序
  • ii: 预处理的 C++ 源程序
  • s/S: 汇编语言源程序
  • h: 预处理头文件
  • o: 目标文件
  • a: 静态库文件
  • so: 动态库文件

HelloWorld

下面以编译 hello.c 为例简单介绍 gcc 的基本使用方法:

// hello.c
#include <stdio.h>

int main(void) {
    printf("Hello World\n");
    return 0;
}

编译指令:

gcc hello.c -o hello

这句话的意思是编译 hello.c 文件,[ -o ] 指定了编译后的可执行文件名为 hello,之后我们就可以直接执行 hello。当然还有许多复杂的可选项可以使用,下面来做个参数的大体介绍,更复杂的参数用法还需要在实际工作中去总结。

gcc 参数

在使用 GCC 编译器的时候,我们必须给出一系列必要的调用参数和文件名称,如下:

gcc [options] [filenames]

其中 options 是编译器所需要的参数,filenames 是相关的文件名称。

gcc 参数分类

gcc 的参数有很多,我们不需要全部都学会,也没有那个精力,我们先大概看下基本的分类:

  • 通用参数
  • C 语言参数
  • C++ 参数
  • Object - C 参数
  • 语言无关参数
  • 警告参数
  • 调试参数
  • 优化参数
  • 预编译参数
  • 汇编参数
  • 链接参数
  • 机器依赖参数

可以看出类别还是很多的,但是我们平常使用的参数也不是很多,把经常用的学会基本就够用了,不懂的参数可以通过 man gcc 来查找,那下面就来介绍下常用的一些参数。

常用参数

哪些是常用的参数呢?告诉你一个方法,man gcc 手册中前面列出的基本就是常用的了,我总结了下面这些。

1. 编译过程参数

下面几个编译过程比较常见,例如 [-o],[-c],[-l] 等:

[-c]:编译不链接,生成 .o 文件
[-S]:编译不汇编,只生成汇编代码
[-E]:只预编译
[-g]:包含调试信息
[-o file]:指定输出文件名称
[-l dir]:添加头文件路径

2. 动态库和静态库参数

我们经常需要静态编译,打包动态库 .so,这些参数也很有用:

[-static]:让 gcc 静态编译
[-Ldir]:添加搜索库文件的路径
[-shared]:生成动态库文件,用于打包动态库
[-fPIC]:生成位置无关的代码,用于打包动态库

3. 警告参数

我们有时需要开启 gcc 的编译警告来帮我们找找 bug,这时下面的参数就很有用了:

[-w]:关闭所有警告
[-Wall]:发出 gcc 提供的所有有用的警告
[-pedantic]:发出 ANSI C 的所有警告

4. 优化参数

为了让我们的程序运行的更快,在发布的时候经常使用优化参数来优化程序:

-O[level]:优化等级,一般只是项目最后时候才用

了解了常用的参数,下面来学习下 gcc 的编译的大体过程,顺便练习下部分的参数,了解它可以让我们更加清楚编译型语言的编译过程。

gcc 编译 C 程序的 4 个过程

对于编译型语言,例如 C/C++ 来说,gcc 的编译 hello.c 整体分为以下 4 个步骤:

  1. hello.c 源代码经过编译器预处理(Pre-Processing)生成预编译文件 hello.i
  2. hello.i 预编译文件经过编译器编译(Compiling)生成汇编文件 hello.s
  3. hello.s 汇编文件经过编译器的汇编器汇编(Assembing)生成目标文件 hello.o
  4. 所有的目标文件,这里只有一个 hello.o 被链接器链接(Linking)生成最后的可执行文件 hello,默认输出的名字是 a.out ,但是我们指定了输出名为 hello

如下图所示:

4 个过程

光说的话还加深不了你的理解,那么我们就来实际编译看看结果怎么样。

1. 预处理 hello.c

使用下面的命令来预处理 hello.c 生成 hello.i:

gcc -E hello.c -o hello.i

预处理就相当于将源文件展开了一样,你可以使用 cat hello.i 查看下里面的内容,因为 hello.i的内容很多,这里只列出开头的一部分:

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
...

2. 编译 hello.i

我们使用下面的命令来将 hello.i 编译成 hello.s:

gcc -S hello.i -o hello.s

我们看下 hello.s 的内容,这里也只列出一部分,都是汇编代码:

    .file   "hello.c"
    .section    .rodata
.LC0:
    .string "Hello World"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
...

3. 汇编 hello.s

我们使用下面的命令来将 hello.s 汇编成 hello.o 目标文件:

gcc -c hello.s -o hello.o

这时候生成的 hello.o 就是二进制的文件了,我们可以看看它的开头部分内容,可以看到在我的 Ubuntu 上显示是 「ELF(Executable and Linkable Format) 可执行链接文件格式」的文件,说明这个文件可以被链接:

ELF>�@@
UH��H�=��]�Hello WorldGCC: (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005zRx

下面就进行最后一步,链接 hello.o。

链接 hello.o

我们使用下面的命令来将 hello.o 链接成最后的 hello 可执行文件:

gcc hello.o -o hello

然后可以执行了:

./hello

# 结果
Hello World

至于可执行文件 hello 的内容,你应该是知道的,因为它是由多个目标文件链接而成的,既然目标文件是二进制的,毫无疑问可执行文件肯定也是二进制的,不信给你看看 hello 的开头:

^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^C^@>^@^A^@^@^@p^E^@^@^@^@^@^@@
^@^@^@^@^@^@^@?^Y^@^@^@^@^@^@^@^@^@^@@^@8^@ ^@@^@^]^@^Z

你看的懂不,我反正是看不懂 :),不过不要紧,知道他是编译最终生成的二进制可执行程序即可。

当你成功打印出 Hello World 说明你已经成功将整个编译过程分步骤完成了,了解了这个分步的编译过程,可以更好的使用 gcc,因为你知道 gcc 在编译 hello.c 的时候每一步大概做了些什么,使用起来更加有信心了,这也是了解一些原理的必要性。

实践:3 个使用 gcc 的实验

实践是检验真理的唯一标准,写程序这个东西光看看怎么行,不动手基本就是过眼云烟,那些能够在看完博客之后立马去实践的人才能进步的更快。废话不多说,下面就介绍 3 个基本的使用 gcc 来编译程序的实验,这 3 个实验都用到下面 2 个文件:

这个文件是含有 main 的主程序文件:

// main.c
#include <stdio.h>

// 声明 add 函数在外部有定义,不加声明会产生警告
extern int add(int a, int b);

int main(void) {
    printf("%d\n", add(1, 2));
    return 0;
}

这个文件里面只有一个 add 函数:

// add.c
int add(int a, int b) {
    return a + b;
}

先来看最简单的第一个实验吧。

1. gcc 编译两个程序相互调用

这个实验要求是这样的:让 main.c 调用 add.c 里面的函数,那么如何使用 gcc 来编译他们呢?

我们前面已经了解了 gcc 编译程序的 4 个基本步骤,知道每个源文件最后都会被编译成目标文件,然后被链接器链接到一起生成最后的可执行文件,因此可以推断出编译器先分别生成 main.o和 add.o 然后将他们链接到一起生成最后的可执行文件,所以编译命令如下:

gcc main.c add.c -o main

直接将这两个文件一起编译即可,然后执行:

./main
# 1 + 2 = 3
3

输出 3 则表明你第一个实验已经成功了,是不是很简单,别放松,来看第二个实验。

2. gcc 编译静态库并调用

在 Linux 我们经常调用别人给我们提供的静态库,静态库本质上就是一系列函数的二进制表示的集合,不过不包含 main 函数,因此只能作为模块提供给别人使用,静态库名称通常为 libname.a。下面就来介绍如何将 add.c 打包成一个静态库来供 main.c 来调用,一共有 3 步:

编译出 add.o

因为静态库里面都是已经编译好的函数,因此我们需要先将 add.c 编译成可以链接的 ELF 格式的目标文件:

gcc -c add.c -o add.o

ar 打包静态库

我们使用 ar 这个命令来将 add.o 打包成 libadd.a,参数 [-crv] 记住即可,如需了解直接 man ar,注意文件的顺序哦,静态库文件名在前,目标文件在后,我实验的时候都搞错了 = =:

ar -crv libadd.a add.o

使用静态库 libadd.a

那么如何将一个静态库在编译的时候静态链接到 main.c 的模块上呢,使用下面的命令,[-L./]表示将当前目录加到静态库的搜索路径:

gcc main.c -L./ libadd.a -o main

之后执行,输出 3 表明成功调用 libadd.a 里面的 add 函数了:

./main
# 1 + 2 = 3
3

静态库实验其实就 3 步,不是很复杂,动态库也不难,一起来看看吧。

3. gcc 编译动态库并调用

动态库与静态库有些异同:

  1. 相同:动态库也是函数的二进制的集合
  2. 不同:动态库在程序运行的时候动态加载到内存,而静态库在编译时期就整合到最后的可执行文件中

之所以叫动态库,就是因为它能够在一个程序运行的时候动态的加载到内存中,这个动态库在内存中也是共享的,在 Linux 下动态库的常用名称为:libname.so.主版本号.次版本号.发行号,关于动态库的其他特点不是本次介绍的重点,需要了解的可以去 Google 搜索,下面还是介绍如何打包和使用一个动态库,分为 4 个步骤:

编译位置无关的目标文件 add.o

为何需要编译位置无关呢?因为动态库动态加载到内存中的位置是不确定,所以需要位置无关,使用 [-fPIC] 来编译出一个位置无关的目标文件:

gcc -fPIC -c add.c -o add.o

打包成动态库

使用下面的命令来将 add.o 打包成 libadd.so 动态库,这里就不加版本号了:

gcc -shared add.o -o libadd.so

链接到 main.o

这里的链接不是实际的链接,这里只是告诉 main.o 在运行的时候需要动态加载 libadd.so 这个动态库而已:

gcc main.c -L. libadd.so -o main

运行 ./main

注意,如果你直接执行 ./main 的话,你应该会得到下面这个错误:

./main: error while loading shared libraries: libadd.so: cannot open shared object file: No such file or directory

这是为什么呢?你可能会想我不是将 libadd.so 告诉了 main.so 了么,为何还报错误,其实这个错误的原因是:main 运行时,当要加载 libadd.so 这个动态库时,没有找到它。为何没有找到?因为你没有将这个动态库加到系统的环境变量指定的目录中。

如何解决这个错误呢?

解决方法:将 libadd.so 拷贝到系统的库目录下:

sudo cp libadd.so /usr/lib/libadd.so

之后再执行:

./main
# 1 + 2 = 3
3

如果成功的打印出了 3,则说明已经成功调用了动态库了。

这样,我们就了解了如何相互调用程序,如何打包并调用静态库和动态库这 3 个实验,还希望你一定要亲自动手去实践下,这其中每一个命令我都有亲自验证过,把这些东西都变为自己的,相信我,你肯定会有很大收获的。

介绍完了 gcc,不能不了解下它的好朋友 g++ 啊,再一起简单了解下吧,有谁会嫌弃自己懂得多呢,你说 4 不 4 :)

g++ 简介

既然编译 C 语言用 gcc ,那编译 C++ 用 g++ 可以说是很恰当的表达方法了,下面看看如何编译一个 C++ 的 hello.cc 吧,跟 gcc 编译 C 语言几乎相同:

// hello.cc
#include <iostream>

int main(void) {
    std::cout << "Hello World" << std::endl;
    return 0;
}

使用下面的命令来编译:

g++ hello.cc -o hello

是不是几乎相同,但这篇文章的重点不是 g++,就简单介绍到这吧,有兴趣的可以去查找相关的资料。

结语

实践是检验真理的唯一标准!

深入Linux下的GCC编译器:从入门到精通 GCC最初作为GNU操作系统的官方编译器被开发,现在已经成为最流行的编译器之一。它被设计为可移植的,并且可以在多种架构上编译出高效的代码。GCC通过预处理器、编译器、汇编器和链接器四个阶段处理代码,将源代码转换成机器语言。在深入探讨静态和动态链接之前,我们首先需要了解链接的概念。链接是指在编译过程的最后阶段,编译器或链接器将各个编译单元(如目标代码、库文件等)合并为一个单一的可执行文件的过程。 阅读详情

相关推荐

Linux应用开发基础知识——交叉编译与gcc编译(一)

源文件需要经过编译才能生成可执行文件。在 Windows 下进行开发时,只需 要点几个按钮即可编译,集成开发环境(比如 Visual studio)已经将各种编译 工具的使用封装好了。Linux 下也有很优秀的集成开发工具,但是更多的时候是 直接使用编译工具;即使使用集成开发工具,也需要掌握一些编译选项。PC 机上的编译工具链为 gcc、ld、objcopy、objdump 等,它们编译出来的 程序在 x86 平台上运行。

嵌入式技术开发 3783

后台编译linux内核代码的方法

后台编译内核个人吐槽最近在AWS公有云虚拟机上开发内核驱动,写完内核驱动之后需要使用kmemleak检查内存泄漏,然后通过查阅资料发现,需要对内核进行重新编译。但是由于编译内核需要接近2个小时,且自己跟AWS虚拟机连接不稳定,一断开之前的编译就前功尽弃,所以查询了一下如何进行后台编译内核。操作make > make.log 2>&1 &该操作是将make结果输入到同一目录下的make.log文件中m

绯浅yousa的笔记 2098

技术解析:ChangeFormer——基于Transformer的孪生网络在遥感变化检测中的创新应用

本文深入解析了ChangeFormer模型在遥感变化检测中的创新应用,该模型基于Transformer架构和孪生网络(Siamese Network),显著提升了变化检测的精度和效率。通过详细的技术实现和实战经验分享,展示了其在建筑物变化、森林监测等场景中的卓越表现,为相关领域的研究和应用提供了有力工具。

weixin_29102619的博客 496

用gcc生成.a静态库和.so动态库

删除静态库文件试试公用函数 hello 是否真的连接到目标文件 hello 中了。我们将文件 libmyhello.so 复制到目录/usr/lib 中,再试。输入以下命令得到动态库文件 libmyhello.so。输入以下命令创建静态库文件libmyhello.a。先运行 gcc 命令生成目标文件,再运行它看看结果。在终端进行文件的创建,并用gedit打开编辑。在终端进行文件的创建,并用gedit打开编辑。在终端进行文件的创建,并用gedit打开编辑。用ls命令检查是否生成了hello.o文件。

Turing_kun的博客 191

基于文件通信的QMT量化交易信号桥接方案设计与实现

在量化交易系统开发中,进程间通信(IPC)是连接不同计算模块、实现策略逻辑与交易执行解耦的关键技术。其核心原理在于允许运行于独立环境或进程的程序安全、可靠地交换数据。文件系统通信作为一种经典的IPC方法,因其实现简单、跨平台兼容性好且数据可持久化,在非高频场景下具有重要技术价值。它尤其适用于需要将外部复杂计算环境(如配备丰富数据科学库的Python环境)与专用交易终端(如迅投QMT)集成的应用场景。通过约定文件路径与数据格式,外部程序可将包含交易指令的JSON信号文件写入特定目录,而交易终端通过轮询或监听机

weixin_28678151的博客 417

ICCompiler II实战:从NDM生成到APR流程的完整避坑指南

本文是一份针对ICCompiler II(ICC II)后端物理实现流程的实战避坑指南。文章详细解析了从NDM库生成、设计初始化、布局规划到时钟树综合与布线的完整APR流程,重点分享了各环节的常见陷阱、精细化配置命令与调试经验,旨在帮助工程师高效达成PPA目标,确保设计一次成功。

p4q5r6s7t的博客 531

Linux基础与命令,vim编译器

vim编译器是从vi基础上发展而来的一种文本编译器,使用方法:vim 文件名称,文件存在则打开,不存在则创建后打开。

Chen_Fn的博客 239

Python实战:高效稳定采集微信视频号评论的API爬虫方案

网络爬虫是数据采集领域的核心技术,其原理是通过程序模拟浏览器行为,向目标服务器发送HTTP请求并解析响应数据,从而自动化获取网页或接口中的信息。这项技术的核心价值在于能够高效、批量化地收集公开数据,为市场分析、舆情监控和竞品研究提供数据基础。在社交媒体分析、电商价格监控等应用场景中,爬虫技术尤为重要。针对微信视频号这类动态加载的复杂应用,传统的GUI自动化工具(如影刀RPA)常面临性能瓶颈和风控挑战。本文聚焦于通过Python实现**无感采集**,直接与后端**API接口**交互,构建稳定高效的评论数据采集

weixin_30899023的博客 328

linux操作系统基础(含C编译,make编译)

Linux终端快捷键。

weixin_46287157的博客 1713

Kali使用Metasploit内、外网渗透windows系统

Metasploit是一个免费的、可下载的框架,通过它可以很容易地获取、开发并对计算机软件漏洞实施攻击。它本身附带数百个已知软件漏洞的专业级漏洞攻击工具。当H.D. Moore在2003年发布Metasploit时,计算机安全状况也被永久性地改变了。 一、(内网渗透)内网英文缩写WAN;内网又称局域网 局域网的覆盖范围一般是方圆几千米之内,其具备的安装便捷、成本节约、扩展方便等特点使其在各类办公室内运用广泛。局域网可以实现文件管理、应用软件共享、打印机共享等功能,在使用过程当中,通过维护局域网网...

QQ670663的博客 2万+

Reality Capture控制点修复/合并模型

通过增加控制点/修改对齐设置参数来修复模型被分为两个部分的解决方法

草履虫建模的博客 5241

下班关机进行后台编译

在使用SecureCRT等终端工具登录服务器后,如果退出当前登录(或者关闭SecureCRT)或导致当前正在执行的任务终端。例如正在编译Android时,下班需要关机,将会导致编译任务终止。

Yxx8066的博客 576

华为OD机试真题 新系统 - WIFI设备网络规划 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 2017

Linux下的GCC编译器

GCC是GNU公社的一个项目,它是GNU Compiler Collection的缩写,起初,GCC只是一个C语言编译器(GNU C Collection),随着开发者的加入,GCC已扩展为可以编译C、C++、Java、Objective-C等多种编程语言的编译器集合了。如今的GCC也具有了交叉编译的功能,即在一个平台上编译另一个平台的代码。所谓编译器,可以简单地将其理解为“翻译器”。

asddrsq的博客 3206

KRC文件——编程中的重要文件

KRC文件是指KUKA机器人控制器(KUKA Robot Controller)所使用的文件格式。KUKA是一家知名的机器人制造商,其机器人控制器通过KRC文件来管理和执行机器人程序。KRC文件包含了机器人的运动指令、逻辑控制、传感器数据等信息,以及与机器人相关的配置参数。这些文件通常使用KRL(KUKA Robot Language)编写,是一种特定的编程语言。KRC文件具有扩展名为.krc的格式,可以在KUKA机器人控制器上直接加载和执行。

TechProX的博客 2971

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

linux基础篇(一)——GCC和Makefile编译过程

gcc的使用方法 gcc [选项] 文件名 一个c/c++文件要经过预处理、编译、汇编和链接才能变成可执行文件。 (1)预处理 C/C++源文件中,以#开头的命令被称为预处理命令,如"#include"、宏定义命令"#define"、条件编译命令"#if、#ifdef"等。预处理是将包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到......

sinat_31039061的博客 1万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Linux 编译器 gcc 与 g++

gcc全称 GNU Compiler Collection,是 GNU 项目开发的一款功能强大的编译器集合。它最初是作为 GNU C 语言编译器而开发的,随着不断发展,如今已支持 C、C++、Objective-C、Fortran、Ada 等多种编程语言。g++实际上是gcc的一个 “马甲”,它是gcc专门用于编译 C++ 代码的前端工具,通过调用gcc的底层编译功能,针对 C++ 语言的特性进行处理,以确保 C++ 代码能够被正确编译。1.1 make 工具。

zzh_Zao的博客 2741

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

零基础上手gcc/g++:Linux编译轻松学

首先我们来学习一下gcc、g++二者之间的关系gcc英文全称为:GUN C Compiler,是GCC中的c编译器g++英文全称为:GUN C++ Compiler,是GCC中的c++编译器。gcc和g++ 两者都可以编译c和cpp文件,但存在差异。gcc在编译cpp时语法按照c来编译但默认不能链接到c++的库(gcc默认链接c库,g++默认链接c++库)。g++编译.c和.cpp文件都统一按cpp的语法规则来编译。所以一般编译c用gcc,编译c++用g++。

2301_80774875的博客 2298

Linux GCC 编译详解

介绍 linux 下 GCC 的使用

weixin_45004203的博客 5450

Linux基础 gcc编译器

当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径,此时就需要系统动态载入器(dynamic linker/loader),对于elf格式的可执行程序,是由ld -linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段,环境变量LD_LIBRARY_PATH /etc/ld.so.cache文件列表—/lib/,/usr/lib目录找到库文件后将其载入内存。库既可以是静态的也可以是动态的。链接器将多个目标文件链接成一个完整的,可加载的,可执行的目标文件。

wangdsh的博客 3260

【Linux】GCC编译器(七)

GCC的通用性使得它在不同的操作系统和平台上都能够使用,包括Linux、Unix、macOS等,这使得开发者可以使用同一套工具在不同的环境下进行开发,提高了开发的效率和一致性。除此之外,GCC已经成为了许多开发环境和工具链的标准组件,许多集成开发环境(IDE)和构建工具都提供了对GCC的支持,这使得开发者可以更轻松地使用GCC进行开发和构建。此外,GCC拥有丰富的功能和选项,支持多种编程语言,包括C、C++、Objective-C、Fortran等,可以满足各种不同项目的需求,从小型工具到大型软件项目。

hdz_wiz_csdn的博客 2371

【Linux】环境基础开发工具的使用之gcc详解(二)

上一篇文章中我们讲解了Linux下的vim和yum的工具的使用,今天我们将在上一次的基础上进一步的讲解开放工具的时候。

m0_64826370的博客 1720

Linux编程及GCC编译器

a.out 这个文件的命名是 GCC 编译器自动命名的,在使用 gcc 命令的时候加上-o 来指定生成的可执行文件名字,比如编译 main.c 以后生成名为“main”的可执行文件。当编译完成以后会生成一个 a.out 文件,这个 a.out 就是编译生成的可执行文件,执行此文件看看是否和我们代码的功能一样,执行的方法很简单使用命令:“./+可执行文件”,比如本例程就是命令: ./a.out。-c: 只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。

hackerbird的博客 917

linux GCC编译C程序

linux GCC编译C程序 GCC已不再是主要针对GNU项目自身的软件的小型C语言编译器了。如今,它已支持了许多不同的语言,包括C、C++、Ada、Fortran、Objective C,甚至还有Java。 利用gcc原理上是经过两步编译的,分别生成目标代码和Linux可执行程序。 1. 编译单个源文件 hello_linux.c #include<stdio.h> #incl...

SkYe's Blog 1329

Linux编译器gcc的使用

Linux编译器gcc的使用

l_shadow_m的博客 2536

嵌入式Linux应用开发-基础知识及GCC 编译器的使用

要编译出能在 ARM 平台上运行的程序,必须使用交叉编译工具 xxx-gcc、xxx-ld 等(不同版本的编译器的前缀不一样,比如 arm-linux-gcc),下面分别介绍。链接就是将上步生成的 OBJ 文件和系统库的 OBJ 文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件,用到的工具为 ld 或 collect2。多数情况的多数机器上,可以看见,除了 main.o、sub.o 两个文件外,还链接了启动文件 crt1.o、crti.o、crtend.o 、crtn.o,

华为奋斗者精神 2930
上一篇: Linux后台开发系列之「06.Shell 编程基础
下一篇: Linux后台开发系列之「08.15 个 gdb 调试基础命令」
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值