2013-05-14 39 views
4

在我對今天我意識到的const的理解中,您的答案非常想要清除這個主要空白。「const int * ptr =&i」是什麼意思?爲什麼它接受非常量的地址?

在我的節目我已經使用了聲明const int *ptr=&i;但沒有使用任何const預選賽變量。兩個東西都困惑我:

1)當我試圖修改的值使用ptr,在那裏我已經使用const int *ptr=&i;,我得到的錯誤assignment of read-only location '*ptr'|,儘管我還沒有聲明的變量const qualifier.So什麼究竟陳述const int *ptr=&i;是什麼意思,它與int * const ptr=&i;有什麼不同?

我有它鑽入我的頭const int *ptr=&i;意味着指針存儲常量的地址,而int * const ptr=&i;意味着指針本身是恆定的,今天一個用戶告訴我,在討論中不能change.But(LINK),其const int *ptr means the memory pointed to must be treated as nonmodifiable _through this pointer_。我發現這個東西是新的,因爲這種意思是「一些選擇指針不能改變值(而其他人可以)」。我不知道這樣的選擇性聲明!!但是一位180K的老兵證明了這個用戶是正確!!因此,你可以用更清晰,更詳細,更嚴謹的方式說明這一點嗎?「const int * ptr =&i; 是什麼意思?

2)我還被告知,我們可以謊言在聲明const int *ptr=&i;程序通過向pointer.What分配非恆定的地址是什麼意思?爲什麼我們允許這樣做?如果我們將一個非常量的地址賦給指向ptr的指針,這個指針需要一個常量的地址,那麼爲什麼我們不會發出警告呢?如果它是如此寬容以便分配非常量的地址,爲什麼它會拋出一個錯誤當我們試圖改變那個非常量的值時,這是一個合理的事情,這個指向變量是一個非常量?

#include <stdio.h> 

int main() 
{ 
int i=8; 
const int *ptr=&i; 
*ptr=9; 
printf("%d",*ptr); 
} 

錯誤:assignment of read-only location '*ptr'|

回答

6

定義const int *ptr = &i;實際上是說:「我不會通過ptr修改i。」這並不是說該intptr點是const,它說,ptr不應該被用來進行修改。

這種轉換是允許的,因爲它是有道理的:既然iconst,我允許修改它,但我也可以選擇不進行修改。當我選擇不修改i時,沒有規則被破壞。而且,如果我創建了一個指向i的指針並說「我不打算使用這個指針來修改i」,那也沒關係。

您希望這樣做的原因是,您可以將對象的地址傳遞給需要指向const對象的例程。例如,考慮strlen例程。 strlen例程不修改其輸入,因此其參數是指向const char的指針。現在,我有一個指向char的指針,我想知道它的長度。所以我打電話給strlen。現在我傳遞一個指向char的指針作爲指向const char的參數的參數。我們希望該轉換工作。這是完全有道理的:可以修改我的char如果我想,但strlen例程不打算,因此它將它們視爲const char

1)你得到*ptr = something;錯誤,因爲你宣佈ptr爲指針,以const int,但你侵犯了您的承諾不使用ptr修改intptr指向的對象不是const,這一事實並不否定您的承諾,即不使用ptr來修改它。

2)將非const對象的地址分配給指向const的指針不是謊言。該作業沒有說該對象是const,它表示不應該使用該指針來修改該對象。

另外,雖然您沒有問過這個問題,但C中的const屬性並沒有完全綁定。如果將對象定義爲const,則不應對其進行修改。但是,在其他情況下,將指向const的指針傳遞給將其轉換爲指向非const的指針的例程。這實際上是該語言的缺陷,無法保留以我們可能更喜歡的方式處理const所需的所有信息。一個例子是strchr例程。其聲明是char *strchr(const char *s, int c)。參數sconst char *,因爲strchr不會更改其輸入。但是,strchr例程的指針來自s(它指向字符串中的一個字符)。因此,在內部,strchr已將const char *轉換爲char *

這使您可以編寫通過char *strchr的代碼,並使用返回的指針修改字符串,這很好。但這意味着編譯器不能完全保護您免受錯誤的影響,比如將const char *傳遞給strchr,並使用返回的指針嘗試修改字符串,這可能是錯誤。這是C的一個缺點。

+0

感謝您的回答。我放棄了這個問題! – 2013-05-14 14:00:50

+0

儘管C可以爲「const」提供更多有用的語義[例如說如果一個參數被限定爲'const return',那麼在傳遞一個const參數時,返回值應該被當作'const'來處理,而當傳遞一個非const參數時應該被當作非const來處理 - 這對理想的語義'strchr']有許多場景涉及寫時複製對象,其中const正確性不能被靜態證明,並且語言必須不允許有用的語義或允許靜態驗證其正確性的構造。 – supercat 2016-10-12 23:06:30

-1

解開此:

const int的* PTR意味着 「* PTR是用const int」;即「ptr是指向const int的指針」。你不能寫* ptr = 9,因爲* ptr是一個常量。你可以寫int j; ptr =&j;因爲你可以允許指針ptr指向一個不同的int。

int * const ptr表示「ptr是一個指向int的常量指針」。你可以寫* ptr = 9,因爲你沒有改變ptr指向的地址。你不能把它分配給別的東西;即int j; ptr =&j;不會編譯。對於第二部分(2),const int * ptr非常有用,特別是在函數原型中,因爲它告訴函數的調用者,函數不會修改ptr所指向的變量。至於賦值,如果你有int * m = & i,那麼ptr = m是可以的,但是m = ptr是不好的,因爲後者會'拋棄const'。即你已經規避了const。

相關問題