C語言的精華指針,沒學指針就是沒學C語言!零基礎了解C語言指針

c語言基礎 發佈 2020-04-02T23:26:21+00:00

int *ptr = NULL; if /* 如果 p 為空,則賦值 */視頻不深奧,不需要鑽研,在公交、在地鐵、在廁所都可以觀看,隨時隨地漲姿勢

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

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

實際上每次編譯運行的結果都會不一樣,因為內存是隨機分配的。

通過上面的實例,我們了解了什麼是內存地址以及如何訪問它。接下來讓我們看看什麼是指針。

什麼是指針?

所謂指針,也就是內存的地址;所謂指針變量,也就是保存了內存地址的變量。不過,人們往往不會區分兩者的概念,而是混淆在一起使用,在必要的情況下,大家也要注意區分。就像其他變量一樣,您必須在使用指針存儲其他變量地址之前,對其進行聲明。指針變量聲明的一般形式為:

type *var-name;

在這裡,type 是指針的基類型,它必須是一個有效的 C 數據類型,var-name 是指針變量的名稱。用來聲明指針的星號 * 與乘法中使用的星號是相同的。但是,在這個語句中,星號是用來指定一個變量是指針。以下是有效的指針聲明:

  int    *ip;    /* 一個整型的指針 */
  double *dp;    /* 一個 double 型的指針 */
  float  *fp;    /* 一個浮點型的指針 */
  char   *ch;     /* 一個字符型的指針 */

所有實際數據類型,不管是整型、浮點型、字符型,還是其他的數據類型,對應指針的值的類型都是一樣的,都是一個代表內存地址的長的十六進位數。

不同數據類型的指針之間唯一的不同是,指針所指向的變量或常量的數據類型不同。

如何使用指針

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 指針是一個定義在標準庫中的值為零的常量。請看下面的程序:

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

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

尾言

文章都是手打原創,每天最淺顯的介紹C語言、C++,windows知識,喜歡我的文章就關注一波吧,可以看到最新更新和之前的文章哦。更多C語言指針可觀看視頻教程。

如果足下基礎比較差,不妨關注下人人都可以學習的視頻教程,通俗易懂,深入淺出,一個視頻只講一個知識點。視頻不深奧,不需要鑽研,在公交、在地鐵、在廁所都可以觀看,隨時隨地漲姿勢

關鍵字: