zoukankan      html  css  js  c++  java
  • Linux-C

    Linux-C

    1. C程序
     1.1 最简单的C程序hello.c
     1.2 多个源码文件
     1.3 头文件(include)和目录
     1.4 C预处理器
     1.5 连接库
     1.6 共享库
      1.6.1 列出共享库的依赖关系
      1.6.2 ld.so怎样找到共享库
      1.6.3 环境变量LD_LIBRARY_PATH
    2. 编译管理工具make
     2.1 make常用选项
     2.2 make常用变量
     2.3 makefile常见的宏
     2.4 makefile常规目标
     2.5 教程手册
     2.6 GNU autotools 安装步骤
     2.7 configure 常用的选项
     2.8 Autotools的基础知识(Gentoo开发人员手册)
     2.9 更多相关链接
    3. 调试器gdb
    4. Lex和Yacc
    5. 脚本语言
    6. Java
    

    1. C程序

    最基本的生成过程: 代码,编译,运行. 编译就会用到C编译器。
    来自LLVM项目的新的C编译器clang越来越流行;但大部分主流的Unix系统上仍然是GNU C编译器gcc。

    1.1 最简单的C程序hello.c

    #include <stdio.h>

    main() {
        printf("Hello, World. ");
    }

    源码文件(.c); -o编译为可执行文件(.out); 运行
    编译 $ cc hello.c
    会产生 a.out 的可执行文件
    指定文件名编译,增加-o选项
    $ cc -o hello hello.c
    运行 $ ./a.out

    1.2 多个源码文件

    多个源码文件(.c); -c编译为对象文件(.o); -o连接为可执行文件; 运行
    main.c, aux.c ...
    使用-c选项给每个文件生成对应的对象文件
    $ cc -c main.c
    $ cc -c aux.c
    产生对象文件: main.o, aux.o ...
    对象文件是一种二进制文件。
    使用连接器将对象文件组合为可执行文件
    $ cc -o myprog main.o aux.o

    更复杂的项目, 更多个源码文件, 需要使用make

    1.3 头文件(include)和目录

    保存类型和函数声明的附加文件,比如stdio.h
    Unix默认的include目录是/usr/include, 编译器一般就看这里, 除非你指定其他地方。
    $ cc -c -I /usr/junk/include text.c
    使用-I选项指定头文件路径

    #include <stdio.h>
    #include "myheader.h"
    <*.h>头文件在系统路径;
    "*.h"表示头文件不在系统的include目录中, 通常表示它与源码在同一目录。

    1.4 C预处理器

    并不是C编译寻找头文件, 而是C预处理器(C preprocessor, cpp)。
    C预处理器是编译器在解析程序之前先在源码上运行的一个东西。
    C预处理器会将源码重写成一种编译器能理解的形式,使源码更易读(并提供捷径)。

    源码中的预处理器命令叫做指令(directive), 以#开头, 分为如下三种。
    inculde文件: #inculde * 使预处理器将整个文件包含进来。
    宏定义: #define BLAH something 预处理器会将源码中所有BLAH替换为something, 约定宏名为大写。
    条件: 可用 #ifdef, #if, #endif 来对代码进行分快。
    #ifdef MACRO 指令用于检查宏MACRO是否已定义;
    #if condition 则检查condition 是否非零。当预处理器发现if语句后的条件为false时,就不会将#if 和 #endif 之间的代码交给编译器。

    注:也可以不在源码中定义宏,而使用编译器的-D选项,(-DBLAH=something)(#define BLAH something)
    C预处理器并不懂C的任何语法,变量,函数或其他元素,它只看宏和指令。
    Unix上的C预处理器是cpp,也可以用 gcc -E 来运行,不过一般很少需要单独运行预处理器。

    1.5 连接库

    所谓C库,就是一些已编译好的,通用的,可让你添加到自己程序的函数。例如很多可执行程序会用到的数学库...
    库主要实在连接的时候(连接器从对象文件产生可执行程序时)发挥作用。
    默认的库文件路径(/usr/lib)

    使用编译器的 -l 选项连接库文件。
    例如这里用到一般的gobject库文件是libgobject.a, 而库的名字是gobject. 所以完整的连接和编译如下:
    $ cc -o textp textp.o -lgobject

    使用 -L 选项指定库文件路径
    例如库文件不在常规位置,而在/usr/junk/lib/libcrud.a
    $ cc -o testp testp.o -lgobject -L/usr/junk/lib -lcrud

    在库中搜索特定的函数,使用nm命令,nm libjobject.a, (可能要用locate命令查找libjobject.a, 很多发行版会将库放在/usr/lib特定的子目录)

    1.6 共享库

    名称以.a结尾的库是静态库。
    连接静态库时,连接器会将库文件中的机器码复制到程序中。最终的可执行程序不需要该库也能运行。
    使用静态库的优点是简单方便,不依赖环境。缺点也很明显:

    •   过多使用静态库,会使文件越来越大,占用空间。
    •   若库里的函数更新了,原有程序不会改变,需要重新编译才能使用到最新的库函数。

    共享库即可解决这些问题。引用共享库的程序只会在需要时才将该库加载到内存中。而且多个进程可以共享内存中同一个共享库。
    使用共享库的的缺点是管理困难,连接复杂。但只需搞定如下问题:

    •   如何列出程序需要的共享库;
    •   程序如何查找共享库;
    •   如何让程序连接共享库;
    •   常见的共享库陷阱。

    1.6.1 列出共享库的依赖关系

    共享库和静态库通常放在同一个地方,Linux的两大标准库目录/lib, /usr/lib. 其中/lib是不应该包含静态库的。
    共享库的名字后缀通常含有.so(意为共享对象)
    $ ldd /bin/bash
    linux-vdso.so.1 (0x00007fff77fe7000)
    libreadline.so.8 => /usr/lib/libreadline.so.8 (0x00007f60035ec000)
    libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f60035e7000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007f6003424000)
    libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x00007f60033b5000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f6003750000)
    考虑到最佳性能和灵活性,可执行程序本身通常不知道它所用的共享库在哪里,只知道共享库名字,或只知道一点点寻找共享库的提示,如上左边是共享库名字。
    ld.so(运行时动态连接器/加载器)可以为程序在运行时找到并加载共享库。如上ldd输出的右边是ld.so找到的库的位置。
    最后一行显示了ld.so的实际位置。

    1.6.2 ld.so怎样找到共享库

    通常的顺序是如下的步骤(1),(2); 特殊情况才会使用(0)这个步骤。

    • (0) 参考环境变量LD_LIBRARY_PATH.(没有源码,又不能使用patchelf指定,就可以用这个了)
    • (1) 通常首先查找(可执行程序预先配置好的运行时搜索路径(如果有配置) runtime library search pach, 简称rpath);
    • (2) 接着,会参考系统缓存/etc/ls.so.cache, 看看该库是否在常规的位置。这是从缓存配置文件/etc/ld.so.conf中的目录列表获取的库文件名字的快速缓存。

    注: 如其他配置文件一样,ld.so.conf 可能会包含 /etc/ld.so.conf.d中的配置。
    标准的库目录/lib和/usr/lib是隐式的,即不需要包含在如上的配置文件中。
    如果改动了ld.so.conf或者改动了某个共享库的目录,需要重建共享库缓存
    $ ldconfig -v
    -v 选项会输出被ldcongfig添加到缓存的目录的详细信息和他所监测到的改动。

    编译时指定程序的rpath
    $ cc -o test test.o -Wl,-rpath=/opt/obscure/lib -L/opt/obscure/lib -lweird
    已编译的程序可用pathchelf加入不同的rpath, 不过最好还是在编译时就做好。

    1.6.3 环境变量LD_LIBRARY_PATH

    环境变量LD_LIBRARY_PATH, 用冒号分隔多个路径。如非必要,请勿滥用。
    * 永远都不要在启动文件中或在编译软件时设置LD_LIBRARY_PATH。
    在没有源码,又不能使用patchelf指定路径,最后的办法。
    但也请将它嵌套进shell脚本里。例如:
    #!/bin/sh
    LD_LIBRARY_PATH=/opt/crummy/lib
    export LD_LIBRARY_PATH
    exec /opt/crummy/bin/crummy.bin $@

    不使用 LD_LIBRARY_PATH 避免大部分共享库问题,但还可能遇到应用程序接口API的改变,导致装好的软件异常。
    最好的解决办法就是预防,在安装库时也使用 -Wl, -rpath, 或者使用静态库。

    2. 编译管理工具make

    您需要一个名为makefile的文件来告诉您make该怎么做。通常,makefile告诉make如何编译和链接程序。

    make有自己内置的规则,当你需要.o文件时,他就会自动去找.c文件,并会对.c文件运行cc -c命令,已达到获得.o文件的目标。
    编译时通过一个 Makefile 文件进行,把这个 Makefile 文件置于 hello.c 同一目录下.

    make命令的使用
    大多数的make都支持“makefile”和“Makefile”这两种默认文件名。
    特定的Makefile,你可以使用make的“-f”和“--file”参数,如:make -f Make.Linux。

    Makefile对格式有要求。
    注释#开头; 宏定义; 目标:描述; 都顶头开始,前面不需要空格或tab缩进。
    任何真实的命令前面都必须要有tab键(不能使用空格键)。

    2.1 make常用选项

    •  -f FILE, 将FILE文件作为makefile。
    •  -n, 显示一次构建所要用到的命令,但并不执行。
    •  -p, 打印make的内部数据库。
    •  -d, 打印大量调试信息。
    •  --trace, 打印跟踪信息。

    2.2 make常用变量

    $* 当前目标的基名。 f1.txt, $*就代表这里的f1
    $< 指第一个前置条件。
    $@ 写在规则里时,表示当前目标。
    $(@D) $(@F) 分别指$@目标的目录名和文件名。
    $(<D) $(<F) 分别指$<条件的目录名和文件名
    $? 比目标更新的所有前置条件。 t: p1 p2, 若p2时间戳比t新,$?就代表p2
    $^ 指所有前置条件,之间空格分隔。

    2.3 makefile常见的宏

    CFLAGS C编译器选项。make会将这个选项作为参数,在将.c变为.o的阶段传给编译器。
    LDFLAGS 类似CFLAGS, 不过他是在将.o变为可执行程序的阶段传给编译器。
    LDLIBS 如果使用了LDFLAGS,但不想库名选项与查找路径混在一起,可以将库名选项写在这里。
    CC C编译器,默认是cc。指定为clang可用 $ make CC=clang
    CPPFLAGS C预处理器选项。make运行预处理器时,将其作为参数。
    CXXFLAGS GNU使用这个宏作为C++编译器选项。

    2.4 makefile常规目标

    clean 通常会吧所有对象文件和可执行程序都清掉,以便重新构建或者打包软件。 rm -f … //这个目标无处不在
    distclean 它能删除原包以外的所有东西,包括Makefile。有些可发者更喜欢用 realclean.
    //GNU autotools所生成的Makefile总会有这个目标。
    install 将文件和编译好的程序放到Makefile认为适当的地方。可能有风险,最好先用make -n install看看会放在哪里。
    test 或 check 检验构建出的东西是否可用。
    depend 通过编译器的-M选项来检查源码,以建立依赖关系。 //这是一个不寻常的目标,因为它经常会改动Makefile自身。
    all 通常是Makefile的地一个目标


    https://www.gnu.org/software/make/manual/make.html#Makefile-Contents
    Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。

    • 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
    • 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
    • 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
    • 文件指示。其包括了三个部分,
      • 一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;
      • 另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;
      • 还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
    •  注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。

    2.5 教程手册

    入门简易版
    https://zhuanlan.zhihu.com/p/47390641
    Makefile由浅入深--教程、干货

    《Makefile文件教程》
    https://gist.github.com/isaacs/62a2d1825d04437c6f08

    http://www.ruanyifeng.com/blog/2015/02/make.html
    Make 命令教程  阮一峰  2015年2月20日
    http://www.ruanyifeng.com/blog/2015/03/build-website-with-make.html
    使用 Make 构建网站

    完整版《GNU Make手册》
    https://www.gnu.org/software/make/manual/make.html

    https://seisman.github.io/how-to-write-makefile/introduction.html
    跟我一起写Makefile
    https://blog.csdn.net/ruglcc/article/details/7814546
    https://blog.csdn.net/haoel/article/details/2886

    2.6 GNU autotools 安装步骤

    GNU autoconf 是一套流行的,用于自动产生Makefile的系统。解决跨平台的问题。
    使用此套系统的包都会带有 configure, Makefile.in, config.h.in文件。其中.in是模板文件。

    默认生成的Makefile中的install目标通常使用/usr/local作为前缀;二进制程序会去到/usr/local/bin. 库会到/usr/local/lib.
    GUN autoconf及很多其他软件包的默认前缀都是/usr/local。他是本地安装软件的传统位置。操作系统不会更新/usr/local里的软件。所以更新不会是你哪里的东西丢失。

    使用这类带配置的源码包安装步骤大致如下:

    01 下载: 官网下载...  
    02-1 验证签名: $ gpg --verify *.sig . 验证签名
    02-2 验证文件: $ md5sum 验证文件. md5sum,sha1sum,sha256sum验证文件。
    03-1 包内容: $ tar -tvf 首先用t选项查看,避免有绝对路径等问题;
    03-2 解包: $ tar -xvf[压缩选项] 再使用xvf[压缩选项]解包。
    04 查看说明: $ cat readme 查看自述文件,install安装说明等
    05 配置: $ ./configure 分析当前系统的特性,然后在Makefile.in文件的基础上做一些替换,创建出适合本机的构建文件:Makefile
    06-1 空跑: $ make -n 显示一次构建所要用到的命令,但并不执行。
    06-2 编译: $ make  
    07 检查: $ make check 若了解程序,也可是尝试运行生成的可执行文件。
    08-1 空跑: $ make -n install 空跑一次,查看安装那些东西到哪里。
    08-2 安装: $ make install  
    09 清理: $ make clean 清除编译连接过程中的一些临时文件
    10 卸载: $ make uninstall 卸载相关应用程序

    2.7 configure 常用的选项

    • --prefix=directory:  指定安装位置。
    • --bindir=directory: 指定可执行程序位置。
    • --sbindir=directory: 指定系统级的可执行程序位置。
    • --libdir=directory: 指定库位置。
    • --disable-shared: 不构建共享库(要看具体什么库)。
    • --with-package=directory: 告诉configure需要用到=directory: 目录的包。当某个库不在标准位置时,使用这个选项。但并非所有的configure脚本都能识别这个选项。

    2.8 Autotools的基础知识(Gentoo开发人员手册)

    https://devmanual.gentoo.org/general-concepts/autotools/index.html
    主要的Autotools组件
    Autotools是相关软件包的集合,当它们一起使用时,消除了创建便携式软件所涉及的许多困难。这些工具以及一些相对简单的上游提供的输入文件用于为包创建构建系统。https://devmanual.gentoo.org/general-concepts/autotools/diagram.png


    在一个简单的设置:

    • 该autoconf程序configure从任一configure.in或产生一个脚本 configure.ac(见下面的注释)。
    • 该automake程序产生一个Makefile.in来自Makefile.am。
    • configure运行 该脚本以Makefile从 Makefile.in文件生成一个或多个文件。
    • 该make程序使用Makefile编译程序。

    ...

    https://wiki.gentoo.org/wiki/Autotools
    Autotools是一个在开源项目中常用的构建系统。虽然很常见,但并非每个开发人员都喜欢使用自动工具。一些项目试图避免这种构建系统。

    https://devmanual.gentoo.org/eclass-reference/autotools.eclass/index.html
    autotools.eclass - 重新生成auto *构建脚本
    此eclass用于安全处理需要重新生成其构建脚本的自动化软件包。如果出现错误,所有功能都将中止。

    https://wiki.gentoo.org/wiki/Comparison_of_build_systems
    构建系统的比较 - 提供各种构建系统的简要比较。
    https://en.wikipedia.org/wiki/List_of_build_automation_software#Build_script_generation_tools

    2.9 更多相关链接

    http://www.gnu.org/software/autoconf/
    http://www.gnu.org/software/automake/

    https://autotools.io/index.html
    Autotools Mythbuster  Diego Elio “Flameeyes” Pettenò   作者和出版商 <flameeyes@flameeyes.com>
    Autotools Mythbuster是一个严肃的Autotools指南,旨在提供GNU构建链中工具的完整集成视图:autoconf,automake,libtool,pkg-config等。

    https://blogs.gentoo.org/lu_zero/2009/03/24/cmake-vs-autotools-a-benchmark/

    ==============
    https://devmanual.gentoo.org/eclass-reference/autotools-utils.eclass/index.html
    autotools-utils.eclass - 基于autotools的软件包的常见ebuild函数

    ==============
    https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Autotools_failures
    本指南旨在描述使自动工具无法在ebuild中运行的常见情况,并提供有关如何解决这些问题的建议。
    介绍
    与术语自动工具,我们通常所说的由GNU工程创建平台和操作系统无关构建系统,开发工具autoconf,automake和libtool。虽然并非每个包装都同时使用所有包装,但大多数现代包装都是这样做的; 旧的包通常不使用automake和libtool替代; KDE包使用更复杂的构建系统,最终依赖于上述三个软件。

    很容易识别构建系统基于autotools的软件包:

    • 如果有配置脚本,以及configure.in或configure.ac文件,构建系统基于autoconf ;
    • 如果各个子目录中有一个或多个Makefile.am文件,它也是automake基于;
    • 如果有一个ltmain.sh脚本,它也在使用libtool。


    要构建一个使用基于autotools的构建系统的软件包,这些工具本身并不是绝对需要的:configure脚本是一个简单的Bourne Shell脚本(通常,但这将在最近讨论)并将Makefile.in文件转换为简单的Makefile的make(或者,更多的时候,gmake)。尽管它们是构建软件的可选项,但解决诸如--as-need构建失败或自动依赖性等问题所需的补丁通常需要重新运行工具来重新创建脚本和makefile的模板。

    本指南不会说明如何使用autotools修复软件包的错误,因为这是一个需要解释很多内容的广泛主题。有关使用autotools时最常见错误的简单介绍,建议使用autotools文章阅读最佳实践。相反,它将描述重新运行autotools导致失败的常见情况,无论是在重建脚本还是在构建时。
    ================

    https://en.wikipedia.org/wiki/GNU_Build_System
    https://en.wikipedia.org/wiki/Automake
    https://en.wikipedia.org/wiki/Configure_(computing)
    https://en.wikipedia.org/wiki/Make_(software)
    https://en.wikipedia.org/wiki/Autoconf
    https://en.wikipedia.org/wiki/CMake

    https://en.wikipedia.org/wiki/Meson_(software)
    https://en.wikipedia.org/wiki/Configure_script
    https://en.wikipedia.org/wiki/Pkg-config

    https://en.wikipedia.org/wiki/GNU_Debugger
    https://en.wikipedia.org/wiki/GNU_Bison
    https://en.wikipedia.org/wiki/Berkeley_Yacc

    https://en.wikipedia.org/wiki/GNU_Compiler_Collection
    https://en.wikipedia.org/wiki/List_of_compilers
    此页面旨在列出所有当前编译器,编译器生成器,解释器,转换器,工具基础,汇编程序,可自动执行的命令行界面(shell)等。

    ===========
    https://en.wikipedia.org/wiki/List_of_GNU_packages
    GNU包列表
    GNU工具链
    主要文章:GNU工具链

    • GNU Binutils - 包含GNU汇编程序(as)和GNU链接程序(ld)
    • GNU bison - 用于替换yacc的解析器生成器
    • GNU构建系统(autotools) - 包含Autoconf,Automake,Autoheader和Libtool
    • GNU Compiler Collection - 针对许多编程语言优化编译器,包括C,C ++,Fortran,Ada和Java
    • GNU调试器(gdb) - 一种高级调试器
    • GNU m4 - 宏处理器
    • GNU make - 为GNU制作程序

    https://wiki.archlinux.org/index.php/GNU#Build_system
    https://www.gnu.org/

    构建系统autotools
    autoconf
    CMake
    SCons

    3. 调试器gdb

    gdb 全称是 GNU Debugger,是 GNU 开源组织发布的一个强大的 UNIX 下的程序调试工具。
    gdb 主要可帮助工程师完成下面 4 个方面的功能:

    启动程序,可以按照工程师自定义的要求随心所欲的运行程序。
    让被调试的程序在工程师指定的断点处停住,断点可以是条件表达式。
    当程序被停住时,可以检查此时程序中所发生的事,并追索上文。
    动态地改变程序的执行环境。

    https://wiki.archlinux.org/index.php/Debug_-_Getting_Traces
    https://wiki.archlinux.org/index.php/Step-by-step_debugging_guide
    https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces#Introducing_gdb
    $ gdb -q /bin/ls
    Reading symbols from /bin/ls...
    (No debugging symbols found in /bin/ls)
    (gdb) set args /usr/share/fonts
    (gdb) run
    Starting program: /usr/bin/ls /usr/share/fonts
    OpenImageIO  adobe-source-code-pro  cantarell  gsfonts misc  noto-cjk
    TTF      adobe-source-han-sans  encodings  mathjax noto
    [Inferior 1 (process 26487) exited normally]
    (gdb) q

    界面友好的 Eclipse IDE 和 Emacs 系统也是Linux支持的。
    想挖掘内存问题和生成统计信息,试试 Valgrind http://valgrind.org

    https://www.ibm.com/developerworks/cn/linux/1508_zhangdw_gdb/index.html
    使用 GDB 和 KVM 调试 Linux 内核与模块

    4. Lex和Yacc

    如果你要编译的程序需要读取配置文件或命令,那你可能要用到Lex和Yacc。这两个工具是用于制作编程语言的。

    Lex, Lexical Analyzar 词法分析器的生成器,能将文本内容转换成一个个标记。
    GNU/Linux版本叫做flex。可以使用编译器的-ll或-lfl连接器标记来连接Lex库。

    Yacc, Yet Another Compiler Compiler 语法解析器的生成器,能根据语法来读取标记。
    GNU的解析器是 bison。为使生成的语法分析器能与yacc兼容,需要执行bison -y。可以使用编译器的-ly连接器标记来连接Yacc的库。

    https://www.ibm.com/developerworks/cn/linux/sdk/lex/index.html
    Yacc 与 Lex 快速入门

    Lex
    Lex 是一种生成扫描器的工具。扫描器是一种识别文本中的词汇模式的程序。 这些词汇模式(或者常规表达式)在一种特殊的句子结构中定义。
    Lex 和 C 是强耦合的。一个 .lex 文件(Lex 文件具有 .lex 的扩展名)通过 lex 公用程序来传递,并生成 C 的输出文件。这些文件被编译为词法分析器的可执行版本。

    Lex 编程可以分为三步:
    以 Lex 可以理解的格式指定模式相关的动作。
    在这一文件上运行 Lex,生成扫描器的 C 代码。
    编译和链接 C 代码,生成可执行的扫描器。

    一个 Lex 程序分为三个段:
    第一段是 C 和 Lex 的全局声明,第二段包括模式(C 代码),第三段是补充的 C 函数。
    例如, 第三段中一般都有 main() 函数。这些段以%%来分界。

    Yacc
    Yacc 代表 Yet Another Compiler Compiler。 Yacc 的 GNU 版叫做 Bison。它是一种工具,将任何一种编程语言的所有语法翻译成针对此种语言的 Yacc 语 法解析器。它用巴科斯范式(BNF, Backus Naur Form)来书写。按照惯例,Yacc 文件有 .y 后缀。

    用 Yacc 来创建一个编译器包括四个步骤:
    通过在语法文件上运行 Yacc 生成一个解析器。
    说明语法:
    编写一个 .y 的语法文件(同时说明 C 在这里要进行的动作)。
    编写一个词法分析器来处理输入并将标记传递给解析器。 这可以使用 Lex 来完成。
    编写一个函数,通过调用 yyparse() 来开始解析。
    编写错误处理例程(如 yyerror())。
    编译 Yacc 生成的代码以及其他相关的源文件。
    将目标文件链接到适当的可执行解析器库。

    如同 Lex 一样, 一个 Yacc 程序也用双百分号分为三段。 它们是:
    声明、语法规则和 C 代码。

    5. 脚本语言

    Unix中,所有#!开头的可执行文本文件都是脚本,后面的路径是该脚本的解释器。
    #!/usr/bin/python
    #!/usr/bin/env python
    #!/usr/bin/tail -2

    常见的脚本语言

    • Python: 文本处理,数据库访问,网络编程,多线程等,支持者众多。还有强大的交互模式和一套有组织的对象模型。David M. Beazley, Python Essential Reference, 4th edition (Addison-Wesley, 2009)
    • Perl: 是Unix上较为老旧的第三方脚本语言。是编程界的“瑞士军刀”,近年被Python超越。
    • PHP: 超文本处理语言,常用于动态网页编程。http://www.php.net
    • Ruby: 面向对象的爱好者和Web开发者尤其喜欢。http://www.ruby-lang.org
    • JavaScript: 有一种实现Node.js,可执行程序是node。
    • Emacs Lisp: Lisp语言的一个变种。
    • Matlab和Octave: Matlab是一套商业矩阵及数学编程语言和库。Octave是类似Matlab的免费软件。
    • R: 流行的免费统计分析语言。http://www.r-project.org
    • Mathematica: 商业的数学编程语言和库。
    • m4: 宏处理语言,常见与GNU autotools。
    • Tcl: 工具命令语言,是一种简单的脚本语言,其扩展有图形界面的Tk和自动化工具Expect。http://tcl.tk

    6. Java

    Java跟C一样都是编译型语言,他有更简单的语法和强大的面向对象能力。
    多用于Web应用和一些特定的应用。Android应用就通常使用Java来开发的。

    Java编译器分为两种:
    用于生成机器码供系统使用的本地编译器(如C编译器);
    字节码解释器(有时也叫虚拟机)使用的字节码编译器。在Linux上看到的Java程序都是字节码。(.class文件)

    Java运行时环境(Java Runtime Environment, JRE)包含了运行Java字节码所需的程序。运行一个字节码:
    $ java file.class
    $ java -jar file.jar
    (.jar)文件是由一堆.class文件打包而成的字节码文件。

    有时需要将java的安装路径设置到JAVA_HOME环境变量中,甚至可能还需要使CLASSPATH变量包含你程序需要的所有class文件目录。

    需要使用(Java Development Kit, JDK)Java开发工具,将.java文件编译为字节码:
    $ javac file.java
    JDK还包含了jar程序,创建和拆分.jar文件,用法类似tar。


  • 相关阅读:
    设计模式学习——代理模式(Proxy Pattern)之 强制代理(强校验,防绕过)
    设计模式学习——代理模式(Proxy Pattern)
    设计模式学习——抽象工厂模式(Abstract Factory Pattern)
    最长字符串系列汇总
    窗口的最大值与最小值更新结构(滑动窗口)
    归并排序和归并排序应用(逆序对+小和)
    位运算在编程题的一些作用
    链表的排序(归并排序+快慢指针)
    Manacher算法解决最长回文子串长度问题
    回文数字的验证
  • 原文地址:https://www.cnblogs.com/sztom/p/11443302.html
Copyright © 2011-2022 走看看