C語言Plus 2020-04-02程序員
C語言指針程序有問題時不要擔憂。若是全部東西都沒問題,你就失業了編程
沒學指針就是沒學C語言!指針是C語言的精華,也是C語言的難點,破解C語言指針,會讓你的C語言水平日新月異。正如您所知道的,每個變量都有一個內存位置,每個內存位置都定義了可以使用連字號(&)運算符訪問的地址,它表示了在內存中的一個地址。請看下面的實例,它將輸出定義的變量地址:#include <stdio.h>int main(){ int var1; char var2[10]; printf("var1 變量的地址:%p\n", &var1); printf("var2 變量的地址:%p\n", &var2); getchar(); return 0;}
當上面的代碼被編譯和執行時,它會產生下列結果:ide
實際上每次編譯運行的結果都會不同,由於內存是隨機分配的。函數
經過上面的實例,咱們瞭解了什麼是內存地址以及如何訪問它。接下來讓咱們看看什麼是指針。測試
什麼是指針?
ui
所謂指針,也就是內存的地址;所謂指針變量,也就是保存了內存地址的變量。不過,人們每每不會區分二者的概念,而是混淆在一塊兒使用,在必要的狀況下,你們也要注意區分。就像其餘變量同樣,您必須在使用指針存儲其餘變量地址以前,對其進行聲明。指針變量聲明的通常形式爲:spa
type *var-name;
在這裏,type 是指針的基類型,它必須是一個有效的 C 數據類型,var-name 是指針變量的名稱。用來聲明指針的星號 * 與乘法中使用的星號是相同的。可是,在這個語句中,星號是用來指定一個變量是指針。如下是有效的指針聲明:操作系統
int *ip; /* 一個整型的指針 */ double *dp; /* 一個 double 型的指針 */ float *fp; /* 一個浮點型的指針 */ char *ch; /* 一個字符型的指針 */
全部實際數據類型,不論是整型、浮點型、字符型,仍是其餘的數據類型,對應指針的值的類型都是同樣的,都是一個表明內存地址的長的十六進制數。3d
不一樣數據類型的指針之間惟一的不一樣是,指針所指向的變量或常量的數據類型不一樣。指針
使用指針時會頻繁進行如下幾個操做:定義一個指針變量、把變量地址賦值給指針、訪問指針變量中可用地址的值。下面的實例涉及到了這些操做:
int main() { int var = 20; /* 普通變量的聲明 */ int *point; /* 指針變量的聲明 */ point = &var; /* 把變量var的地址賦值給指針變量point */ printf("&var value: %p\n", &var); /* 在指針變量中存儲的地址 */ printf("point value: %p\n", point); printf("var value: %d\n", var); /* 使用指針訪問值 */ printf("*point value: %d\n", *point); getchar(); return 0;}
當上面的代碼被編譯和執行時,它會產生下列結果:
能夠看出經過指針能夠修改變量的值,實際上指針是直接對內存進行操做,指針存在的最大意義是間接賦值,
在變量聲明的時候,若是沒有確切的地址能夠賦值,爲指針變量賦一個 NULL 值是一個良好的編程習慣。賦爲 NULL 值的指針被稱爲空指針。
NULL 指針是一個定義在標準庫中的值爲零的常量。請看下面的程序:
int main() { int *ptr = NULL; printf("ptr 的地址是 %p\n", ptr); return 0;}
當上面的代碼被編譯和執行時,它會產生下列結果:
#define NULL((void*)0)NULL是一個宏定義,是把0強轉爲空指針。在大多數的操做系統上,程序不容許訪問地址爲 0 的內存,由於該內存是操做系統大哥的。然而,內存地址 0 有特別重要的意義,它代表該指針不指向一個可訪問的內存位置。但按照慣例,若是指針包含空值(零值),則假定它不指向任何東西。
如需檢查一個空指針,您可使用 if 語句,以下所示:
#include <stdio.h>int main() { int xxoo = 666; int *ptr = NULL; printf("ptr 的地址是 %p\n", ptr); for (int i = 0; i < 2; i++) { if (ptr == NULL) /* 若是 p 爲空,則賦值 */ { ptr = &xxoo; } if (ptr != NULL) /* 若是 p 非空,則修改內容*/ { *ptr = 'A'; } } printf("xxoo:%d\n", xxoo); getchar(); return 0;}
你們本身測試下,頗有意思~
C語言用變量來存儲數據,用函數來定義一段能夠重複使用的代碼,它們最終都要放到內存中才能供 CPU 使用。
CPU 只能經過地址來取得內存中的代碼和數據,程序在執行過程當中會告知 CPU 要執行的代碼以及要讀寫的數據的地址。若是程序不當心出錯,或者開發者有意爲之,在 CPU 要寫入數據時給它一個代碼區域的地址,就會發生內存訪問錯誤。這種內存訪問錯誤會被硬件和操做系統攔截,強制程序崩潰,程序員沒有挽救的機會。
CPU 訪問內存時須要的是地址,而不是變量名和函數名!變量名和函數名只是地址的一種助記符,當源文件被編譯和連接成可執行程序後,它們都會被替換成地址。編譯和連接過程的一項重要任務就是找到這些名稱所對應的地址。