當前位置:才華齋>計算機>C語言>

C語言中指標高階用法介紹

C語言 閱讀(1.47W)

問題描述:指標是C語言很有特色的一個部分,但是使用也比較複雜,很容易導致一些莫名的錯誤,比如有時候函式指標沒有賦值,有時指向了未定義的記憶體,這些時候都可能導致程式異常執行或者崩潰。但指標的靈活性讓它可以實現很多複雜的操作,如指向指標的指標,指向函式的指標。

C語言中指標高階用法介紹

指向指標的指標:函式傳遞引數是傳值呼叫的,如果想在呼叫函式時改變傳入的引數的值,而且該傳入的引數的值本來是個指標時,這時就可以使用指向指標的指標了,以這種方式一般不用給函式返回引數,函式中只拷貝指向指標的指標值,而被指向的指標以及該指標指向的記憶體單元都可以直接操作,

void add_to_list(struct node **list, int n) {

struct node *new_node;

new_node = malloc(sizeof(struct node));

if(new_node == NULL) { // 確認申請記憶體成功

printf("Error: malloc failed in add_to_listn");

exit(EXIT_FAILURE);

}

new_node->value = n;

new_node->next = *list;

*list = new_node;

}

add_to_list(&first, 10);

該函式用於將結點新增到一個連結串列的表頭,first本身是一個指標,其指向連結串列的表頭結點,&first將其指標的地址傳入函式賦值給指向指標的指標**list,此時list為指向first指標的指標,*list即為first,因此在函式內部對*list進行操作即相當於對外部的first指標進行操作一樣,圖示如下:

[指標]C語言中指標的高階用法

指向函式的指標:指標不只能指向資料,也能指向函式。函式佔用記憶體單元,每個函式都有地址的,因此可以使用指向函式的指標。指向函式的指標在呼叫函式較多的地方會用到,另外也可以設計架構利用函式指標模擬某一物件的行為。

double integrate(double (*f)(double), double a, double b); // 宣告一,表明第一個引數接收函式指標

double integrate(double f(double), double a, double b); // 宣告二,不建議使用,表意不明確

result = integrate(sin, 0.0, PI/2); // 呼叫

在integrate函式體內(*f)(x)即表示sin(x)的呼叫。

由於C語言將函式指標當成資料指標對待,可以將函式指標儲存在變數之中,也可以當作陣列的元素,這樣,在索引陣列元素時就可以得到事先儲存好的`函式呼叫了。函式指標也可用作結構或聯合的成員,可以作為函式的返回值等。

傳遞給函式指標的值是某個函式的函式名,後面不用括號,這個與陣列類似,陣列名代表地址,函式名也是代表地址。

void (*pf)(int); // 函式指標變數宣告

pf = f; // 函式指標變數賦值

(*pf)(i); // f(i),函式指標指向的函式的呼叫,也可以直接用pf(i)

函式指標陣列:

void (*file_cmd[])(void) = {new_cmd, open_cmd; close_cmd, close_all_cmd, save_cmd, save_as_cmd, save_all_cmd, print_cmd, exit_cmd}; // 函式指標陣列初始化賦值,函式指標陣列在函式指標變數後多了[]

(*file_cmd[n])(); // 函式指標陣列元素的呼叫,呼叫對應的函式,也可以用file_cmd[n]();

受限指標(C99):

int * restrict p; // p為受限指標,restrict為關鍵字

受限指標p指向的物件在之後需要修改,那麼該物件不會允許通過除p之外的任何方式訪問。一個例子就是中的memcpy和memmove兩個函式的區別,其原型分別為:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n); // 表明s1和s2不應當重疊

void *memmove(void * s1, const void * s2, size_t n);

靈活陣列成員(C99):這個功能用於字串陣列作為結構的成員時動態分配記憶體,

struct vstring {

ing len;

char chars[];

}; // 包含字串陣列的結構,該結構最後一個成員為陣列時,長度可省略--就是靈活陣列成員

struct vstring *str = malloc(sizeof(struct vstring) + n);

str->len = n;