1. 程式人生 > >指標是否能相加?C語言中的NULL總是被定義為0嗎?NULL總是等於0嗎?

指標是否能相加?C語言中的NULL總是被定義為0嗎?NULL總是等於0嗎?

一、指標是否能相加?

兩個指標是不能相加的。仍以街道地址的比喻為例,假設你住在湖濱大道1332號,你的鄰居住在湖濱大道1364號,那麼1332+1364指的是什麼呢?其結果是一個毫無意義的數字。如果你的C程式試圖將兩個指標相加,編譯程式就會發出警告。

 

當你試圖將一個指標和另外兩個指標的差值相加的時候,你很可能會誤將其中的兩個指標相加,例如,你很可能會使用下述語句:

    p=p+p2-p1;

 

上述語句是不正確的,因為它和下述語句完全相同:

    p=(p+p2)-p1;

正確的語句應該是:

    p=p+(p2-p1);

對此例來說,使用下述語句更好:

      p+=p2-p1;

 

但是,可以相減,

如果兩個指標向同一個陣列,它們就可以相減,其為結果為兩個指標之間的元素數目。仍以本章開頭介紹的街道地址的比喻為例,假設我住在第五大街118號,我的鄰居住在第五大街124號,每家之間的地址間距是2(在我這一側用連續的偶數作為街道地址),那麼我的鄰居家就是我家往前第(124-118)/2(或3)家(我和我的鄰居家之間相隔兩家,即120號和122號)。指標之間的減法運算和上述方法是相同的。

#include<stdio.h>

typedef struct {
    char *name;
}stuff;

stuff array[] = {
    {"paul"},
    {"allen"},
    {"james"},
    {"curry"},
    {"rose"},
    {"kobe"},
    {"anthory"},
    {"wade"},
};

int main()
{
    stuff *p0 = &array[0];
    stuff *p7 = &array[7];

    int diff = p7 - p0;
    printf("___p0_addr: %p\n",p0);
    printf("___p7_addr: %p\n",p7);


    printf("___p7-p0: %d\n",diff);


    printf("___p7-7_addr: %p\n",(void *)(p7 - 7));
    printf("___p7-7_addr: %p\n",(p7 - 7));
    printf("sizeof(array): %ld\n", sizeof(array));


}

結果如下(作業系統為64位):

 ___p0_addr: 0x601060
___p7_addr: 0x601098
___p7-p0: 7
___p7-7_addr: 0x601060
___p7-7_addr: 0x601060
sizeof(array): 64

 

二、C語言中的NULL總是被定義為0?NULL總是等於0?

NULL總是被定義為0嗎?

 

NULL不是被定義為0,就是被定義為(void *)0,這兩種值幾乎是相同的。當程式中需要一個指標時(儘管編譯程式並不是總能指示什麼時候需要一個指標),一個純粹的零或者一個void指標都能自動被轉換成所需的任何型別的指標。

NULL總是等於0嗎?

 

對這個問題的回答與“等於”所指的意思有關。如果你是指“與。比較的結果為相等”,例如:

    if(/*  ...  */)

    {  

        p=NULL;

    }  

    else  

    {

        p=/* something else */;

    }

    /*  ...  */

    if(p==0)

那麼NULL確實總是等於0,這也就是空指標定義的本質所在。

 

如果你是指“其儲存方式和整型值。相同”,那麼答案是“不”。NULL並不必須被存為一個整型值0,儘管這是NULL最常見的儲存方式。在有些計算機中,NULL會被存成另外一些形式。

 

如果你想知道NULL是否被存為一個整型值0,你可以(並且只能)通過除錯程式來檢視空指標的值,或者通過程式直接將空指標的值打印出來(如果你將一個空指標強制轉換成整型別,那麼你所看到的很可能就是一個非零值)。