【C 語言入門】175.指標間轉型的限制

在之前的文章我們有提過,我們在函式之間,可以直接傳遞陣列。

#include <stdio.h>
void print(int (*q)[3]){
    int i;
    for(i=0;i< sizeof(*q)/sizeof((*q)[0]);i++){
        printf("%d",(*q)[i]);
    }
    printf("\n");
}

int main()
{
    int v[] ={1, 2, 3};
    print(&v);    
    return 0;
}

輸出結果:

123

我們可以把陣列的位址,直接傳遞到函式內部。

我們之前也說過,我們在函式傳參數時,可以不用寫大小,像這樣 void print(int (*q)[])

不寫大小也就代表這是一個指標,也就是它會解釋成這個樣子,void print(int *(*q)),也可以直接寫成 void print(int **q)

從原本整數的陣列,變成一個整數的指標看待 。

#include <stdio.h>
void print(int **q){
    int i;
    for(i=0;i< sizeof(*q)/sizeof((*q)[0]);i++){
        printf("%d",(*q)[i]);
    }
    printf("\n");
}

int main()
{
    int v[] ={1, 2, 3};
    print(&v);    
    return 0;
}

q 本身是一個指標,指向一個整數的指標。

這時候 q 指向的空間也就是整數的指標 sizeof(*q) 其實就是 sizeof(int*)

sizeof(*q)/sizeof((*q)[0]) 其實就是 sizeof(int*)/sizeof(int)

q 本身存了一個位址,但是位址裡面住著的是整數的指標。

指標間的轉型

絕大部分情況下,指向不同型別的指標間是不能直接隱性轉型的。

我們來看以下的例子。

int intVar;
double doubleVar;

int *intPointer = &doubleVar;      //(int *) = (double *)  (?)
double *doublePointer = &intVar;   //(double *) = (int *)  (?)

假設我有一個整數的指標,我可以把 double 的位址存在一個指標裡面嗎?

答案是不可以的。

假設我有一個 double 的指標,我可以把整數位址存在一個 double 的指標裡面嗎?

答案是不可以的。

這樣做很可能產生難以預計的行為。

我們再看一個例子。

int **intPointerPointer1 = &intVar; // (int **) = (int *) (?)

右邊是指標指向整數,左邊是指標指向整數的指標。

他們指向的東西是不同的,因此也不可以被直接複製。

int **intPointerPointer2 = &intArray;    // (int **) = (int (*)[3]) (?)

陣列的位址指向長度為 3 的陣列,不能存到指標的指標。

int **intPointerPointer3 = intVar;       // (int **) = (int [3])  (?)

右邊是陣列,左邊是整數指標的指標。

一般如果指向的型別部不同、以及指標之間的互轉,一般都是不行的,只有少數例外。

例外1

int *n = v;      //(int *) = (int [5])  (O)

陣列隱性轉型成指標的話是 ok 的。

例外2

const int *c = &a;     //(const int *) = (int *)  (O)

加上 const 。我們可以把一個指向整數的指標,隱性轉型成指向 const 整數的指標。

Leave a Comment

Your email address will not be published. Required fields are marked *