2017-04-11 230 views
0

我想比較一個數字和一個地址。 這是代碼。錯誤C2446:'==':沒有從'int *'轉換爲'int'

#include "stdio.h" 
int main (void) { 
    int a = 1; 
    printf("%#x\n", &a); // The address of a is 0x18ff44 
    int b = 0x18ff44; 
    if (b == &a) {  //error 
     printf("no\n"); 
    } 
    return 0; 
} 

我想知道我是否可以將數字與地址進行比較。

錯誤:錯誤C2446: '==':沒有從 '詮釋*' 轉換爲 '廉政'

我做了一些研究,我有兩個hypothesises:

  • 也許是因爲不同的數據類型無法比較。

    但我試圖比較float的數據類型與char,並且代碼compielred正確。

  • 我學會了MSDN的編譯器錯誤c2446。翻譯是「編譯器無法將type1轉換爲type2」

我的假設是,當執行關係操作時,編譯器需要將type1轉換爲type2。但'int *'到'int'的轉換沒有意義。 我的問題:這個假設是否正確?如果不是,那爲什麼會發生?

編譯器的信息:VC 6.0從https://www.microsoft.com

+0

首先,如果你想打印一個指針,你應該使用''%p''格式,它必須是一個'void *'(需要一個明確的轉換)。閱讀例如[這個'printf'(和家庭)參考](http://en.cppreference.com/w/c/io/fprintf)瞭解更多信息。 –

+0

您的代碼調用未定義的行爲。要打印一個指針,使用'%p',它需要'void *'。 – Olaf

+0

至於錯誤,應該很清楚:你有兩個你想要比較的不兼容類型的值。 –

回答

1

類型的bint)是不相容用表達&aint *)的類型。解決方法是簡單的 - 聲明b作爲int *

int *b = (int *) 0x18ff44; // literal will have integral, non-pointer type, 
...      // so the cast is necessary 
if (b == &a) // int * == int * 
{ 
    ... 
} 

現在詞語具有兼容的類型,錯誤就會消失。

打印指針值,使用%p轉換說明像這樣:

printf("&a = %p\n", (void *) &a); 

這是在C中很少(如果不僅是)的地方之一是鑄造void *是必要的。

編輯

要回答一個更大的問題,爲什麼int不符合int *

int數據類型是一個帶符號的類型,且僅保證來表示範圍[-32767,32767]值。它可以代表更廣泛的值(在大多數現代實現中,它通常是[-232, 232-1]),但它可能或可能不能表示所有可能的指針值。指針值可以轉換爲int值,反之亦然,但結果不保證有意義或定義明確。

指針類型的表示基本上取決於實現,並且該表示可能甚至不是標量值。它對於不同的指針類型甚至可能不同(儘管void *char *必須具有相同的表示和對齊)。因此,int與指針類型之間的直接比較可能沒有意義。實現可以在引擎蓋下使用相同的字大小和表示形式,但由於不能保證是這種情況,所以語言要求這些類型不兼容。

0

下載這似乎工作:

#include "stdio.h" 
int main (void) { 
    int a = 1; 
    printf("%p\n", &a); // The address of a is 0x18ff44 
    int b = 0x18ff44; 
    if (b == (int) &a) {  //no error 
     printf("no\n"); 
    } 
    return 0; 
} 

編輯:對於一般性的緣故在64個系統中,使用此:

#include "stdio.h" 
int main (void) { 
    int a = 1; 
    printf("%p\n", &a); // The address of a is 0x18ff44 
    long long b = 0x18ff44; 
    if (b == (long long) &a) {  //no error 
     printf("no\n"); 
    } 
    return 0; 
} 
+0

它似乎可以工作,但是如果指針不適合'int'(在64位系統上通常是這樣),該怎麼辦?這通常是比較指針的一種非常糟糕的方式。 –

+1

@Someprogrammerdude它是VC6。它嚴格的32位。 – JeremyP

+0

@JeremyP:這仍然是比較指針值的一種非常糟糕的方式。 –

0

是的,您可以將變量與地址進行比較,但這非常危險。

首先,你的代碼用gcc版本4.6.3編譯正確。所以我假設編譯器錯誤與MSVC相關,並且肯定會被禁用。

儘管如此,

的地址類型是size_t,其可以是(通常)32或64根據在機器上,並建立環境。另一方面,整數可能小於size_t,不足以解決整個RAM的問題!所以我建議你使用size_t而不是int(或者將你的整數和指針都轉換爲size_t),然後比較它們,我認爲這是最安全的,因爲我們真的比較了兩種內存指針類型整數和浮點數。

我會做這樣的事情:

size_t a_adr = (size_t)&a; 
size_t b_adr = (size_t)&b; 

if (a_adr == b_adr) 
    .. 

與指針處理我的朋友時要小心。

+0

我不認爲'size_t'確保足夠大以容納一個指針。如果編譯器有'intptr_t'是正確的類型。對於VC 6而言'int'足夠大,儘管我會用'unsigned long'去掉。 – JeremyP

+0

爲什麼不把'b'聲明爲'int *'? –