簡體   English   中英

為什么不能用另一個指向const char的指針初始化一個指針?

[英]Why can't a pointer be initialized with another pointer to a const char?

這是我們在C ++類簡介中得到的另一個“重塑方向”問題:

編寫一個函數,該函數返回字符串中字符序列首次出現的位置,即strstr函數的變體。

我開始如下編寫函數:

int strstr2(const char *text, const char *pattern) {
    int pos = 0;
    char *temp;
    temp = text;
}

我以為我會記住該函數的字符串的第一個字符的地址以供將來使用,但是編譯器說:

無法將類型“ const char *”的值分配給類型“ char *”的實體。

我知道一旦初始化就無法更改常量,但是為什么我不能將指向常量char的指針分配給另一個非常量指針呢?

我讀了一些有關指針和常量的問題,似乎這篇文章的公認答案的底部可能回答了我的問題,但是我不確定百分百,因為對我來說討論仍然處於高級水平。

我的第二個問題是,解決方法是什么? 如何定義一個指向字符串開頭的指針?

謝謝。

這與const-correctness有關 const char *text表示text是指向常量char的指針。 這意味着如果您嘗試做類似的事情

*text = 'a'

由於您嘗試修改const對象,因此編譯器將發出錯誤。 如果可以的話

char *temp;
temp = text;

那你可以做

*temp = 'a'

即使您剛剛修改了const對象,也不會出錯。 這就是為什么如果您確實想拋棄const C ++要求您使用const_cast (有一些用例,但到目前為止,它們並不是您通常想要做的)。


危險,下面有龍。 如果決定使用const_cast,請非常小心

假設您必須處理一個僅使用char*的舊API調用, 但它保證不會進行修改 ,那么您可以使用類似

int wrap_api(const char *text)
{
    return api_call(const_cast<char*>(text));
}

並且這將是“好的”,因為api_call保證不會修改字符串。 另一方面,如果api_call可以修改,則僅當text指向的內容實際上不是const時才合法

char foo[] = "test"
wrap_api(foo);

如果foo被修改將是合法的,但是

const char foo* = "test"
wrap_api(foo);

如果foo被修改並且是未定義的行為,則將不合法。

如果允許分配,您將可以合法地編寫:

*temp = 'x'; // write to char* is legal in general

但這在這種情況下會很糟糕,因為您將要寫入一個常量。

該標准可以temp = text分配是合法的,而*text = 'x'是未定義的行為,但這沒有任何意義,因為T*const T*之間的唯一區別是是否可以寫入它。

因此,C ++禁止為T*類型分配const T* T*類型的值是很合乎邏輯的,這樣可以避免以后做一些不好的事情,而是強制您使用const char* temp; temp = text; const char* temp; temp = text; 在這種情況下。

這是const-correctness類型安全性的一部分。 由於text是指向const char的指針,因此您無法修改其指向的字符。 這是一件好事,也是一項安全措施。

但是,如果允許為其分配非常量字符指針,則整個安全性將失效! 因為比起您可以通過上述指針修改字符並繞過安全性!

因此,不允許進行此分配。 要解決此問題,請將您的temp也標記為指向const char的指針: const char* temp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM