程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 數組和指針的區別

數組和指針的區別

編輯:關於C語言

C++/C程序中,指針和數組在不少地方可以相互替換著用,讓人產生一種錯覺,以為兩者是等價的。

    數組要麼在靜態存儲區被創建(如全局數組),要麼在棧上被創建。數組名對應著(而不是指向)一塊內存,其地址與容量在生命期內保持不變,只有數組的內容可以改變。

指針可以隨時指向任意類型的內存塊,它的特征是“可變”,所以我們常用指針來操作動態內存。指針遠比數組靈活,但也更危險。

下面以字符串為例比較指針與數組的特性。

1 修改內容

       示例1中,字符數組a的容量是6個字符,其內容為hello\0。a的內容可以改變,如a[0]= ‘X’。指針p指向常量字符串“world”(位於靜態存儲區,內容為world\0),常量字符串的內容是不可以被修改的。從語法上看,編譯器並不覺得語句p[0]= ‘X’有什麼不妥,但是該語句企圖修改常量字符串的內容而導致運行錯誤。

char a[] = “hello”;

a[0] = ‘X’;

cout << a << endl;

char *p = “world”;     // 注意p指向常量字符串

p[0] = ‘X’;             // 編譯器不能發現該錯誤

cout << p << endl;

示例1 修改數組和指針的內容

2 內容復制與比較

    不能對數組名進行直接復制與比較。示例2中,若想把數組a的內容復制給數組b,不能用語句 b = a ,否則將產生編譯錯誤。應該用標准庫函數strcpy進行復制。同理,比較b和a的內容是否相同,不能用if(b==a) 來判斷,應該用標准庫函數strcmp進行比較。

    語句p = a 並不能把a的內容復制指針p,而是把a的地址賦給了p。要想復制a的內容,可以先用庫函數malloc為p申請一塊容量為strlen(a)+1個字符的內存,再用strcpy進行字符串復制。同理,語句if(p==a) 比較的不是內容而是地址,應該用庫函數strcmp來比較。

    // 數組…

    char a[] = "hello";

    char b[10];

    strcpy(b, a);           // 不能用   b = a;

    if(strcmp(b, a) == 0)   // 不能用  if (b == a)

    // 指針…

    int len = strlen(a);

    char *p = (char *)malloc(sizeof(char)*(len+1));

    strcpy(p,a);            // 不要用 p = a;

    if(strcmp(p, a) == 0)   // 不要用 if (p == a)

示例2 數組和指針的內容復制與比較

3 計算內存容量

    用運算符sizeof可以計算出數組的容量(字節數)。示例3(a)中,sizeof(a)的值是12(注意別忘了’\0’)。指針p指向a,但是sizeof(p)的值卻是4。這是因為sizeof(p)得到的是一個指針變量的字節數,相當於sizeof(char*),而不是p所指的內存容量。C++/C語言沒有辦法知道指針所指的內存容量,除非在申請內存時記住它。

注意當數組作為函數的參數進行傳遞時,該數組自動退化為同類型的指針。示例3(b)中,不論數組a的容量是多少,sizeof(a)始終等於sizeof(char *)。

    char a[] = "hello world";

    char *p  = a;

    cout<< sizeof(a) << endl;   // 12字節

    cout<< sizeof(p) << endl;   // 4字節

示例3(a) 計算數組和指針的內存容量

 

    void Func(char a[100])

    {

        cout<< sizeof(a) << endl;   // 4字節而不是100字節

}

示例3(b) 數組退化為指針

---------------------------------

1. 字符串宏 #define CONST_STR "const str" 宏在預編譯的時候會替換成實際的值
2.數組 數組名對應一塊內存,在生命周期內其地址和容量不會改變,數組裡面的內容可以變。
3.指針 指針指向一塊內存,如果指向字符串常量(RO),則不能修改內容。 如果申請了一塊內存,復制字符串常量,則可以修改內容

    stdioh
  1. #include h
  2. #include unistdh
  3. #include stdlibh
  4. #define CONST_STR
  5. typedef void string_test_routine_t
  6. void pointer_strcpy_macrovoid
  7.     char p
  8.     p charmalloc100
  9.     strcpyp CONST_STR
  10.     printf
  11.     printf
  12.     p0 a
  13.     printf
  14. void pointer_strcpy_stringvoid
  15.     char p
  16.     p charmalloc100
  17.     strcpyp
  18.     printf
  19.     printf
  20.     p0 a
  21.     printf
  22. void pointer_macro_stringvoid
  23.     char p CONST_STR
  24.     printf
  25.     printf
  26.     p0 a
  27.     printf
  28. void pointer_stringvoid
  29.     char p
  30.     printf
  31.     printf
  32.     p0 a
  33.     printf
  34. void array_macro_stringvoid
  35.     char a100 CONST_STR
  36.     printf
  37.     printf
  38.     a0 a
  39.     printf
  40. void array_stringvoid
  41.     char a100
  42.     printf
  43.     printf
  44.     a0 a
  45.     printf
  46. void array_strcpy_stringvoid
  47.     char a100
  48.     strcpya
  49.     printf
  50.     printf
  51.     a0 a
  52.     printf
  53. void array_strcpy_macrovoid
  54.     char a100
  55.     strcpya CONST_STR
  56.     printf
  57.     printf
  58.     a0 a
  59.     printf
  60. static string_test_routine_t func_base
  61.     array_strcpy_string
  62.     array_macro_string
  63.     array_string
  64.     array_strcpy_macro
  65.     pointer_macro_string
  66.     pointer_string
  67.     pointer_strcpy_macro
  68.     pointer_strcpy_string
  69. #define NUM_FUNC sizeof func_base sizeoffunc_base0
  70. void test_stringvoid
  71.     pid_t pid
  72.     i 0
  73.     string_test_routine_t func func_base
  74.     i 0 i NUM_FUNC i
  75.    
  76.         pid fork
  77.         pid 0
  78.        
  79.             printf
  80.        
  81.         pid 0
  82.        
  83.             funci
  84.             0
  85.        
  86.        
  87.        
  88.             sleep 1
  89.        
  90.    
  91. main
  92.     test_string
  93.     return 0

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved