argc 是命令行总的参数个数,记录了用户在运行程序的命令行中输入的参数的个数;程序员
argv[] 存放了命令行输入的所有字符串,包含 argc 个参数,其中第 0 个参数是程序的全名,至少有一个字符指针,指向程序中可执行文件的文件名,有些版本的编译器中还包括程序文件所在的路径;数组
程序中获得这些参数的工做是编译器完成的,编译器将输入参数的信息放入 main 函数的参数列表中,赋值过程也是编译器完成的。dom
导入 sys/stat.h 头文件能够获取文件的属性,其中声明了一个重要的结构体 stat:socket
struct stat{ mode_t st_mode; //文件类型和权限信息 ino_t st_ino; //i结点标识 dev_t st_dev; //device number (file system) dev_t st_rdev; //device number for special files nlink_t st_nlink; //符号连接数 uid_t st_uid; //用户ID gid_t st_gid; //组ID off_t st_size; //size in bytes,for regular files time_t st_st_atime; //最后一次访问的时间 time_t st_mtime; //文件内容最后一次被更改的时间 time_t st_ctime; //文件结构最后一次被更改的时间 blksize_t st_blksize; //best I/O block size blkcnt_t st_blocks; //number of disk blocks allocated };
文件类型包括了:普通文件、目录文件、块特殊文件、字符特殊文件、套接字、FIFO、符号连接,文件类型信息包含在 stat 结构的 st_mode 成员中,能够经过宏肯定文件类型,这些宏是 stat 结构中的 st_mode 成员:S_ISREG()、S_ISDIR()、S_ISCHR()、S_ISBLK()、S_ISFIFO()、S_ISSOCK()函数
S_TYPEISMQ() 表示消息队列、S_TYPEISSEM() 表示信号量、S_TYPEISSHM() 表示共享存储对象。测试
进程每次打开,建立或删除一个文件时,内核就进行文件访问权限测试,测试可能涉及文件全部者(st_uid 和 st_gid),进行的有效 ID 以及进程的附加组 ID:ui
(1).若进程的有效用户ID是0(超级用户),则容许访问。
(2).若进程的有效用户ID等于文件的有效用户ID,那么若所在者适当的访问权限被设置,则容许访问。
(3).若进程的有效组ID或进程的附加组ID之一等于文件的组ID,那么组适当的访问权限位被设置,则容许访问。
(4).若其余用户适当的访问权限位被设置,则容许访问。
按顺序执行以上四步。spa
stat()、lstat()、fstat() 函数都是获取文件(普通文件、目录、管道、socket、字符、块)的属性。操作系统
int stat(const char *restrict pathname, struct stat *restrict buf); 提供文件名字,获取文件对应属性;.net
int fstat(int filedes, struct stat *buf); 经过文件描述符,获取文件对应的属性;
int lstat(const char *restrict pathname, struct stat *restrict buf); 链接文件描述符,获取文件属性
fstat() 用来将参数 filedes 所指向的文件状态复制到参数 buf 所指向的结构中(structstat),fstat() 与 stat() 做用彻底相同,不一样之处在于传入的参数为已打开的文件描述符
返回值:执行成功返回 0,失败返回 -1,错误代码保存在 errno;
#include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> main() { struct stat buf; int fd; fd = open("/etc/passwd", O_RDONLY); fstat(fd, &buf); fstat(fd, &buf); printf("/etc/passwd file size = %d\n", (int)(buf.st_size)); }
头文件 malloc.h(alloc.h 两个头文件内容相同的)
函数声明:extern void *malloc(unsigned int num_bytes);
分配长度为 num_bytes 字节的内存块,分配成功返回指向被分配内存的指针,不然返回空指针 NULL。
#include <stdio.h> #include <malloc.h> int main() { char *p; p = (char *)malloc(100); if(p) printf("Memory Allocated at %x\n", p); else printf("Not Enough Memory!\n"); free(p); return 0; }
malloc 向系统申请分配指定 size 个字节的内存空间,返回类型是 void* 类型(未肯定类型的指针,C、C++规定,void *类型能够强制转化为任何其它类型的指针)
当内存再也不使用时,应使用 free() 函数将内存块释放;
void free(void *ptr); //#include <stdlib.h> 或 #include <malloc.h>
释放 ptr 指向的存储空间,被释放的空间一般被送入可用存储区池,之后可在调用 malloc、realloc 以及 realloc 函数再分配(连续两次 free 会报错,malloc 次数要和 free 此时相对)
free(str) 后指针仍然指向原来的堆地址,即你仍然能够继续使用,但很危险,由于操做系统已经认为这块内存可使用,会分配给其它程序,这种状况就叫“野指针”(指程序员或操做者不能控制的指针,不是 NULL 指针,而是指向“垃圾”的指针),最好 free() 了之后再置空,str = NULL,即放弃使用它;
calloc() 函数用来动态地分配内存空间并初始化为 0:
void * calloc(size_t num, size_t size);
calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每个字节都初始化为 0,因此它的结构是分配了 num*size 个字节长度的内存空间,而且每一个字节的值都是 0。
分配成功返回指向该内存的地址,失败则返回 NULL。
realloc() 函数用来更改已经配置的内存空间,即更改由 malloc() 函数分配的内存空间大小,若是将分配的内存减小,realloc 仅仅是改变索引的信息;
realloc(void * __ptr, size_t __size)
若是是将内存扩大:
1)若是当前内存段后面有须要的内存空间,则直接扩展这段内存空间,realloc() 将返回原指针;
2)若是当前内存段后面的空闲字节不够,那么就使用堆中第一个能知足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。
3)若是申请失败,将返回 NULL,此时,原来的指针仍然有效;
若是调用成功,无论当前内存段后面的空闲空间是否知足要求,都会释放原来的指针,从新返回一个指针,虽然返回的指针有可能和原来的指针同样,即不能再次释放掉原来的指针。(若是当前内存段后有足够的空间,则返回原来的指针,若是没有足够的空间,会返回一个新的内存段指针)
#include <string.h>
void * memcpy(void *destin, const void *src, size_t n);
有 src 指向地址为起始地址的连续 n 个字节的数据复制到以 destin 指向地址为起始地址的空间内,返回一个指向 dest 的指针。
source 和 destin 所指内存区域不能重置,函数返回指向 distin 的指针;
C 语言错误处理,提供了宏 errno、 perror() 函数和 strerrno() 函数
perror() 函数显示的字符串传递,而后接一个冒号,一个空格,而后目前 errno 值得文字表述;
strerrno() 函数返回一个指针,指向目前的 errno 值的文字描述。
errno 在头文件 errno.h 中定义
#ifndef errno extern int errno; #endif #define EDOM 33 /* Math argument out of domain of function */
errno 常见用法是在调用库函数以前清零,随后再进行检查。
看代码的过程当中,不少地方遇到了相似这样的声明 void ** A = &B,A(即 B 的地址)是指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量,根据 B 的状况不一样,二级指针又分为指向指针变量的指针和指向数组的指针。
任何值都有地址,一级指针的值虽然是地址,但这个地址作为一个值亦须要空间来存放,是空间就具备地址,这就是存放地址这一值的空间所具备的地址,二级指针就是为了获取这个地址。
数组也是一种指针,指针+1 的操做相似于数组下标加一,指针加一其实是相对于声明指针时类型而言的,若是声明指针时为 int 类型,那么指针加一,实际上移动了 4 个字符位。
在 C 和 C++ 中,void 表明一种抽象的无类型,任何变量都应该是有类型的,void * 即为无类型指针,void * 能够指向任何类型的数据,由于 void * 的声明指针类型能够转变成任何其它类型。
函数 | 说明 |
getpagesize() | 取得内存页大小 |
mmap() | 创建内存映射 |
munmap() | 接触内存映射 |
memccpy() | 复制内存中的内容 |
memchr() | 在内存中查找特定字符 |
memcmp() | 比较内存前 n 个字节 |
附带 C 语言函数手册:http://c.biancheng.net/cpp/u/hs3/