2012-05-30 37 views
0

據我所知,標準的strcmp函數看起來是這樣的:STRCMP混亂

int strcmp(const char* string1, const char* string2) 
{ 
    while(*pString1++ == *pString2++) 
    { 
     if(*pString1 == 0) return 0; 
    } 
    return *pString1 - pString2; 
} 

我的問題是,不會這個增量指針傳遞到STRCMP?在下面的例子中,它似乎會垃圾指針並導致無效的事情發生。

const char* string1 = "blah"; 
const char* string2 = "blah"; 
const char* string3 = "blah"; 
if(strcmp(string1, string2) {doSomething();} 
// Won't this make string1 = "" because it incremented the pointer to the end? 
else if (strcmp(string1, string3) {doSomethingElse();} 

對不起,我只是困惑,因爲它看起來像如果我傳遞一個指針到STRCMP,我不應該期望該指針突然持有空字符串。看起來strcmp應該使用const char * const。我完全誤解了什麼嗎?

+2

你懷疑什麼,如果它是'會發生爲const char * string1';即通過參考。 – iammilind

+0

請注意,要測試相等性,您必須檢查!strcmp(...)或strcmp(...)== 0. –

回答

8

你的誤解是這樣的:參數是按值(副本)傳遞的,但你似乎認爲它們是通過引用傳遞的。

你可以通過參數聲明以strcmp作爲參考,這樣讓你的預期行爲:

int strcmp(const char*& string1, const char*& string2) 
+0

啊。那真是愚蠢。 –

+0

爲了澄清它爲什麼很愚蠢,我的調試器改變了char *的地址是我遇到的問題,即使指針在代碼執行過程中並沒有真正改變,我仍然在觀察它。不知道它爲什麼這麼做,但浪費了我很多時間:-p –

4

不,指針string1string2是函數的本地(通過值傳遞)。對它們所做的任何更改對於調用者都是不可見的。

1

指針本身是通過值傳遞的,所以儘管它是一個指向某個東西的指針,但改變它只會改變本地聲明。

爲了能夠從函數的內部範圍修改指針本身,您需要指向指向char的指針。

1

指針按值傳遞,strcmp使用您發送的指針的副本,因此原始指針不會被觸摸。

0

首先,strcmp經典混淆實現甚至 簡單:

int 
strcmp(char const* s1, char const* s2) 
{ 
    while (*s1 ++ == *s2 ++) 
     ; 
    return *s1 - *s2; 
} 

(我希望沒有人會真的在 的練習中寫這樣的代碼。)

至於你的實際問題:C++(和C,因爲這是一個真正的C 問題)通過值傳遞參數,所以strcmp得到的任何指針是 副本;它不可能修改調用的 代碼中的任何指針。所有制作參數char const* const意味着 strcmp無法修改其指針的本地副本。

+0

strcmp的經典的obfsucated實現有一個bug? –

0

C++將參數傳遞給函數「按值」。考慮以下代碼:

void f(int i) { i = 7; } 
... 
    int j = 0; 
    f(j); 
    assert(j == 0); 

變量j是無關的變量i。事實上,i本地的功能f。它的初始化爲j的副本。對i的更改永遠不會傳達給j

現在考慮下面的代碼:

void f(char *i) { i = i + 1; } 
... 
    char *j = "Hello"; 
    f(j); 
    assert(*j == 'H'); 

同樣,i用的j副本初始化。對i的更改永遠不會傳回給j


注:一個可以強制參數,以「按引用」被初始化正是如此:

void f(int& i) { i = 7; } 
... 
    int j = 3; 
    f(j); 
    assert(j==7); 

在這種情況下,而不是與的j副本被初始化,i結合j 。但是這隻適用於在聲明中有&

0

試試這個,你會發現它們是完全不同的指針。 因爲你誤解是什麼使它們指向同一個區域

#include <iostream> 

using namespace std; 

int strcmp2(char const *s1, char const *s2) 
{ 
    cout << "In strcmp" << endl; 
    cout << &s1 << " " << &s2 << endl; 
    cout << endl; 
} 

int main() 
{ 
    char a[100]; 
    char b[100]; 

    cout << "In main function" << endl; 
    cout << &a << " " << &b << endl; 
    cout << endl; 

    strcmp2(a, b); 
}