2009-04-19 62 views
4

鑑於scanf在documentation from Microsoft中有(const char *),並且回答了this question當我對(char **)提升(const char **)做同樣的事情時會發生什麼?這爲什麼允許從(char *)提升到(const char *)?

基本上這是爲什麼編譯?

#include <stdio.h> 
int main(int argc, char **argv) 
{ 
    char szArray[50]; 
    int i = 0; 
    strcpy(szArray,"10"); 
    /* the following code is upcasting the (char *) to (const char *) */ 
    sscanf(szArray,"%d",&i); 
    return 0; 
} 

爲什麼不能編譯?

#include <stdio.h> 
void processargs(const char **p) 
{ 
} 
int main(int argc, char **argv) 
{ 
    processargs(argv);   
    return 0; 
} 

這兩者似乎都在對指針做同樣的事情!

+1

你不明白一件事:如果T - > U工作,那麼這並不意味着T * - > U *的作品。只是一個簡單的:double a = 4;/* int - > double */int p; double * dp =&p;/* int * - > double * ?? */ – 2009-04-19 23:40:42

+0

我不會在這裏改變類型......兩組都是指針。 – ojblass 2009-04-19 23:43:02

+0

請關閉另一個,而不是這個...... – ojblass 2009-04-19 23:48:36

回答

12

char** -> const char **是危險的,因爲您可能最終意外修改了底層const對象。

正確的方式來寫你想要的是:

void processargs(const char * const *p) 
{ 
} 
3

您被允許增加訪問限制,您無法減少訪問限制。從普通指針到const指針是好的,從const指針到普通指針不是。

第二個示例不會編譯,因爲您不是將指針轉換爲常量指針,而是將指針轉換爲一種類型(char*)轉換爲另一種類型(const char*)。例如,您可以將char**更改爲char* const*,但不是const char**

0

你的第一個示例,因爲你轉換右值的char*const char*,這是OK(基本上是因爲你不能分配到rvalues)。第二個不是,因爲(非const)指針的目標始終是一個左值。

只要嘗試(也許在編譯器的幫助下),您可以使用char**執行哪些操作,並與const char**一起使用,並考慮是否可以和哪些類型可以互換。

2

檢查這就說明你:

char * a_mutable = /*...*/; 
const char * a_constant = /*...*/; 

char **pointer_to_mutable = &a_mutable; /* ok */ 

const char **pointer_to_constant = &a_constant; /* ok */ 

pointer_to_constant = pointer_to_mutable; /* oops, are you sure? */ 

*pointer_to_constant = a_mutable; /* valid, but will screw things around */ 

的最後一行是有效的,因爲pointer_to_constant是一個可變指向一個可變指向一個恆定的字符,但它會破壞東西,因爲你正在a_constant點到a_mutable。這就是爲什麼你不能讓pointer_to_constant收到pointer_to_mutable的內容。

相關問題