您的位置:首页 > 编程语言 > C语言/C++

C语言(转自UNIX环境高级编程等)

2012-10-22 11:36 295 查看
一、数据类型及其运算
1、运算符
算术运算符:正、负、加、减、乘、除、求余(%)
自增自减运算符:++、--
赋值运算符:=
关系运算符:<、<=、>、>=、==、!=
逻辑运算符:!、&&、||
逗号运算符:,例子:“2*a,2*b”为一个逗号表达式,返回第二个表达式即2*b的结果。
条件运算符:?: 例子:c=a?2*a:2*b
长度运算符:sizeof 例子:sizeof(int)。
位逻辑运算符:~(位非)、&(位逻辑与)、|(位逻辑或)、^(位逻辑异或)
位移位运算符:<<左移 例子:a<<n,a向左移n位,左补0。>>右移。
(表达式分为算术表达式和逻辑表达式)
二、文件I/O
1、open和create函数是文件操作的两个基本函数,它们都可以创建文件,它们之间存在一些差别,但按如下方式设置参数它们是等价的。
open(
const
char
* pathname, (O_CREAT|O_WRONLY|O_TRUNC),mode_t mode);

creat(
const
char
* pathname,mode_t mode);

       当文件不存在时按照mode方式创建新文件,如果文件存在,则覆盖原有文件。事实上是因为O_WRONLY|O_TRUNC参数的原因:当文件存在并且以可写方式打开的时候,原有文件到长度则清0,即会清空原有文件,但是文件属性不变,与原有文件方式相同,并不会设置成mode方式。
       在下面的源代码中,以open函数方式创建文件时,由于设置拉O_CREAT|O_EXCL参数,当要创建到文件不存在时,open函数创建这个文件,并且文件到存取权限为S_IRUSR|S_IWUSR。当文件存在时因为设置拉O_EXCL则出现错误。而当以creat()方式创建文件时,如本文开头所述,无论是否存在将要创建的那个文件,都不会出现错误。
#include "stdio.h"

#include "sys/types.h"

#include "sys/stat.h"

#include "fcntl.h"

#include "unistd.h"

#include "error.h"

int
main()

{

int
fd,n;

printf
(
"please select a way of creating files:\n"
);

printf
(
"1.creat 2.open\n"
);

scanf
(
"%d"
,&n);

if
(n==1)

{

if
((fd=creat(
"example_62.c"
,S_IRWXU))==-1)

{

perror
(
"open"
);

exit
(1);

}

else

{

printf
(
"create file success\n"
);

}

}

else
if
(n==2)

{

if
((fd=open(
"example_62.c"
,O_CREAT|O_EXCL,S_IRUSR|S_IWUSR))==-1)

{

perror
(
"open"
);

exit
(1);

}

else

{

printf
(
"create file success\n"
);

}

}

else

{

printf
(
"your choice may be wrong\n"
);

}

close(fd);

return
0;

}

 
 

【转】S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP

fd=open("/dev/globalvar", O_RDWR, S_IRUSR|S_IWUSR);//可读写方式打开设备文件
S_IRUSR
Permits the file's owner to read it.
S_IWUSR
Permits the file's owner to write to it.
S_IRGRP
Permits the file's group to read it.
S_IWGRP
Permits the file's group to write to it.
S_ISREG ( ) 普通文件
S_ISDIR ( ) 目录文件
S_ISCHR ( ) 字符特殊文件
S_ISBLK ( ) 块特殊文件
S_ISFIFO ( ) 管道或F I F O
S_ISLNK ( ) 符号连接( P O S I X . 1或S V R 4无此类型)
S_ISSOC K ( ) 套接字(P O S I X . 1或S V R 4无此类型)
? O_RDONLY 只读打开。
? O_WRONLY 只写打开。
? O_RDWR 读、写打开。
在这三个常数中应当只指定一个。下列常数则是可选择的:
? O_APPEND 每次写时都加到文件的尾端。3 . 11节将详细说明此选择项。
? O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数m o d e,
用其说明该新文件的存取许可权位。( 4 . 5节将说明文件的许可权位,那时就能了解如何说明
m o d e,以及如何用进程的u m a s k值修改它。)
? O_EXCL 如果同时指定了O C R E AT,而文件已经存在,则出错。这可测试一个文件是
否存在,如果不存在则创建此文件成为一个原子操作。3 . 11节将较详细地说明原子操作。
? O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。
? O_NOCTTY 如果p a t h n a m e指的是终端设备,则不将此设备分配作为此进程的控制终端。
9 . 6节将说明控制终端。
? O_NONBLOCK 如果p a t h n a m e指的是一个F I F O、一个块特殊文件或一个字符特殊文件,
则此选择项为此文件的本次打开操作和后续的I / O操作设置非阻塞方式。
2、lseek函数
       可以调用lseek函数显式的定位一个打开文件
#include <sys/types.h>
#include <unistd.h>
off_t lseek(intf i l e d e s, off_t o f f s e t, int w h e n c e) ;
返回:若成功为新的文件位移,若出错为- 1
也可以用该函数创建一个空洞文件。
3、read函数 write函数
       用read函数从打开的文件中读数据。
#include <unistd.h>
ssize_t read(intf i l e d e s, void *b u f f, size_tn b y t e s) ;
返回:读到的字节数,若已到文件尾为0,若出错为- 1
如果read成功则返回成功读取的字节数,如果已到达文件的尾端,返回0。在很多情况下,实际读取的字节数少于要求的字节数。
当从终端设备读时,通常一次最多读取一行
从网络读取时,网络中的缓冲机构可能造成返回值小于要求的字节数。
用w r i t e函数向打开文件写数据。
#include <unistd.h>
ssize_t write(inft i l e d e s, const void b* u f f, size_tn b y t e s) ;
返回:若成功为已写的字节数,若出错为- 1
4、I/O的效率
思考一下缓存的大小对读写的影响?
5、文件共享
linux系统允许多个进程共享一个文件,在介绍dup函数之前,先介绍一下内核用于所有I/O的数据结构。共有三个数据结构,它们之间的关系决定了一个进程对另一个进程的影响。这三个结构为:
(1)进程表——进程表项——文件描述符表——?
(2)文件表——文件表项——?
(3)文件v节点表——文件v节点表项——?



       当两个不同进程各自打开(open)同一文件时,如下图所示,打开此文件的每个进程都得到一个文件表项(原因:每个进程都有它自己对该文件的当前位移量。),但对一个给定的文件只有一个文件v节点。



       每当执行完一次write后,当前文件位移量就会增加写的字节数。(文件位移量:例如在read之前,文件位移量为0,read 8个字节后,文件位移量变为8,当下次再read时,就会从位移量为8的为止开始读取。)
       如果用O_APPEND标志打开一个文件时,该标志也会被加到文件表项中文件状态标志中。
       lseek函数只修改文件表项中文件位移量,并没有执行任何I/O操作。
也有可能多个文件描述符指向同一个文件表项,例如dup函数,fork函数创建子进程时。
注意文件状态描述符和文件描述符标志的区别????作用范围(文件描述符标志只用于一个进程的一个描述符,而文件状态描述符则适用于指向该给定文件表项的任何进程中的所有描述符。)
6、原子操作
其是为了避免多个进程对同一个文件进行操作而产生错误的手段。
7、dup和dup2函数
       通过这两个系统调用函数可以重定向文件描述符。
#include <unistd.h>
int dup(int fields)
int dup2(int fields,int fields2)
若成功返回新的文件标示符,否则返回-1;
返回的新的文件标示符一定是当前可用的文件标示符的最小值。dup2可以用fields参数指定的文件描述符,若已经打开,则先关闭,若两参数值相等则不关闭直接返回fields2。注意这些返回的文件描述符与fields共享同一文件表项。
8、fcntl函数
        该函数能改变已打开文件的性质。
int fcntl(int Fields,cmd,.../intarg/)若成功,则依赖于cmd,失败则依赖于-1;
在本节的各实例中,第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但
是1 2 . 3节说明记录锁时,第三个参数则是指向一个结构的指针。
f c n t l函数有五种功能:
? 复制一个现存的描述符(c m d=F D U P F D)。
? 获得/设置文件描述符标记(c m d = F G E T F D或F S E T F D)。
? 获得/设置文件状态标志(c m d = F G E T F L或F S E T F L)。
? 获得/设置异步I / O有权(c m d = F G E TO W N或F S E TO W N)。
? 获得/设置记录锁(c m d = F G E T L K , F S E T L K或F S E T L K W)。
新文件描述符有它自己的文件描述符标志?
附:int atoi(char *nptr)函数:将字符串转换为整形数。
使用/dev/null:把/dev/null 看作"黑 洞" .它非常等价于一个只写文件. 所有写入它的内容都会永远丢失. 而尝试从它那儿读取内容则什么也读不到. 然而,/dev/null 对命令行和脚本都非常的有用.9、ioctl函数ioctl函数是I/O操作的杂物箱。不能用以上函数操作的I/O通常都能用该函数操作。小结: 因为每个read, write都因调用系统调用而进入内核,所以称这些函数为不带缓存的I / O函数。
 
习题
3 . 1在当读/写磁盘文件时,本章中描述的函数是否有缓存机制?请说明原因。
答:不具有缓存机制。因为这些函数都因调用系统调用而进入内核。
3 . 5在在Bourne shell和K o r n S h e l l中,d i g i t1> & d i g i t2表示要将描述符d i g i t1重定向至描述符d i g i t2的同一文件。请说明下面两条命令的区别。
a.out > outfile 2>&1
a.out 2>&1 > outfile
(提示:s h e l l从左到右处理命令行。
答:?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C语言 编程 a