2017-01-23 121 views
6

是否有一個原因的strcpy的簽名是這樣的:爲什麼strcpy不使用dest指針的const指針?

char *strcpy(char *dest, const char *src); 

,而不是這個?

char *strcpy(char *const dest, const char *src); 

據我所知,函數永遠不會改變指針。

我誤解了什麼const指針應該用於?在我看來,當我寫一個函數接受一個不會被改變的指針(通過realloc等),然後我把它標記爲一個const指針,這樣調用者可以確定它們的指針不會被移動。 (如果他們有其他結構/等參考指針位置將變得過時)

這是一種好的做法,或者它會產生意想不到的後果嗎?

+0

左側的const我覺得一個常數,只能被初始化/ assighned /定義一次控制或在聲明時定義。 –

+0

不僅_函數不會改變pointer._,但是即使沒有const,strcpy也無法改變dest。 –

回答

11

strcpy的源代碼是非常粗略的:

char *strcpy(char *dest, const char *src) 
{ 
    while (*dest++ = *src++); 
} 

在這裏,我們其實並修改dest但是這對調用者沒有影響,因爲strcpy函數內部,dest是一個局部變量。

但是,下面的代碼將無法編譯,因爲dest是常量:

char *strcpy(char * const dest, const char *src) 
{ 
    while (*dest++ = *src++); 
} 

我們需要這樣寫:

char *strcpy(char * const dest, const char *src) 
{ 
    char *temp = dest; 
    while (*temp++ = *src++); 
} 

它引入了一個非必要temp變量。

+1

注意:3個例子不會返回值爲'char * strcpy()'函數渲染它們UB - 當然它們是_rough_。看到沒有「非必要的臨時變量」的代碼會很有趣,它會返回C庫中指定的原始「dest」。 – chux

+0

@chux你完全正確,但它僅用於演示目的。 –

3

函數自變量的限定符在聲明(原型)中完全被忽略。這是C語言所要求的,它是有道理的,因爲這樣的限定沒有可能對函數的調用者有意義。

const char *src的情況下,參數src不是合格的;它指向的類型是合格的。在dest的假設聲明中,限定符適用於dest,因此無意義。

-1

據我所知,函數永遠不會改變指針。

是的,但你可以。你可以自由改變指針。無需製作dest指針const

例如:

int main(void) 
{ 
    char *s = "Hello"; 
    char *d = malloc(6); 

    strcpy(d, s); 
    puts(d); 
    strcpy(d, "World"); 
    puts(d); 
} 
1

這是沒有意義的,將其標記爲const你的建議。在C中,函數參數作爲副本傳遞。這意味着strcpy()裏面的變量dest實際上是一個新的變量(壓入堆棧),它保存着相同的內容(這裏是地址)。

看看這個函數原型:

void foo(int const a); 

這有沒有語義價值,因爲我們知道,不能改變原來的變量,我們傳遞給foo(),因爲它是一個副本。只有副本可能會改變。當foo返回時,我們保證原始變量a不變。

在函數參數中,只有當函數實際上可以持久地改變變量的狀態時,纔想使用關鍵字const。例如:

size_t strlen(const char *s); 

這標誌着可變s爲const(即,存儲在該地址s點值)的含量。因此,你保證你的字符串在strlen返回時不會改變。

2

char *foo(char *const dest, const char *src) { ... }表示指針dest在函數體內不會改變。

這並不意味着dest指向的數據將會或不會改變。

const char *src確保調用代碼src指向的數據不會改變。

在調用像strcpy(d,s)foo(d,s)這樣的函數時,調用代碼並不關心函數是否更改指針的副本。所有調用代碼關心的是如果數據指向sd改變,這是由*

char *dest,  // data pointed by `dest` may or may not change. 
const char *src // data pointed by `src` will not change change because of `src`. 
相關問題