C語言中的 *p[2] 與 (*p)[2] 的截然不同



C語言運算符優先級表(由上至下, 優先級依次遞減)

運算符 結合性
()  []  ->  . 自左向右
 !  ~  ++  --  -  (type)  *  &  sizeof 自右至左
*  /  %  自左向右
+  -  自左向右
<<  >>  自左向右
<  <=  >  >=  自左向右
==  !=  自左向右
自左向右
自左向右
自左向右
&&  自左向右
||  自左向右
?:  自右至左
assignments  自右至左 
自左向右

 (來自C陷阱與缺陷)


 


 

對於( )  或者  [ ] 的優先級是最高的

於是對於  *p[2]  結合的方式應該是   *(p[2])    對於  (*p)[2]  顯然結合方式是括號中的 *p 優先於 [2]

具體

char *p[2]  表示p是一個存儲指向char類型數據的指針的數組

char (*p)[2]  則表示*p是一個擁有兩個char類型元素的數組,那么p則表示指向這個數組的指針

void test(){
    char *p1[2];
    char (*p2)[2];
    printf("p1----%d\n", sizeof(p1));
    printf("p2----%d\n", sizeof(p2));
    return;
}

得到的結果是

可以看到p1表示的是一個擁有兩個(char *)類型的數組,一個指針占有4個字節,倆個當然是8個字節

而p2僅僅就只是一個指針,只占有4個字節

常用用途


  • 對於  *p[]

在main函數的參數中有使用到,其中的 char *argv[]的argv就是一個指針數組,用來存儲函數調用時傳進來可變個數的參數

(詳細:利用 gdb 探究main(int argc, char *argv[]){} 中的char *argv[]

int main(int argc, char *argv[])
{
    something you want to do;
    return 0;
}

比如可以這樣

char *pp[2] = {"hello", "world",};

pp[0]存儲字符串"hello"的第一個字符的地址,pp[1] 存儲字符串"world"的第一個字符的地址

printf("%s\n", pp[0]);

將會打印出 hello


  • 對於  (*p)[]

無疑就是可以作為二維數組的引用

其實二維數組的本質也是一維數組,那么當我們定義一個二維數組的時候為什么不可以使用像引用一維數組的那樣的指針來引用二維數組呢?

錯誤樣例

void arrays(){
    int nums[3][4] = {0};
    int *pn = nums;
}

原因就是二維數組其實就是一個成員是一維數組的一維數組,所以它的類型是應該是數組類型

而這里的pn所指的類型是int,就會出現類型不匹配的問題

正確的方式是

void arrays(){
    int nums[3][4] = {0};
    int (*p_nums)[4] = nums;
}

這樣的p_num是指向類型為數組的指針,與nums的類型相匹配


補充

二維數組在內存中的存儲問題

示例代碼

#include <stdio.h>
#include <stdlib.h>

int main()
{
    /*定義char類型便於觀察地址,因為char只占一個byte*/
    char chars[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12},};
    printf("-------------------------------------------------------------------\n\n");

    for(int i = 0; i < 3; ++i){
        for(int j = 0; j < 4; ++j){
            printf("%5d(%d)", chars[i][j], (int)&chars[i][j]);
        }
        printf("\n");
    }

    printf("\n-------------------------------------------------------------------\n");

    printf("%d\n", sizeof(chars));
    printf("%d\n", (int)chars);
    printf("%d\n", (int)(chars + 1));/*移動了4個元素,行移動*/

    printf("-------------------------------------------------------------------\n");

    printf("%d\n", sizeof(chars[0]));
    /*可以看作是一維數組的第一個元素的地址 形如 一維數組中的 &array[0]*/
    printf("%d\n", (int)&chars[0]);
    /*可以看作就是一維數組里的第一個元素是數組,它相當於一個數組名表示數組地址  形如  array*/
    printf("%d\n", (int)chars[0]);

    printf("-------------------------------------------------------------------\n");

    return 0;
}

輸出

得到的結果以及代碼注釋已經可以說明一些問題了,就不再重復


本節完...... 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM