C 語言函數手冊

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

    argc 是命令行總的參數個數,記錄了用戶在運行程序的命令行中輸入的參數的個數;程序員

    argv[] 存放了命令行輸入的所有字符串,包含 argc 個參數,其中第 0 個參數是程序的全名,至少有一個字符指針,指向程序中可執行文件的文件名,有些版本的編譯器中還包括程序文件所在的路徑;數組

    程序中獲得這些參數的工做是編譯器完成的,編譯器將輸入參數的信息放入 main 函數的參數列表中,賦值過程也是編譯器完成的。dom

 

stat.h

    導入 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()

    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()、calloc()、realloc()、free()、memcpy()  

    頭文件 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 的指針;

 

errno.h    

    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/

相關文章
相關標籤/搜索