2015-09-13 35 views
1

考慮這個實施strcpy爲什麼字符串複製函數只是指定指針不工作?

void my_strcpy(char target[], char source[]) 
{ 
    target = source; 
} 

int main(void) 
{ 
    char target[20]; 
    char source[] = "Source String"; 

    my_strcpy(target, source); 
    printf("Target: %s", target); 

    return 0; 
} 

這不工作,它讓我懷疑我的字符串和數組的理解C.

,這裏是我的推理:targetsource是真正公正的指針,以數組的第一個元素,即。 target == &target[0]source == &source[0]。當我設置target = source時,我將指針target指向指針source指向的同一內存地址。

現在當我printftarget,它也應該打印"Source String"。但事實並非如此。

有人可以解釋爲什麼嗎?

+1

您是否期待將'source'複製到'target'或'target'中以指定source的地址?兩者都是錯誤的,順便說一句。 – Downvoter

+0

請注意,C使用[詞法作用域](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope_vs._dynamic_scope)。 'my_strcpy'中的'target'變量與'main'中的'target'變量不同。因此,即使你給了它們相同的名字,它們也不是同一個變量。 – user3386109

回答

8
void my_strcpy(char target[], char source[]) 
{ 
    target = source; 
} 

您在這裏所做的是,如您所寫,將指針傳遞給函數。但指針本身通過值通過,所以函數具有這些指針的本地副本。函數內部的target在函數退出後立即停止。

要實際修改函數中的指針,您必須將指針傳遞給此指針(例如,像這樣:

void my_strcpy(char *target[], char source[]) 
{ 
    *target = source; 
} 

需要注意的是,這仍然不會與你的程序工作,因爲在main()聲明數組。聲明數組的地址不能更改。這是因爲數組是而不是與指針相同(因爲您經常可以在編寫不好的C教程中閱讀),但是當您將它傳遞給函數時,它會隱式轉換爲指向其第一個元素的指針。所以,在你的main()中寫char *target,這個就會工作,調用函數如my_strcpy(&target, source);

另外請注意,這是在沒有辦法副本,所以你的函數的命名是語義錯誤。一個真正的複製功能應該是這樣的:

void my_strcpy(char *target, const char *source) 
{ 
    while (*target++ = *source++); 
} 

複製單個字符,直到擊中\0字符(則表達式將評估爲0和while循環將停止)。這個超級簡單的實現給負載提供了足夠的存儲空間,並且確保source實際上是0-terminated給調用者,但它確實或多或少是標準C庫的strcpy()所做的。

編輯:我剛剛改變了你的功能簽名 - 第一個改變是一個品味問題,用*identifier代替identifier[]。我喜歡這樣做,因爲這是內部反正發生的事情,所以它更清楚地說明了函數實際需要的東西。第二個是在適當的地方添加一個const:你的函數不會改變source指向的內容,所以你應該明確這一點 - 這樣編譯器可以爲你捕獲更多的錯誤。

+0

感謝您的詳細解釋,這是有道理的。 – User314159

+0

感謝您的接受,我只是在希望未來的讀者可能會獲利的情況下添加了一些內容! –

5

兩件事情你需要記住:

  • C使用pass-by-value
  • 您不能更改自動數組的地址。

現在,

my_strcpy(target, source); 

相同

my_strcpy(&target[0], &source[0]); 

其中通過這兩個陣列的第一元件和所述地址

void my_strcpy(char target[], char source[]) 

相同

void my_strcpy(char* target, char* source) 

其中target指向的數組target的第一個元素的在mainsource指向的數組sourcemain第一元素的地址的地址。

所以,

target = source; 

只是改變其中target點的位置。現在,targetsource都指向相同的存儲位置,即指向main中的陣列source的地址。 由於C使用按值傳遞,因此這對main中的任一數組都沒有任何影響。函數中的指針與數組的地址都有不同的地址。

+0

感謝您的詳細解釋,這是有道理的。 – User314159

相關問題