2013-10-18 31 views
-3

我有以下代碼:字符指針參數不同的行爲

void uppercase(char *sir) 
{ 

for(int i=0;i<strlen(sir);i++) 
{ 

sir[i]=(char)toupper(sir[i]); 
} 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 

//char lower[]="u forgot the funny"; this works 
//char *lower="u forgot the funny"; this gives me a runtime error 

uppercase(lower); 

cout<<lower<<"\n\n"; 

system("PAUSE"); 

return 0; 
} 

我注意到,如果我與焦矢量運行它的工作原理。 當我嘗試使用第二種方法運行時,它會生成運行時錯誤。 我想知道這種行爲的原因請。

+0

一個真正的C++編譯器不應該*編譯*第二種情況。 –

+0

@KerrekSB:在C++ 11中,我會同意。但是在C++ 03中,我相信這會編譯並定義好 - 這並不是說程序員可能期待什麼! –

+0

@KerrekSB clang on osx只是發出警告'從字符串文字到'char *'的轉換已被廢棄[-Wdeprecated-writable-strings]' – SheetJS

回答

2

不能修改字符串文字;這樣做(如你的第二種情況)是未定義的行爲。

char x[] = "foo"; 

創建包含字符f,o,o,\0的字符數組。它基本上是一個可變的字符串副本。

char *x = "foo"; 

創建指向"foo"字符串文字的字符串指針。文字可能存在於某些只讀存儲器,程序存儲器或常量池中。寫入它是未定義的行爲。另外,不是字符串文字的類型總是const char[],所以將它分配給char *違反了const正確性。

+0

+1但注意:'char *'示例將不再在C++ 11下編譯。 –

+0

正如nneonneo所說,後者不起作用,因爲你不能將const字符串文字轉換爲非const char *。也就是說,在'char * x =「foo」之前加'const';'將工作。 – nomann

+0

@nomannasim:那麼你不能將它傳遞給'大寫'。 – nneonneo

1

前者創建一個字符陣列,它可以被突變,後者是一個指向固定存儲器(其不能被操縱)