C語言指針基礎入門

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;}

當上面的代碼被編譯和執行時,它會產生下列結果:

圖片

能夠看出經過指針能夠修改變量的值,實際上指針是直接對內存進行操做,指針存在的最大意義是間接賦值

圖片C語言中的空指針
圖片

在變量聲明的時候,若是沒有確切的地址能夠賦值,爲指針變量賦一個 NULL 值是一個良好的編程習慣。賦爲 NULL 值的指針被稱爲指針。

NULL 指針是一個定義在標準庫中的值爲零的常量。請看下面的程序:

int main() {  int  *ptr = NULL;  printf("ptr 的地址是 %p\n", ptr);  return 0;}


當上面的代碼被編譯和執行時,它會產生下列結果:

圖片

#define NULL((void*)0NULL是一個宏定義,是把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 訪問內存時須要的是地址,而不是變量名和函數名!變量名和函數名只是地址的一種助記符,當源文件被編譯和連接成可執行程序後,它們都會被替換成地址。編譯和連接過程的一項重要任務就是找到這些名稱所對應的地址。

相關文章
相關標籤/搜索