UNIX系统管理:CC命令

在UNIX系统中,实现C源程序到可执行文件的这一转换过程的工具是cc。在大多数系统中cc实际上是一个shell命令文件。有些系统中的C编译程序可能并不叫cc而是其它的一个什么名称,如Sun工作站上常用的gcc等等。但这些都无关紧要。大多数系统中C编译命令的用法基本上都是类似的。我们这里介绍的将以SVR4上的C编译系统为基础。

cc基本用法

一般我们只需要将C源程序的名字写在CC命令行中,cc即可对这些源文件(.c文件)进行编译。如果这些源文件中都没有main()函数的定义,那么cc将只能生成与各源文件相对应的目标文件(.o文件)。如果某个源文件中有关于main()函数的定义,则将把所有目标文件链接起来生成相应的可执行文件。缺省的情况下这个可执行文件的名字将是a.out。

例如,假定myprog.c是一个包含有main()函数定义的C语言程序文件,其中代码如下:

/*********************************************

* An example source code with errors     *

* Name:myprog.c                *

********************************************* /

#include <stdio.h>

#include <ctype.h>

# define TESTOK  1

int TestInput(char * ValuInput)

{while (* ValueInput)

 if (! isdigit(* ValueInput )) return (! TESTOK);

 else              ValueInput + +;

return ((100/atoi(ValueInput))? TESTOK:! TESTOK);

}

void

main(int argc,char * argv[])

{int i;

for (i=1;i<argc;;i++)

 if(TestInput (argv[i]) = =TESTOK)

 printf("The %dth ">value '%s' \tis OK! \n",i,argv[i]);

 else

  printf("The %dth value '%s' \tis BAD! \n" ,i,argv[i]);

}

对于此程序中的错误(设计错误)我们暂不理会。下一章我们介绍程序调试时再回过头来看看如何排除这个错误。

我们看到。在这个源程序文件中,定义了两个函数:TestInput()和main(),定义了一个宏TESTOK,同时包含了两个标准的头文件。为了把这个C程序转换成可执行文件,在shell提示符下输入:

$cc myprog.c

在程序中没有任何语法错误的情况下,cc将在当前目录下生成一个名为a.out的可执行文件,如:

$ cc myproc.c

$ ls -l

-rwx------ 1 yxz users 5812 Aug 31 15:32 a.out

-rw------- 1 yxz users 716 Aug 31 15:27 myproc.c

$

还可以看到这里a.out是一个可执行文件。当然这个程序由于在设计上有些失误,我们现在还不能马上就带参数运行。但不带参数运行还是可以的。只不过此时该程序什么都没有干,如:

$ a.out

$

在程序中我们通过main函数的两个参数argc和argv而使程序能够引用shell命令行参数;这是UNIX环境下一种常用的编程技术。

在生成了a.out文件之后,我们自然可用mv命令将其修改为某个合适的名称。但更简单的方法是在cc命令行中加上-o选项,使cc直接将可执行文件写入到指定的文件中而不生成a.out文件,如:

$ cc -o myprog myprog.c

$ ls -l myprog

total 14

-rwx------ 1 yxz users   5812 Aug 31 15:34 myprog

-rw------- 1 yxz users    716 Aug 31 15:27 myprog.c

$

我们看到,myprog这个文件除了文件名及修改时间同a.out不一样外,其他属性同a.out都是一摸一样的。这也说明了两者的等价性。

在某个程序的源代码被存放到多个不同文件中的情况下,我们只需要在命令行中一一指定这多个C文件即可。例如,我们可以将上述myprog.c拆分为两个C文件和一个头文件(.h)如下:

myprog.h

# include <stdio.h>

# inclued <ctype.h>

# define TESTOK 1

myprog.c

#include "myprog.h"

void

main (int argc,char * argv[])

{int i;

for (i=1;i<argc;i + +)

if (TestInput(argv[i])= = TESTOL)

  printf("The %dth value '%s' \tis ok! \n",argv[1]);

else

  printf("The %dth value ' %s' \tis BAD! \n",iargv[i]);

}

myfunc.c

#include "myprog.h"

int

TestInput(char * ValueInput)

{while (* ValueInput)

  if (!isdigit(*ValueInput) return (! TESTOK);

  else     ValueInput + +

return ((100/atoi(ValueInput))? TESTOK:! TESTOK);

这时要再编译此程序时可输入如下命令:

$ cc -o myprog myprog.c myfunc.c

在这个命令行中如果不指定myfunc.c,此时由于在myprog.c中所调用的TestInput()这个函数不是任何标准的库函数,在链接时链接程序将找不到此符号的定义,故链接过程将以失败而告终,此时cc将给出如下的错误信息:

Undefine      first referenced

symbol          in file

TestInput         myprog.o

id: myprog:fatal error: Symbol referencing errors.No output written to myprog

$

而可执行文件myprog也无法生成。但编译却会生成myprog.c的目标代码(在某个文件固有语法错误而无法正确被编译的情况下(此时为编译过程出错),cc将生成其他无语法错误的源文件的目标文件,但不进行链接)。如下:

$ ls -l

total 8

rw-r--r-- 1 yxz user 454 Sep 1 09:27 myfunc.c

rw-r--r-- 1 yxz user 479 Sep 1 09:28 myprog.c

rw-r--r-- 1 yxz user 298 Sep 1 09:27 myprog.h

rw-r--r-- 1 yxz user 924 Sep 1 09:28 myfunc.o

此时我们可以使用如下命令行得到可执行文件:

$ cc -o myprog myprog.o myfunc.c

这里我们看到,cc命令行中的文件参数可以不全是.c文件,目标文件(.o)文件以后编译过程中所得到的其他文件,如预编译后文件(.i文件),编译后的汇编程序(.s文件)等都可作为文件参数。在了解了UNIX C编译系统的工作过程之后,理解这一点是不困难的。因为编译系统只需要对各种不同类型的文件进行有关的处理就可以了。

时间: 2024-09-13 12:17:32

UNIX系统管理:CC命令的相关文章

给系统管理员的 15 条实用 Linux/Unix 磁带管理命令

给系统管理员的 15 条实用 Linux/Unix 磁带管理命令 磁带设备应只用于定期的文件归档或将数据从一台服务器传送至另一台.通常磁带设备与 Unix 机器连接,用 mt 或 mtx 控制.强烈建议您将所有的数据同时备份到磁盘(也许是云中)和磁带设备中.在本教程中你将会了解到: 磁带设备名 管理磁带驱动器的基本命令 基本的备份和恢复命令 为什么备份? 一个备份计划对定期备份文件来说很有必要,如果你宁愿选择不备份,那么丢失重要数据的风险会大大增加.有了备份,你就有了从磁盘故障中恢复的能力.备份

使用Python编写类UNIX系统的命令行工具的教程_python

引言 您是否能编写命令行工具?也许您可以,但您能编写出真正好用的命令行工具吗?本文讨论使用 Python 来创建一个强健的命令行工具,并带有内置的帮助菜单.错误处理和选项处理.由于一些奇怪的原因,很多人并不了解 Python? 的标准库具有制作功能极其强大的 *NIX 命令行工具所需的全部工具. 可以这样说,Python 是制作 *NIX 命令行工具的最佳语言,因为它依照"batteries-included"的哲学方式工作,并且强调提供可读性高的代码.但仅作为提醒,当您发现使用 Py

UNIX系统管理:动态链接程序程序搜索目录

在采用动态链接方式对程序进行编译,链接时候.链接程序只是在最终的可执行文件中记录下关于所引用的共享库中的符号的一些登记信息,以便在程序被执行时,动态链接程序能够根据这些登记信息找到相应的代码.因此登记动态链接方式而言,除了在链接阶段涉及到对库文件的搜索路径外,还有一个在程序运行阶段对库文件的搜索问题. 前一个问题我们知道借助于LD_LIBRARY_PATH环境变量及cc命令行中的-L选项已经得到了比较好的解决.对于第二个问题,我们必须提供一种机制,使得动态链接程序能够找到相应的动态库,然后才能将

UNIX系统管理:编译过程概述

了解一些编译知识的读者都知道,所谓编译,就是在编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序. UNIX环境下的C编译系统所遵循的也是这么一个一般的过程.值得注意的是这个过程并不是有某个单个程序完成的,而是有多个分别完成某一方面工作的程序组合完成的.这一http://www.aliyun.com/zixun/aggregation/8511.html">设计

UNIX系统管理:sdb的启动

首先来看看在哪些情况下需要对程序进行调试. 第一种情况(这是大多数用户都会碰到的),程序在运行过程中忽然跳了出来,屏幕上显示一个xxxx-core dumped消息,然后Shell提示符就又显示出来了,其中xxxx表示出错原因.这种情况的出现一般是系统核心认为进程的执行出现了异常,如进程试图去访问一块不允许它访问的存储区域(Memory Fault,Segmentation Fault);或者扫描某个无终止符的字符串(Bus http://www.aliyun.com/zixun/aggrega

UNIX系统管理:静态库及动态库的建立

UNIX系统及各种软件包为http://www.aliyun.com/zixun/aggregation/7155.html">开发人员提供了大量的库文件.但一般情况下这些库文件还不能足以满足用户的所有需求.开发人员大多会根据他们自己的开发.研究要求编写出许多函数.对于这些函数,如果都用在命令行中指定源文件的方法同调用它们的的程序链接起来,虽然也是可以的,但也有一些缺点: 对每一个调用了这些函数的程序,在编译时都需要将这些函数的代码分别重新编译,这实际是对计算时间的大量浪费. 一个文件中通

UNIX操作系统tar命令之隐患及解决方法

unix|解决 目前,UNIX操作系统在我国金融界被广泛地采用,UNIX以其强大的功能(分时.多任务.多用户.网络互连.图形接口等),倍受金融企业青睐.中国农业银行现应用的SCO UNIX OPENSERVER50更是功能强劲. 各家银行的储蓄.会计.信用卡等计算机业务处理系统均运行在UNIX操作系统平台上.电子化的发展拓展了银行的业务领域,提高了工作效率,加强了业务的准确性.保密性.安全性,树立了银行的社会形象,产生间接的经济效益.电子化银行的发展对计算机数据的可靠性提出了更高的要求. 据笔

用UNIX的kill命令来终止Oracle的过程

正如你所知,有时候我们有必要终止所有的Oracle过程(process)或者指定的一组Oracle过程.当数据库"锁定"而你无法进入Server Manager来"温柔"的终止数据库时,就可以用UNIX中的kill命令来终止所有的Oracle过程--这是kill命令的常见用途之一.当你需要终止一个UNIX服务器上的一个Oracle实例(instance)时,执行下面的步骤: 终止与ORACLE_SID有关的所有Oracle过程. 用ipcs –pmb命令来识别所有占

Unix系统stty命令用法详解

UNIX系统的命令很多,下面讲解stty. 该命令是一个用来改变并打印终端行设置的常用命令. 1.stty(set tty,设置tty)命令用于检查和修改当前注册的终端的通信参数. UNIX系统为键盘的输入和终端的输出提供了重要的控制手段,可以通过stty命令对特定终端或通信线路设置选项. 可以在stty命令中使用-a查看当前注册终端的设置情况. $ stty -a Speed 9600 baud; line =0;intr= DEL;quit = ^;erase = ^h;kill =^U;