2013-12-09 57 views
1

維基百科:什麼決定全局定義的字符串是否在數據段的讀寫區域或只讀區域?

爲const char *字符串= 「Hello World」 的使字符串文字「你好 世界」存儲在初始化只讀區和字符串 指針變量已初始化讀寫區域。

  1. 爲什麼存儲在string讀寫區域,當它被用const修飾符聲明?
  2. 爲什麼"hello world"存儲在只讀區域當字符串應該是不可變的?
  3. 有沒有一種方法可以確定(在代碼本身)變量存儲在哪個段和區域(C99)?
  4. 爲什麼BSS /初始化數據段中的只讀和讀寫區域之間沒有分離?
  5. 如果const修飾符被關閉,上面引用的語句是否仍然是真的?如果不是,爲什麼不呢?

回答

2

你誤會。該字符串始終是隻讀的。持有該字符串指針變量string是一個可變的變量,因此必須進行重新分配:

const char * string = "abc"; 

int main() 
{ 
    string = NULL; // this must work 
} 

此外,你應該明白,C標準不包含有關實際程序的實施細則任何要求,特別是沒有「只讀存儲器」的概念。它純粹是平臺(編譯器,鏈接器,二進制格式,加載器)的選擇,無論他們是否希望提供具有不同訪問權限的不同類型的內存。

+0

所以,即使你離開了const,「abc」仍然是不可變的 - 那麼添加const的意義是什麼?謝謝 –

+1

@WuschelbeutelKartoffelhuhn:它基本上是一個錯誤,但由於歷史的慣性,C允許您爲字符串文本指定一個指向'char *'的指針。考慮它歷史古怪。對於它的價值,C++ 11修復了這個問題。字符串文字總是隻讀的,就是這樣。 –

2

我不太明白你想要問什麼。在你的例子中,"hello world"存儲在讀寫區域,但是指向的不是,因爲它沒有被聲明爲const

const char* string手段,這是一個可變指針恆定串

爲了使指針被存儲在只讀區,太,你必須將其聲明爲const

const char* const string = "hello world"; 

常量

我一般都修飾符C和C++語言綁定到它的值左側。只有在左邊沒有任何東西的時候,它們纔會適用於右邊的下一個。因此,這兩個是相同的:

char const* str; // Bind const modifier to 'char'. 
const char* str; // Bind const modifier to 'char', since there is nothing to the left. 

當看着這個,你需要知道指針聲明由2個「部分」組成。 類型指針指向,而指針本身

修飾符像constvolatile可以應用到這兩個部分組成:

char* const str; // A constant pointer, that points to a mutable char (array). 

下面的幾個例子,如何const影響變量:

char const* a = "foo"; 
*a = '\0'; // Error, the array pointed to is not mutable. 
a = "bar"; // Okay. 

char* const b = "foo"; 
*b = '\0'; // Okay. 
b = "bar"; // Error, the pointer is not mutable. 
+0

我不知道你可以把const放在標識符後面。現在對我來說很有意義。謝謝! –

+0

我添加了一段'const',給我一秒鐘;) –

1
  • 爲什麼存儲在讀寫區域字符串時,它是用const修飾聲明?

這是所有文字常量都去的地方。這樣他們可以在流程之間共享,也可以在其他指針之間共享。

  • 爲什麼「hello world」存儲在讀寫區域時,字符串應該是不可變的?

指針(到文字常量)本身可變。 「hello world」很可能存儲在全局常量中。

  • 有沒有一種方法可以確定(在代碼本身中)變量存儲在哪個段和區域(C99)?

全局和靜態變爲'全局變量',局部變量和參數變爲'棧',malloc'變成'堆'。至於全局變量,那些是const的可能會也可能不會去'全局常量'。

  • 爲什麼BSS /初始化數據段中的只讀和讀寫區域之間沒有分離?

通常兩個段 - 一個用於常量數據(以及一個進程之間共享),一個用於可變數據(其不能被明顯地共享)。

  • 如果const修飾符被關閉,上面的引用語句仍然是真的嗎?如果不是,爲什麼不呢?

在C++中,所有字符串文字都是const char*,而在C中它們本質上是char*。因此,在C中的變量(除了有時會出現警告)之外添加/刪除const變量沒有問題,但它會在C++中導致const-cast錯誤。在const char* string中有const禁止string的數據被修改。

P.S.下面的代碼可以幫助你瞭解正在發生的事情:

int main() 
{ 
    char s1[] = "abc"; 
    char* s2 = "abc"; 
    const char* s3 = "abc"; 
    s1[0] = 'z'; 
    s2[0] = 'x'; 
    // s3[0] = 'y'; will not compile due to const 
    printf("%s %s %s\n", s1, s2, s3); 
    s2++; s3++; // it perfectly fine to modify pointers themselves 
} 

根據平臺,代碼可能在S2崩潰(Linux)的[0]賦值,或可能成功;在後面的情況下,s3也可能會被修改(Cygwin)或者可能不會。