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/