Chinaunix首页 | 论坛 | 博客
  • 博客访问: 397407
  • 博文数量: 115
  • 博客积分: 2501
  • 博客等级: 少校
  • 技术积分: 1009
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-23 17:05
文章分类

全部博文(115)

文章存档

2011年(2)

2010年(86)

2009年(27)

我的朋友

分类: LINUX

2009-10-09 21:44:36

Linux入门程序分析

linux下编写第一个程序时,会看到如下的函数:

#inlcudexxx

...

int main(int argc,char *argv[])

{

    ...

    exit(0);

}

#inlcudexxx

...

int main()

{

    ...

    exit(0);

}

初次接触linux编程的人会问:怎么主函数的入口多了两个变量?怎么不用这两个变量也可以?

其实: int main(int argc,char *argv[]) UNIX Linux 中的标准写法,而 int main() 只是 UNIX Linux 默许的用法。那就是随便你怎么用了,看你自己的需要了,呵呵。argc 是外部命令参数的个数,argv[] 存放各参数的内容。举个例子应该会更加深理解:

先用vi创建一个文件text.c

然后按a输入文本。

#include

int main(int argc,char *argv[])

{

    int i = 0;

    for(;i

    {

        printf("%s\n",argv[i]);

    }

    return 0;

}

输入完成后,按ESC然后按“shift+:”,输入wq并回车保存文件。

把上面的程序编译一下.

gcc -o text text.c

int main(int argc,char *argv[])

记住,第1个参数是命令行参数的个数,char *argv[]是一个存放字符指针的数组, 每个指针指向一个具体的命令行参数(字符串)。运行一下,不难发现:

[root@ReinSquid code]# ./text haha 1

./text

haha

1

ANSI C定义的主函数的参数实际上是可变长的,最多可以为三个.第三个参数与第二个参数类似,存放环境变量。

再看一个程序,在某一目录下新建file.c 1.c文件,其内容如下:

/*file.c*/

#include ;

#include ;

#include ;

#include ;

#include ;

#include ;

#include ;

#define BUFFER_SIZE 1024

int main(int argc,char **argv)

{

int from_fd,to_fd;

int bytes_read,bytes_write;

char buffer[BUFFER_SIZE];

char *ptr;

if(argc!=3)

{

fprintf(stderr,"Usage%s fromfile tofile\n\a",argv[0]);

exit(1);

}

/* 打开源文件 */

if((from_fd=open(argv[1],O_RDONLY))==-1)

{

fprintf(stderr,"Open %s Error%s\n",argv[1],strerror(errno));

exit(1);

}

/* 创建目的文件 */

if((to_fd=open(argv[2],O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))==-1)

{

fprintf(stderr,"Open %s Error%s\n",argv[2],strerror(errno));

exit(1);

}

/* 以下代码是一个经典的拷贝文件的代码 */

while(bytes_read=read(from_fd,buffer,BUFFER_SIZE))

{

/* 一个致命的错误发生了 */

if((bytes_read==-1)&&(errno!=EINTR)) break;

else if(bytes_read>;0)

{

ptr=buffer;

while(bytes_write=write(to_fd,ptr,bytes_read))

{

/* 一个致命错误发生了 */

if((bytes_write==-1)&&(errno!=EINTR))break;

/* 写完了所有读的字节 */

else if(bytes_write==bytes_read) break;

/* 只写了一部分,继续写 */

else if(bytes_write>;0)

{

ptr+=bytes_write;

bytes_read-=bytes_write;

}

}

/* 写的时候发生的致命错误 */

if(bytes_write==-1)break;

}

}

close(from_fd);

close(to_fd);

exit(0);

}

 

/*1.c*/

#include

int main(void)

{

printf(“copy me!\n”);

exit(0);

}

使用命令GCC –o file file.c后,输入./file 1.c 2.c,可以发现1.c的内容变为1.c的内容了。

现在该知道main函数入口参数中两个变量的用法了吧!

   

再看一下exit的用法,

exit(0) 表示正常退出, exit(1)exit(-1)表示程序异常退出;

exit() 结束当前进程/当前程序,在整个程序中,只要调用exit,就结束;

return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用。在多个进程时.如果有时要检测上进程是否正常退出的.就要用到上个进程的返回值。当exit(1)表示进程正常退出,返回1;exit(0)表示进程非正常退出,返回0exit()函数定义在 stdlib.h中,而_exit()定义在unistd.h中,exit_exit函数用于正常终止一个程序:_exit立即进入内核,exit则先执行一些清除处理, (包括调用执行各终止处理程序,关闭所有标准I/O流等),然后进入内核。exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的“清理I/O缓冲”一项。在Linux 的标准函数库中,有一套称作“高级I/O”的函数,我们熟知的printf()fopen()fread()fwrite()都在此列,它们也被称作“缓冲I/Obuffered I/O)”,其特征是对应每一个打开的文件,在内存中都有一片缓冲区,每次读文件时,会多读出若干条记录,这样下次读文件时就可以直接从内存的缓冲区中读取,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(达到一定数量,或遇到特定字符,如换行符\n和文件结束符EOF),再将缓冲区中的内容一次性写入文件,这样就大大增加了文件读写的速度,但也为我们编程带来了一点点麻烦。如果有一些数据,我们认为已经写入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时我们用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失,反之,如果想保证数据的完整性,就一定要使用exit()函数。

请看以下例程:

/* exit2.c */

#include

#include

main()

{  

printf("output begin\n");  

printf("content in buffer");  

exit(0);

}

编译并运行:

gcc -o exit2 exit2.c

./exit2

output begin

content in buffer

 

/* _exit1.c */

#include

#include

main()

{  

printf("output begin\n");  

printf("content in buffer");

_exit(0);

}

编译并运行:

gcc _exit1.c -o _exit1

./_exit1

output begin

 

另外,也有形如如下的程序返回:

int main(int argc,char *argv[])

{

    ...

    return(0);

}

return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用。

linux初学者来说,掌握linux下第一个程序设计,并理解基本程序结构非常重要。

阅读(593) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~